import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.jetbrains.kotlin.jvm").version("2.0.21")
id("com.google.cloud.tools.jib") version "3.4.4"
application
}
repositories {
jcenter()
}
dependencies { (1)
implementation("org.jetbrains.kotlin:kotlin-stdlib")
implementation("io.vertx:vertx-web:5.0.0.CR2")
implementation("org.asciidoctor:asciidoctorj:2.5.13")
}
application { (2)
mainClass = "io.vertx.howtos.knative.serving.AppKt"
}
tasks.withType<KotlinCompile> {
kotlinOptions.jvmTarget = "11"
}
jib { (3)
to {
image = "dev.local/jponge/knative-vertx-asciidoctor"
tags = setOf("v1")
}
container {
mainClass = "io.vertx.howtos.knative.serving.AppKt"
ports = listOf("8080")
}
}
部署由 Vert.x 提供支持的 Knative 服务
本操作指南将向您展示如何部署基于 Vert.x 的 Knative 服务。
您将构建什么
-
您将编写一个服务,该服务接受 Asciidoc 文本,并使用 Asciidoctor 生成 HTML 渲染。
-
该服务将使用 Kotlin 编写。
-
将使用 Jib 创建包含该功能的容器镜像。
-
该服务将使用 Knative/serving 进行部署。
您需要什么
-
文本编辑器或 IDE
-
Java 11 或更高版本
-
Maven 或 Gradle
-
Docker
-
一个运行中的 Kubernetes 集群,并安装了 Knative/serving。
什么是 Knative 服务,以及 Vert.x 为何是理想之选?
Knative 启动容器镜像(默认为 3 个)来响应请求,并在没有流量的一段时间延迟后缩容到 0。Knative/serving 提供的“函数”只是一个用任何语言编写并打包为容器镜像的 HTTP 服务。
Vert.x 是在 JVM 上编写 Knative 服务的理想选择,因为
-
Vert.x 应用程序启动速度非常快,因为运行时没有“魔法”发生,
-
可以使用 GraalVM 编译进一步减少启动时间和内存占用(超出本操作指南的范围),
-
Vert.x 应用程序资源效率高,即使在高负载下也能保持响应,
-
Vert.x 提供了庞大的响应式客户端生态系统,可连接其他中间件(数据库、消息传递等),
-
一个 main 方法/函数就足以启动 Vert.x 应用程序!
创建项目
此项目的代码包含功能等效的 Maven 和 Gradle 构建文件。
使用 Gradle
以下是您应该使用的 build.gradle.kts
文件的内容
1 | 我们需要 Kotlin、vertx-web 和 asciidoctorj 。 |
2 | Gradle 应用程序插件允许我们使用 run 命令在本地运行应用程序。 |
3 | 用于生成镜像的 Jib 配置。 |
使用 Maven
以下是您应该使用的 pom.xml
文件的内容
<?xml version="1.0" encoding="UTF-8"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>io.vertx.howtos</groupId>
<artifactId>knative-serving-howto</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<kotlin.version>2.0.21</kotlin.version>
<kotlin.compiler.jvmTarget>11</kotlin.compiler.jvmTarget>
<main.class>io.vertx.howtos.knative.serving.AppKt</main.class>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies> (1)
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>5.0.0.CR2</version>
</dependency>
<dependency>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctorj</artifactId>
<version>2.5.13</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<plugins>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId> (2)
<artifactId>exec-maven-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${main.class}</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>com.google.cloud.tools</groupId> (3)
<artifactId>jib-maven-plugin</artifactId>
<version>3.4.4</version>
<configuration>
<to>
<image>dev.local/jponge/knative-vertx-asciidoctor</image>
<tags>
<tag>v1</tag>
</tags>
</to>
<container>
<mainClass>${main.class}</mainClass>
<ports>
<port>8080</port>
</ports>
</container>
</configuration>
</plugin>
</plugins>
</build>
</project>
1 | 我们需要 Kotlin、vertx-web 和 asciidoctorj 。 |
2 | 允许使用 mvn exec:java 运行。 |
3 | 用于生成镜像的 Jib 配置。 |
编写服务
该服务暴露一个 HTTP 服务器。Asciidoc 通过 HTTP POST 请求传递给函数。对于每个请求,Asciidoctor 用于执行到 HTML 的转换。
package io.vertx.howtos.knative.serving
import io.vertx.core.Vertx
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.BodyHandler
import org.asciidoctor.Asciidoctor
import org.asciidoctor.Options
import org.asciidoctor.SafeMode
fun main() {
val vertx = Vertx.vertx() (1)
val asciidoctor = Asciidoctor.Factory.create() (2)
val options = Options.builder()
.safe(SafeMode.SAFE)
.backend("html5")
.standalone(true)
.build()
val router = Router.router(vertx)
router.route().handler(BodyHandler.create()) (3)
router.post().handler { ctx -> (4)
ctx.response()
.putHeader("Content-Type", "text/html")
.end(asciidoctor.convert(ctx.body().asString(), options))
}
vertx.createHttpServer()
.requestHandler(router)
.listen(8080)
.await()
}
1 | 我们创建一个 Vert.x 上下文。 |
2 | 我们配置一个 Asciidoctor 渲染器。 |
3 | 我们安装一个 HTTP 请求体处理器,这样我们就可以直接处理整个请求体,而不是手动组装缓冲区。 |
4 | 对于每个请求,我们从 Asciidoc 渲染 HTML。 |
我们可以将 Vert.x 代码编写为一个 verticle,但在 main
函数中这样做可以减少样板代码,因为我们无论如何在这里只部署一个 verticle。
在本地运行函数
我们可以轻松测试服务是否正常工作
-
从您的 IDE 运行
main
函数,或 -
使用 Gradle:
./gradlew run
(Linux, macOS) 或gradle run
(Windows)。 -
使用 Maven:
mvn compile exec:java
。
然后,您可以上传 Asciidoc 文件的内容,例如此仓库根目录下的 README.adoc
文件。使用 HTTPie,您可以运行类似于以下内容的命令:
http POST :8080/ @README.adoc
准备您的集群
您应该前往 Knative 文档查看安装说明。
本操作指南中的命令假设您已使用 快速入门 和 Minikube 安装了 Knative。
构建您的容器镜像
您 Gradle 或 Maven 构建中的 Jib 插件将自动组装一个容器镜像,其中包含运行应用程序的正确入口点,并暴露端口 8080。然后,该容器镜像必须被推送到您偏好的仓库。
如果您正在使用 Minikube,可以直接构建并标记容器镜像
eval $(minikube docker-env -p knative)
./gradlew jibDockerBuild # or mvn package jib:dockerBuild
Docker 应该会列出该镜像
docker image ls
您应该看到类似如下内容
REPOSITORY TAG IMAGE ID (...) dev.local/jponge/knative-vertx-asciidoctor latest 4ca7aafd590c dev.local/jponge/knative-vertx-asciidoctor v1 4ca7aafd590c (...)
为 Knative 描述服务
以下是文件 service.yaml
中用于通过 Knative/serving 暴露我们服务的描述符
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: knative-vertx-asciidoctor
namespace: default
spec:
template:
spec:
containers:
- image: dev.local/jponge/knative-vertx-asciidoctor:v1
然后我们可以应用配置并检查服务是否可用
kubectl apply -f service.yaml
您应该看到类似如下内容
service.serving.knative.dev/knative-vertx-asciidoctor created
然后
kubectl get ksvc
您应该看到类似如下内容
NAME URL LATESTCREATED LATESTREADY READY REASON knative-vertx-asciidoctor http://knative-vertx-asciidoctor.default.10.101.169.49.sslip.io knative-vertx-asciidoctor-00001 knative-vertx-asciidoctor-00001 True
测试 Knative 暴露的服务
使用 Minikube,向函数发出请求类似于
http POST knative-vertx-asciidoctor.default.10.101.169.49.sslip.io @README.adoc
您应该在响应中看到 HTML。
如果您的系统无法解析 |
您还应该看到您的服务的 pod
kubectl get pods
您应该看到类似如下内容
NAME READY STATUS RESTARTS AGE knative-vertx-asciidoctor-mlhwq-deployment-5cc999bdb7-jx2ff 3/3 Running 0 2m5s
一段时间后,您可以检查 Knative 自动扩缩器是否已移除所有 pod
kubectl get pods
您应该看到类似如下内容
No resources found.
发出一个新请求,然后您会看到新的 pod 已再次创建。
总结
-
我们使用 Vert.x 和 Kotlin 编写了一个 Knative 服务,将 Asciidoc 文本渲染为 HTML。
-
我们构建了一个容器镜像。
-
我们使用 Knative/serving 部署了该服务。