部署运维与容错韧性

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 构建配置:

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 与按需自动扩缩容机制。