演示使用 Kafka 的异步通信的高度可扩展微服务应用。
本系列使用不同的技术创建相同的可伸缩微服务应用程序:
1.(本文)
2.使用 AWS Lambda Kinesis 的可扩展的无服务器微服务演示
3.使用 Knative 和 Kafka 的可扩展的无服务器微服务演示(计划中)
本文描述了使用 Kubernetes, Istio 和 Kafka 的高度可扩展的微服务演示应用程序。通过同步的 REST API 调用,可以创建用户。在内部,所有通信都是通过 Kafka 异步完成。
Image 1: Architecture overview
Kafka 消费者/生产者 “用户审批服务” 会根据 Kafka 主题中有多少未处理的消息自动缩放(HPA)。还有一个节点/集群缩放器。
我们将扩展到每秒23000个 Kafka 事件,11个 Kubernetes 节点和280个 Pod。
Image 2: Results overview
该应用程序完全使用 Terraform 编写,并且可以使用一条命令来运行。
< https://github.com/wuestkamp/s ... e-dem o>
查看自述文件以获取有关如何运行程序的说明。
Image 3: Architecture
我们有三个微服务:
Kafka 集群由 ConfluentCloud 管理,Mongo 数据库和 K8s 集群由 Azure 管理。
我们不会使用多个服务共享一个大型数据库,每个服务都有自己的数据库(如果是有状态的)。我们仍然只有一台 MongoDB 数据库服务器,但是在一台服务器上可以存在多个数据库。如果微服务使用相同的类型/版本,则它们可以共享相同的数据库服务器。详细内容请阅读 这里 。
这三个微服务彼此异步通信,没有直接的同步连接。异步通信的优点之一是松耦合。如果 用户审批服务 停止服务了一段时间,请求不会失败,只是需要更长的时间,直到用户获得审批完成。因此,在使用异步通信时,无需执行重试或断路器。
Image 4: Message workflow
图四显示了消息是如何生成和消费的。用户服务使用用户创建的消息,创建待审批的用户并存储于MongoDB,然后生成用户审批的消息。
一旦收到来自 用户审批服务 的用户批准响应消息,它将更新用户为“批准”或“未批准”,并生成用户创建响应消息,操作服务将接收该消息,该消息将更新操作状态为“完成”。
当使用一个大型 (MySQL) 关系数据库时,您只需将操作包装在数据库事务中即可。SAGA 模式可用于实现类似于 ACID 的事物,可用来跨多个微服务进行操作。
在图4中,可以将用户服务视为 SAGA 用户创建的协调器。因为它通过生产和消费各种消息来协调用户的创建。在此示例中,仅涉及一项服务(用户审批服务),但是如果有更多服务,可能会变得更加复杂。
可以将 SAGA 与状态机进行比较并实现为状态机。了解更多关于 SAGA 模式以及编排和编排之间的区别,请阅读这里: https://microservices.io/patterns/data/saga.html
Image 5: Sync to Async conversion
(1) 图5显示,首先对操作服务进行同步 REST 调用以创建一个新操作,这种情况为“用户创建”。操作服务发出异步消息,然后立即以挂起状态返回新操作。
(2)返回的操作包含一个 UUID,可以使用该 UUID 定期获取该操作的当前状态。该操作将根据其他服务提出的异步请求进行更新。
Kubernetes 集群扩展在 Azure 上使用 Terraform 配置。在 用户审批服务 的部署上,我们还有一个HPA(水平Pod自动缩放器)。
HPA 会监听一个自定义指标,该指标提供有关用户审批的 Kafka 主题中尚未处理的消息数量。如果有消息排队,我们会增加更多的 Pod。
用户审批服务在处理消息后会休眠200毫秒。这意味着如果它是唯一实例,并且不断收到新消息,它将会落后。
我们使用 Prometheus 和 Grafana 实现可视化。
我们使用 kafka_exporter 从 Kafka 获取指标,它可以为 Prometheus 和 Grafana 提供这些指标。我们在用户审批服务的每个 Pod 中将 kafka_exporter 作为 sidecar,以便可以从每个 Pod 中或者为每个 Pod 使用指标。
为了使这些 Kafka Prometheus 指标可用作 K8s 的自定义指标(HPA 必需),我们使用 k8s-prometheus-adapter 。
```
kubectl api-versions | grep "custom.metrics"
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 | jq
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pod/*/kafka_consumergroup_lag" | jq
```
更多详细信息请访问该项目的 prometheus-adapter.yaml 。现在我们可以将这些 Kafka 指标用于 K8s HPA 。
Kiali 与 Istio 完美结合,并立即为我们提供了概要图:
Image 6: Kiali network
6中,我们看到 REST 请求命中 Istio Gateway,然后是 操作服务。其余的通信都通过 “PassthroughCluster” 进行,这是外部托管的 kafka。我们还可以看到 kafka-exporter 正在与 Kafka 进行通信以收集指标。
到目前为止,Istio 无法更加详细地管理 Kafka 流量,而是将其作为 TCP 进行处理。Envoy 似乎已经能够做到这一点,这意味着 Istio 将效仿。我们可能还会看到 Kiali 的进步,例如在边缘显示每秒的消息数。
在 Joel Takvorian 的 Twitter 线程中了解更多信息,他在其中设法将 Kafka 节点包含在 Kiali 服务图谱中。
See Joel Takvorian's other Tweets
现在,乐趣开始了。
在未启用 HPA 的情况下,我们每秒创建约60个新事件。
Image 7: topic user-approve lag is rising'''
从左到右,我们看到:
用户审批服务在处理消息后会休眠200毫秒。这意味着如果只有单个实例并且新事件不断出现,用户审批服务将落后,如图7所示。
现在启用了 HPA,并且不断增加 REST 请求以创建新用户。
Image 8: no load, but we start with 9 Nodes for faster scaling
Image 9: Requests hitting, we see HPA scaling up the Kafka consumer UserApprovalService
Image 10: 2045 Events per second
Image 11: First node scaling
Image 12: Close to 20000 Events per second
Image 13: 23000 !
该应用程序自动扩展到约280个 用户审批服务 pod,11个 node节点,每秒处理约23000个事件!这是一个不错的开始:)
这仅受 Azure 账户的计算限制,无法再创建更多 node 节点。
原文链接: Scalable Microservice Demo K8s Istio Kafka (翻译:xiebo)