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")
}
}
Knative 无服务器服务部署
本指南将向你展示如何使用 Vert.x 与 Kotlin 构建由 Knative Serving 驱动的自适应弹性微服务。
你将构建什么
-
编写一个接收 AsciiDoc 文本并使用 Asciidoctor 实时渲染输出 HTML 的 Web 服务;
-
使用 Kotlin 语言进行简洁优雅的实现;
-
使用 Google Jib 无守护进程极速构建 OCI 容器镜像;
-
将服务部署到 Knative Serving 环境中,实现缩容至 0 与突发流量按需秒级拉起。
前置要求
-
文本编辑器或 IDE
-
Java 11 或更高版本
-
Maven 或 Gradle
-
Docker 环境
-
安装了 Knative Serving 的可用 Kubernetes 集群(或 Minikube)
为什么 Vert.x 是 Knative 服务的理想之选?
Knative 会在无请求流量时将 Pod 副本缩容为 0(Scale-to-Zero),并在突发请求到达时瞬时拉起实例。在 JVM 生态中,启动耗时和常驻内存至关重要。
Vert.x 极其轻量且启动极速,无运行时反射侵入,内存占用极低且能够承受极高并发请求,是构建微服务与 Serverless 容器的不二之选。
创建工程项目
本项目同时提供 Gradle 与 Maven 构建配置:
build.gradle.kts| 1 | 引入 Kotlin 标准库、vertx-web 以及 asciidoctorj; |
| 2 | 配置 Application 插件便于本地调试; |
| 3 | 配置 Jib 镜像构建参数。 |
编写服务逻辑
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 | 挂载 BodyHandler 完整接收 HTTP POST 请求正文; |
| 4 | 将 AsciiDoc 文本即时编译转换为 HTML 并写回客户端。 |
本地运行测试
使用 Gradle 本地启动:./gradlew run;或使用 Maven:mvn compile exec:java。
使用 HTTPie 提交测试文档:
http POST :8080/ @README.adoc
控制台将即刻返回格式化渲染的 HTML 网页正文。
使用 Jib 极速打包容器镜像
利用 Jib 无需启动 Docker 守护进程即可构建分层镜像:
eval $(minikube docker-env -p knative)
./gradlew jibDockerBuild
声明 Knative 服务资源
在 service.yaml 中声明 Knative Service 描述符:
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
应用部署到 Kubernetes:
kubectl apply -f service.yaml
查看 Knative 自动生成的访问入口域名:
kubectl get ksvc
向 Knative 服务端点发起真实请求:
http POST <KSVC_URL> @README.adoc
经过一段时间无网络流量后,再次执行 kubectl get pods,你将亲眼目睹所有 Pod 已全部自动缩容至 0,完全释放集群资源!当新的请求再次到达时,Knative 将在瞬间重新拉起服务。
本文总结
-
使用 Vert.x 与 Kotlin 编写了实时 AsciiDoc 转 HTML 的无服务器计算服务;
-
使用 Jib 构建了高效分层容器镜像;
-
在 Knative 环境中验证了全自动缩容至 0 与按需自动扩缩容机制。