事件驱动的微服务。实现进化的发展
8月3日 - 6分钟阅读

图片来源:Hugo Hercer
应用程序增长的解决方案
所有的软件都是从一个想法开始的,为了在这个想法的基础上发展,软件需要进行扩展。这篇文章将描述如何使用事件驱动的微服务来最好地发展你的应用程序,并将解释每个决定的优势。
硬件扩展
随着应用程序中软件的增长,它最终会达到服务器所能提供的极限。需要对硬件如何与应用程序一起扩展做出决定。有两种解决方案。
- 垂直扩展--更大的单台服务器,有更多的功率。
- 横向扩展--多个较小的服务器,应用程序分布在它们之间。
横向扩展的优点
- 成本低 - 许多小服务器比一台大服务器便宜。
- 可靠性 - 其他地方的尖峰不会影响本地服务器。
- 无限扩展 - 垂直扩展的上限是你能找到的最大的服务器,而水平扩展可以增加越来越多的服务器。
横向扩展通常是首选方法。
如何拆分应用程序
决定使用多个服务器后,你需要考虑在这些服务器上拆分应用程序。那么,我们该如何做呢?
选项1:迷你服务(Miniservices),又称模块化单片机。
这被定义为一套相互依赖的模块化服务,这意味着这些服务是相互依赖的。如果一个服务出现了问题,那么整个系统就会出现问题。
这种方案的范围是整个企业,因此很难扩展软件,更新会影响到系统的多个部分,而且它使开发人员很难理解和测试。这种方案通常使用同步通信,意味着一个函数在执行之前必须等待第一个函数的完成。然而这种方案也更容易运行,复杂度也更低。这是一种分布式架构。
选项2:微服务。
Martin Fowler将微服务定义为**"可独立部署的服务套件"**。这意味着它也是独立可扩展的,可以节省资金和资源,故障隔离局限于一个服务,并且是技术不可知的,可以防止厂商锁定。
这种方案有一个单一的业务领域的范围,提供松散的耦合,每个服务都有一个坚定的模块边界。由于这些边界,每个服务很容易被一个特定的团队拥有和管理。这种方案通常使用异步通信,意味着功能可以同时执行。这种方案采用了一种进化的设计,使得它很容易增加更多的服务,并允许更大的灵活性。这是一个集成的架构。


图片来源:Gartner
一个微服务应该有多大?
在决定了微服务之后,我们需要考虑其规模,而微服务的规模应该从认知负荷的角度来考虑。
"认知负荷:正在工作记忆中使用的心理努力的总量"。-John Sweller
Daniel Terhorst-North说,微服务的大小应该是 "适合你脑袋里的软件",按照《团队拓扑》的教导,你应该 "将软件服务的大小限制在团队能够处理的认知负荷"。这意味着更少的错误、所有权和更容易理解的代码。
分割什么
我们需要找到产品中的缝隙。从商业角度来看,它们自然会落在哪里?使用领域驱动设计 - 软件代码的结构和语言应该与业务领域相匹配的概念。
对于软件的边界,需要有一个团队优先的方法,一个服务必须由一个团队拥有,并考虑到康威法则。
康威定律:"组织被限制在生产应用设计上,这些设计是其通信结构的副本" - 康威定律
相反,使用 "反康威定律"--发展你的团队和组织结构以促进你所期望的架构。理想情况下,你的技术架构将与你的业务架构显示出同构性。
如何整合服务
现在,我们已经将我们的应用程序分割成了服务,我们需要将这些服务整合在一起,以便它们能够进行通信。有4种常见的方法来整合服务。
- 文件传输--将数据写入文件,然后将其发送给另一个服务来读取。
- 共享数据库 - 一个数据库,所有服务都存储和访问数据。
- 远程程序调用(RMI)/远程程序调用(RPC)--将数据发送到另一个服务上的一个函数,并接收输出。
- 消息传递--向消息总线发送数据,然后由消息总线负责将数据异步转发给其他服务。


图片来源:enterpriseintegrationpatterns.com
使用消息传递的优势
- 异步可靠交付--我们可以相信消息总线发出的消息,并在同一时间发送给不同的服务。
- 发送和遗忘--源服务只负责将消息发送到消息总线上,然后就可以忘记它。
- 通用连接性--消息总线与许多不同的服务有内置的连接性,应该有容易的集成。
- 没有过载 - 接收者控制它消耗请求的速度,所以不会有服务过载的情况。
- 断开操作--不依赖其他东西,客户端仍然可以访问消息总线。
- 允许使用事件源--对应用程序状态的所有变化都以事件序列的形式存储。
集成问题
整合服务有3个主要问题。
- 网络是不可靠的,而且很慢。
- 任何两个应用程序都是不同的。
- 变化是不可避免的 - 应用程序确实随着时间的推移而变化。
我们选择消息传递是因为。
它比文件传输更直接,比共享数据库封装得更好,比远程过程调用更可靠。
什么是事件驱动架构?
AWS将事件驱动架构定义为 "使用事件来触发并在解耦服务之间进行通信"。我们通过我们的微服务创建一个事件,将其发送到我们的消息总线,然后将其发送到其他解耦的微服务上,触发一些行动来实现这一目标。
事件驱动架构与其他架构的明显区别在于,事件是可观察的,而不是定向的。这使我们能够有明确的界限,多个功能可以在不知道其他服务的情况下同时执行。


图片来源:AWS - James Beswick


图片来源:AWS - James Beswick
事件驱动架构有4个组成部分。
- 事件生产者
- 事件总线
- 事件路由器
- 事件消费者
事件生产者创建的事件被发送到事件总线上。然后,事件路由器将事件引导到适当的事件消费者那里。
在AWS中,你可以通过使用Amazons EventBridge服务来重新创建。一个事件生产者被称为事件源,一个事件消费者被称为目标,一个事件路由器被称为规则,你配置一个规则来触发来自事件源的事件模式,然后路由到目标上。
进化的开发
归根结底,我们今天要写的是明天的遗留代码,所以我们要使它进化
上面的步骤为我们实现进化式开发做了准备,通过使用Strangler模式,使用事件路由器将数据发送到一个新的服务和一个旧的服务,我们可以在不威胁遗留问题的情况下进化我们的软件。
Strangler模式是一种通过分阶段用新的应用程序和服务替换现有功能来逐步迁移遗留系统的方法 -N Natesan
我曾经和很多在高压下设计和建造的系统打过交道,虽然它们符合所有的验收标准,但很少考虑接下来会发生什么。人们更习惯于认为一个项目已经完成,一个需求清单已经结束,就好像企业处于一个需要恢复正常的变动状态。为了开发成功的软件,我们需要更加适应标准状态是变化的,总是在不断地转动以实现不断变化的利益。这样就能以更少的努力从技术中获得更多的价值,这就是为什么你需要有一个进化的架构。它使你能够快速、独立地构建想法,而不会对遗留问题造成威胁,这样你就可以把最好的想法展现在客户面前,并更快地开始实现效益。
