分布式事务不是微服务

2020-05-02 18:02:34

(给读者的快速说明-这是一篇纯粹基于观点的文章,从我的经验中提炼出来)。

我参与了许多基于体系结构的讨论、审查和实现,并将许多基于微服务的系统交付生产。我非常同意马丁·福勒的“巨石优先”的做法。然而,我看到很多人走的是相反的方向,认为提前优化是合理的,这可能会导致系统不稳定和混乱。

如果您仅仅为了分布式事务的目的而构建微服务,了解这一点非常重要,您将会遇到很大的麻烦。

让我们举个例子,在电子商务应用程序中,这将是单片版本的订单流。

在这个版本中,事务被两个服务分成两个独立的事务,现在原子性需要由API控制器管理。

在构建微服务时需要避免分布式事务。如果您在多个微服务中产生事务,或者调用多个RESTAPI或发布/订阅(这可以通过进程内单个服务和单个数据库轻松完成),那么很可能您的操作方式是错误的。

混乱测试,与正在进行的交易中的测试相比。要稳定以分布式方式编写的特性真的很难,因为您不仅要测试愉快的情况,还要测试RESTAPI的服务中断、超时和错误处理等情况。

排序,实际上,当涉及到事务时,每个人都需要某种排序,但是要稳定一个异步的(如node.js)和分布式的系统并不容易。

性能,这是一个很大的问题,是过早优化的副产品。最初,您的事务可能不处理大型JSON,但可能稍后出现,并且在后续代码和事务可以访问相同内存的进程中,在分发事务的微服务世界中,这可能是痛苦的(现在每个微服务都将多次加载数据、序列化和反序列化或相同的大型DB调用)。

重构,每次您在设计级别上进行更改,都会出现新的问题(1-3个),这会导致工程团队变得“抗拒更改”。

慢功能,微服务背后的整个概念是“独立而快速地构建和部署功能”,但是现在您可能需要构建、测试、稳定和部署大量服务,而这会减慢速度。

如果未优化硬件利用率,则很有可能大多数硬件未得到充分利用,您可能会开始在同一容器或相同虚拟机中运送许多服务,从而导致高I/O。突然,如果系统收到一些大请求,可能会使其过度利用,这将使您将该组件分离出来,如果此类请求不再出现,则会进一步使系统未得到充分利用,现在将有一个团队来处理这种无限.。

不要将微服务视为类似于重构不同目录中的代码的练习。如果一些代码文件在逻辑上看起来是分开的,那么将它们分开放在一个包中总是一个好主意,然而,在这里创建一个微服务只不过是过早的优化。

如果需要调用RESTAPI来完成请求,请三思而后行(我建议完全避免)。基于消息传递的系统也是如此,在创建新的生产者和消费者之前,尽量不要使用它们。

始终关注不同的用户体验和不同的伸缩需求,比如对于电商来说,API是庞大的、事务性的,与消费者API相比,它是识别组件的好方法。

避免集成测试(是的,您刚才没听错)。如果您创建了10个服务并编写了数百个集成测试,那么您正在制造一个混乱的局面。相反,您可以从2-4个服务开始,编写数百个单元测试,然后编写5个集成测试,我相信您稍后不会后悔的。

考虑批处理,因为这种设计将被证明在性能上很好,并且不那么混乱。例如,假设在电子商务中,供应商和消费者数据库中都有产品。在这里,您不需要编写分布式事务来在两个DB中制造新产品,而是可以首先只在供应商DB中写入,然后运行批处理过程来挑选100个新产品并将它们插入到Consumer DB中。

考虑设置审计程序或创建您自己的审计程序,这样您就可以在原子操作失败时轻松地进行调试和修复,而不是查看不同的数据库。如果您希望减少深夜间歇性错误修复,请尽早设置并在所有地方使用。因此,解决方案可能是这样的。

我建议忽略同步。我见过许多人试图用它来稳定生态系统,但它会带来新的问题(比如超时),然后又会修复。最后,服务应该保持可伸缩性。