Service Mesh 与 Kotlin 微服务:从混乱到有序

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

您的 Kotlin 微服务已经不再仅仅是微服务了吗?

\n\n

如果您曾经在生产环境中运行过一个由十几个 Kotlin 服务组成的系统,您一定知道这个时刻。一开始一切都很美好:ktor 沙沙作响,spring-webflux 飞速运行,数据库响应迅速。但一个月过去了,熟悉的世界崩塌了。流量开始迂回,重试次数激增,超时在不该出现的地方出现,而日志则变成了一百万行的大杂烩。

\n\n

就在这一刻,您开始寻找 service mesh。而这是正确的道路。让我们来弄清楚这项技术如何将混乱转变为有序,以及如何将其正确地引入 Kotlin 世界。

\n\n

什么是 service mesh,为什么 Kotlin 开发者需要它?

\n\n

Service mesh(服务网格)是一个专用的基础设施层,用于管理服务间的通信。它承担了所有“脏活累活”:路由、负载均衡、加密、可观测性和熔断。而且这一切都不需要修改您的 Kotlin 应用程序代码。

\n\n

为什么这对 Kotlin 至关重要?Kotlin 微服务通常使用 Ktor 或 Spring Boot 等框架编写。两者都能很好地处理业务逻辑,但当服务数量超过 20 个时,每个服务都开始背负大量重复代码:指标、追踪、mTLS、重试机制。Service mesh 将这一切提升到了基础设施层面。

\n\n

想象一下:您在 Ktor 上编写一个简单的 REST 端点,而 service mesh 自动为其添加加密、追踪和负载均衡。很美妙,对吧?

\n\n

Service mesh 的主要组件

\n\n

任何服务网格都建立在两个关键组件之上:

\n\n
    \n
  • Control plane(控制平面) — 系统的“大脑”。收集配置,管理路由规则和安全策略。在 Istio 中是 istiod,在 Linkerd 中是 linkerd-controller。
  • \n
  • Data plane(数据平面) — 系统的“肌肉”。一组 sidecar 代理(通常是 Envoy),它们与您的每个 Kotlin 服务一起运行,并拦截所有入站/出站流量。
  • \n
\n\n

当 Kotlin 服务 A 想要调用服务 B 时,其请求首先到达 sidecar 代理。代理检查规则,应用 mTLS,进行负载均衡,添加追踪头——然后才将请求发送出去。您的代码甚至对此毫不知情。

\n\n

实践:为 Kotlin 微服务配置 service mesh

\n\n

让我们编写一个基于 Ktor 的简单 Kotlin 服务,看看 service mesh 如何改变其行为。

\n\n

步骤 1. 编写 Kotlin 应用程序

\n\n
// build.gradle.kts\ndependencies {\n    implementation("io.ktor:ktor-server-netty:2.3.7")\n    implementation("io.ktor:ktor-server-content-negotiation:2.3.7")\n    implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")\n    implementation("ch.qos.logback:logback-classic:1.4.14")\n}\n\n// Application.kt\npackage com.example\n\nimport io.ktor.server.engine.*\nimport io.ktor.server.netty.*\nimport io.ktor.server.routing.*\nimport io.ktor.server.response.*\nimport io.ktor.serialization.kotlinx.json.*\nimport io.ktor.server.plugins.contentnegotiation.*\n\nfun main() {\n    embeddedServer(Netty, port = 8080) {\n        install(ContentNegotiation) {\n            json()\n        }\n        routing {\n            get("/health") {\n                call.respond(mapOf("status" to "UP", "service" to "payment"))\n            }\n            get("/api/payments/{id}") {\n                val id = call.parameters["id"] ?: "unknown"\n                call.respond(mapOf("paymentId" to id, "amount" to 150.00))\n            }\n        }\n    }.start(wait = true)\n}\n
\n\n

这个服务对 service mesh 一无所知。它只是响应请求。但一旦我们将其部署到带有 Istio 的 Kubernetes 集群中,一切都会改变。

\n\n

步骤 2. 部署到

博客

书籍推荐