内部与外部的通信
如 Lagom 设计理念 所述,服务应当是隔离且自治的。这类服务通过在网络上收发消息来彼此通信(服务间)。为了性能与韧性,同一服务的多个实例通常运行在同一节点上,而这种服务内通信同样走网络。此外,第三方和/或遗留系统也可能消费或供给你的微服务系统的数据。
下面分主题更详细地讨论这些通信路径:
微服务系统内的通信
尽管原则相似,服务间通信与服务内通信的需求却大不相同,Lagom 也提供了多种实现选项。服务间通信必须借助松耦合的协议与消息格式,以维持隔离与自治——跨服务的变更协调既困难又昂贵。你可以利用以下方式实现:
- 服务调用(同步或异步流式):服务通过公开的 API 与标准协议(HTTP、WebSocket)相互通信。
- 向 消息代理(如 Apache Kafka)发布消息,能进一步解耦通信。Lagom 的 Message Broker API 提供“至少一次(at-least-once)“语义:新实例开始发布时,其消息会接续此前发出的事件;新实例订阅主题时,会收到过去、现在与将来的所有事件(只要已订阅)。
单个服务(统称为集群)的节点之间,需要的去耦程度较低:它们共享同一份代码,并由同一个团队或个人作为整体来管理。因此服务内通信可以利用开销更小、性能更高的机制,例如:
- 许多 Lagom 组件内部使用 Akka 远程处理,你也可以在自己的服务中直接使用它。
- 分布式发布-订阅 可用于节点间低延迟、“至多一次(at-most-once)“的消息传递,限制包括:
- 网络中断可能导致消息丢失;
- 新实例启动、加入集群并订阅后,不会收到订阅之前已发出的消息。
- 数据库等持久化存储,也可视为服务节点间通信的另一种方式。对使用持久化实体的微服务,Lagom 鼓励 事件流式传输,它同样受益于异步通信,并通过事件日志提供保证。
下图展示了分布在上三台服务器上的 Lagom 系统中,服务间与服务内各类通信。示例中,订单服务发布到一个或多个 Kafka 主题,而用户服务订阅以消费消息;用户服务使用 Akka 远程处理与其他用户服务实例(集群成员)通信;配送服务与用户服务则通过在服务调用中流式传输数据来交换信息。

与微服务系统外部的各方通信
Lagom 提倡异步通信,但不排斥在必要时使用同步(阻塞)通信。第三方可以异步地从 Lagom 服务发布到 Broker API 的数据中获取信息,并享受“至少一次”保证;Lagom 服务也对外暴露 API,供第三方同步交换数据(通常映射到 HTTP)。Lagom 服务 API 还通过 WebSocket 支持向外部客户端流式传输数据,详见 ServiceDescriptors。
与外界的交互,可能意味着通过互联网使用服务的客户端,如浏览器、移动应用或物联网设备。在使用标准 HTTP 或 WebSocket 时,这类客户端通常不直接与单个服务通信。一般来说,网络边界充当外围,而受控的通信点则作为外部世界与内部世界之间的中介。在 Lagom 中,这个通信点就是服务网关(Service Gateway)。
把你的微服务系统想象成一座中世纪城镇:四周环绕城墙,只有一扇门作为进出的唯一通道。城墙内部的通信自由而直接,但与外部世界的通信必须经由服务网关——如下图所示。
