Lagom:响应式微服务框架
Lagom 在瑞典语中意为“恰到好处、刚刚好”。微服务的核心,是创建“大小合适”的服务——既具备恰当的功能边界与隔离级别,又能支撑起可伸缩、有韧性的系统。
Lagom 致力于让应用充分发挥“响应式宣言(Reactive Manifesto)“的潜力,同时提供高生产率的开发体验,以及无缝的生产部署能力。
Lagom 概念概览
Lagom 框架提供了一整套从开发到部署的库与开发环境:
- 开发期:一条命令即可构建项目,并启动所有服务及配套的 Lagom 基础设施;代码改动会触发热重载。短短几分钟,你就能新建一个服务,或加入一个已有的 Lagom 开发团队。
- 语言:可以使用 Java 或 Scala 编写微服务。Lagom 让服务间的通信格外顺滑——服务定位、通信协议等细节都由框架透明处理,把便利性和生产率拉满。
- 持久化:Lagom 支持基于事件溯源(Event Sourcing)与 CQRS(命令查询职责分离)的持久化模式。
- 服务客户端:Lagom 会根据服务描述符(Service Descriptor)自动生成服务客户端,调用和测试端点变得异常简单。
部署:你可以选择任意平台,例如:
- Kubernetes:用于自动化容器化应用部署、扩缩容与管理的开源系统。
- DC/OS:由 Mesosphere 基于 Apache Mesos 分布式系统内核创建和维护的开源分布式操作系统。
- 任意支持主机间私有网络的云环境或本地部署。
设计高可伸缩、并且在意外故障下仍能保持韧性的微服务系统,是一件极其困难的事。没有 Lagom 这样的框架,你就得自己处理高度分布式系统里那些棘手的线程与并发问题。遵循 Lagom 的设计初衷,你可以规避大量此类陷阱,同时提升生产率。而且 Lagom 不要求你推倒重来——它允许你在现有约束内渐进式地采纳响应式架构。例如,你可以用它来:
- 与遗留系统对接,或逐步替换单体应用的功能。
- 用 Cassandra 做持久化,也可以选用你自己的数据库,或对接其他数据存储。(Lagom 的持久化 API 默认支持 Cassandra,因为它天然契合微服务系统所需的分片与读侧支持。)
Lagom 的设计理念
先看看 Jonas Bonér 在《Reactive Microservices Architecture:分布式系统的设计原则》中提出的响应式微服务的几项基本要求:
- “隔离是弹性与韧性的前提,服务边界之间必须采用异步通信……”
- “自治的服务只能通过公开其协议/API 来承诺自身行为。“以及”要让服务做到位置透明,它必须是可寻址的。”
- “每个微服务都必须对自身状态及其持久化负全责。”
以下 Lagom 特性正是为了践行这些最佳实践:
- 默认异步:Lagom 的 API 把服务间通信当作一等公民,通过流式传输实现。所有 Lagom API 都基于 Akka Streams 的异步 IO 能力;Java API 使用 JDK 8 的
CompletionStage表达异步计算,Scala API 使用Future。 - 分布式持久化:相比传统的集中式数据库,Lagom 支持分布式持久化模式。我们鼓励(但不强制)采用基于事件的架构来做数据持久化。实体持久化的默认模式是事件溯源(ES)+ CQRS,详见「管理数据持久化」与「持久化实体」。
- 服务注册与发现:Lagom 提供了用于开发目的的服务注册表与服务网关实现,以及客户端/服务器端服务发现的内部管线,详见「注册和发现服务」。
在多语言系统中使用 Lagom
Lagom 并不要求你系统里的每个服务都是 Lagom 微服务。毕竟,采用微服务的一大优势,正是可以为每个服务务实选择最合适的语言与技术。Lagom 对标准通信协议的“地道”用法,加上它与“设计驱动 API”思路的天然契合,使它能很好地融入这种多语言系统。
- Lagom 服务调用映射到用于同步通信的标准 HTTP,以及用于流式传输与异步消息传递的 WebSocket。任何支持这些协议的语言或框架,都能轻松消费 Lagom 服务;反过来,Lagom 服务也能轻松与任何公开 REST API 的服务对话。
- Lagom 服务的 API 描述该服务如何使用 HTTP:REST 服务调用由 HTTP 方法与 URI 标识,请求头与响应头均可定制。默认情况下,Lagom 消息通过地道的映射库序列化为普通 JSON,让 JSON 在网络上的呈现方式对开发者透明。
开发环境概览
借助「Lagom 入门」中介绍的 sbt 模板或 Maven 原型(archetype),几分钟即可搭好 Lagom 开发环境。这些模板无需任何编码、脚本或配置,就能建立以下内容:
- 一个包含两示例服务的分层构建结构,你可以照着它的模式在同一项目里创建自己的服务。
- 本地运行与测试服务所需的基础设施:
- 一个用于处理消息的 Kafka 服务器;
- 一个用于处理持久化的 Cassandra 服务器;
- 一套服务注册表与服务网关,支撑位置透明性;
- 构建并运行服务与基础设施所需的配置。
用模板创建项目后,执行 runAll 命令即可启动所有运行时组件,立刻开始测试。
Lagom 的构建理念
如果做得对,采纳响应式微服务架构能显著提升研发组织的生产率与交付速度。Lagom 提供了一套灵活的构建方法,既支持个人开发,也支持团队协作,并能随业务增长而演进。你可以把所有微服务放在单个 sbt/Maven 构建(项目)中,也可以每个服务独立构建,或者把逻辑相关的服务组放进多个构建。
如何取舍?可参考以下利弊:
- 单一构建承载多个服务:开发新功能往往要同时改动多个服务,把它们放在同一构建里,开发体验无懈可击。但随着参与构建的开发人数增加,彼此干扰会降低速度。
- 多个构建,每个承载一个或一小组服务:每个微服务都能独立变更,隔离状态下推进更快;发布时,相关服务再统一升级、消费更新后的服务。但多构建会增加复杂度——你需要把服务发布出去,供其他服务可用;实现时也要导入所依赖的全部服务。详见「将系统拆分为多个版本」。
起步阶段,把所有服务放在同一构建里通常最合理:小团队用一个构建就够,也避免了拆多构建带来的滞后与依赖问题。随着系统与组织的发展,调整策略才有意义——比如随功能增长,把服务拆到不同的内部版本。团队同理。重要的是,不要害怕重构你的构建以满足组织需求。
组件技术
作为一个完整的微服务平台,Lagom 汇聚了一系列技术,并在其之上增加了价值。Lagom 使用并支持的库、工具与服务器,一部分由 Lightbend 开发,其余来自第三方与开源社区。使用 Lagom 开发时,你还能借助以下技术:
- Play 框架:Lagom 构建于 Lightbend 的 Web 框架 Play 之上,这是一个实现细节,开发简单微服务时你并不直接接触它;但高级用户可以直接调用部分 Play API。如果你已有 Play Framework 应用并想叠加微服务,Lagom 也为此用例提供支持。
- Akka:Lagom 的 Persistence、Publish-Subscribe 与 Cluster 都构建于 Lightbend 的工具包 Akka 之上,用于构建并发、分布式、有韧性的消息驱动应用(同样是实现细节,简单微服务开发时并不直接相关;但你也可直接调用 Akka API)。为跨多服务器扩展微服务,Lagom 通过 Akka Cluster 提供集群能力;如「实现服务」所述,Lagom 服务可以是“简单的”或“流式的”,流式异步服务则建立在 Akka Streams 之上。
- Lightbend Platform 增值组件(订户可用):Akka Split Brain Resolver 处理网络故障与系统崩溃;Lightbend Telemetry 与 Lightbend Console 让你洞察系统的健康、可用与性能。详见 Lightbend Platform。
- Cassandra:默认情况下,需要持久化的 Lagom 微服务使用随开发环境一起运行的 Cassandra 实例;你也可以用已有的 Cassandra 或其他类型数据库。
- Guice:与 Play 一样,Lagom 使用 Guice 做依赖注入。
- SLF4J 与 Logback:Lagom 用 SLF4J 记录日志,默认由 Logback 作为日志引擎支撑。
- Typesafe Config:Lagom 及其众多组件技术都用 Typesafe Config 库配置,配置格式为 HOCON——JSON 的强大且富有表现力的超集。
- 序列化:Lagom 推荐的序列化格式是 JSON。Java 端默认用 Jackson,Scala 端用 Play JSON;也支持其他序列化格式。
API 概览
Lagom 同时提供 Java 与 Scala API。Java API 以 Java 8 为目标,假定你熟悉 lambda、默认方法与 Optional。Lagom 主体用 Scala 实现,但即便你用 Java API 开发,这也是无需关心的实现细节。
Lagom 富有表现力的服务接口声明,让开发者能快速定义接口并立即着手实现。开发时你会用到的重要 API 包括:
- Service API:声明并实现供客户端使用的服务接口。为支持位置透明,客户端通过服务定位器发现服务。除同步的请求-响应调用外,Service API 也支持服务间的异步流。
- Message Broker API:提供分布式发布-订阅模型,服务可借由主题(Topic)共享数据。主题只是允许服务推入/拉出数据的通道。
- 持久化 API(Persistence API):为存储数据的服务提供基于事件溯源的持久化实体,并附带 CQRS 读侧支持。Lagom 管理持久化实体在节点集群中的分布,从而实现分片与水平扩展。开箱即用提供 Cassandra,但也支持其他数据库。