本文将介绍在使整体式应用程序演化为微服务架构时要考虑的重要数据库主题。其中将介绍一些可能遇到的挑战,以及可用来解决这些挑战的模式。还将通过一个示例,展示将 Java 应用程序从整体式模式转变为微服务的必要任务。 分布式数据管理常见的整体式应用程序通常会使用一个或两个关系数据库,数据库中包含运行系统所需的所有信息。这个整体式应用程序通常由一个专门的团队管理。该应用程序的架构使添加新功能、扩展和更改应用程序成为一个缓慢且高风险的过程。 在微服务架构中,每个微服务都必须有自己的数据库,这就使得新功能(也即新微服务)的添加可以快速实现,而且对应用程序其他功能产生影响的风险很低。此方法还支持对每种功能采用合适的工具。例如,可以使用Data Cache for Bluemix 服务或 Redis数据库来存储应用程序中常见的数据的键值信息。此数据可能是城市、商店或机场列表。这个合适的工具也可能是一个关系数据库,用于存储必须在与事务流程相关的各个实体中保持一致的商店事务(订单)信息。 这种新方法有一些优点(参阅第 1 部分'微服务'),但从集中化数据管理转变为了分布式数据管理。该方法带来了一些必须考虑的新挑战。 新挑战当从集中化数据管理转变为使用多个工具和数据库时,会出现一些整体式应用程序中不存在的挑战:
数据一致性通 过为整个应用程序提供一个数据库,可以仅在一个事务中获取、修改和创建各种记录,使您始终能安全地拥有相同的信息视图。在整体式应用程序中,当应用程序增 大,而且您需要更快执行查询时,就会出现不一致问题。结果,您需要创建缓存服务或一次性将公共信息发送给客户端设备(例如移动设备、HTML、桌面应用程 序等)。这减少了服务器调用,但带来的问题是,需要确保所有阶段(也即数据库、缓存和客户端)都有相同的信息。 在采用分布式数据管理(多个 数据库)的微服务架构中,从开发开始,就会出现不一致问题。无论应用程序大小,都无法避免此问题。例如,在可使用奖励积分订购机票的奖励系统中,要为某人 创建一个新的机票订单,必须先获得这个人的当前积分总数。还必须获得该机票的积分成本,然后在比较这两个值之后创建订单。 在微服务架构中,这个过程包含以下阶段: 1.从 Catalog 微服务获得积分形式的机票价格。 2.从 Rewards 微服务获得机票订购者的积分总数。 3.在 Orders 微服务的业务逻辑级别上比较积分成本与积分额。 4.利用 Orders 微服务创建机票订单。 5.利用一个外部预定服务预定航班。 6.利用 Reward 微服务更新创建订单的人的积分数。 此过程有 3 个不同的微服务,每个微服务都有不同的数据库。挑战在于在所有微服务之间共享相同的信息。这是为了确保在机票购买过程中没有信息发生更改,同时确保事务结束时在每个微服务中更新完整信息。 一致性问题在分布式系统中很常见。CAP 定理规定,在分布式系统中,一致性、可用性和分区容错性 (CAP) 不能同时发生;仅能同时确保满足其中两个特征。 在当今环境中,可用性是最重要的选择。因此,有两种模式可视为一致性问题的解决方案:
管道流程 此流程可能看起来像一致性问题的简单解决方案,而且它适合需要执行一组步骤来完成某个流程(事务)的场景。 继续以奖励系统为例,通过采用管道模式,对 Orders 微服务的一个请求会在微服务之间启动一个操作流,如图 1 所示。 图 1 管道模式图 1 中所示的管道流程很常见,但这可能不是最佳的解决方案,因为它在服务之间建立了依赖关系。因此,如果更改了 Catalog 或 Reward 微服务,则必须更改 Orders 微服务。 事件驱动架构模式 一致性问题的另一个解决方案是事件驱动架构, 其中的微服务相互通信的方式是,在其数据库中发生某个重要事件时发布一个事件。例如,如果在一个微服务中创建或更新了一条记录,而且其他微服务订阅了这个 事件队列,那么在订阅微服务收到消息时,它们将更新或创建自己的记录。这种记录更新或创建可能导致发布一个新事件。 通过使用事件,可以创建与多个微服务相关的事务。 对于前面的示例,完成事务的必要步骤和事件如下:
图 2 创建 In-process 状态的记录2.Rewards 和 Catalog 微服务收到 order created 事件消息,更新各自的记录,以保留相应积分和机票价格。然后,每个微服务发布一个新事件(参见图 3)。 |
|