失败的微服务的三个特征
微服务可以带来极致体验。拆分单体应用,实现服务独立扩展、加速变更并提升弹性,可以带来丰厚的回报。精心实施的微服务所带来的敏捷性,正是那些让你回想起“我们之前是如何做到的?”时会思考的事情之一。
微服务也可能很糟糕。如果实施不当,它们可能引发比解决的问题更多的问题,并造成难以控制的混乱。
这两种情况我都见过,但失败的微服务项目比成功的项目多。随着微服务理念的成熟和人们在实施过程中积累的经验越来越多,情况正在好转,但前路依然漫长。
失败是学习的源泉。回顾我所见过的失败的微服务实现(当然,这只是从 SRE/ops 的角度来说的),我发现它们都有一些共同的特征。
1. 他们分手太早
精心设计的微服务需要对要划分的服务边界和上下文有深入的理解。如果您刚刚构建了 MVP,您可能还不具备这方面的理解。如果您正在尝试使用微服务构建应用,那么您肯定也缺乏这方面的理解。
当人们不太了解应用的边界时,他们往往会依赖一个理论:根据数据模型而不是行为来划分应用。如果你将应用拆分成“用户”、“订单”和“商品”之类的类型,最终会得到三个 CRUD 微服务,以及一组处理你创建的前几个服务之间的业务逻辑的微服务(或一个独立的单体应用)。在这种情况下,你基本上只是在抽象数据库。
相反,如果你做了像“auth”、“order”和“stockcheck”这样的事情,其中每个服务都是由其行为而不是数据定义的,你最终会得到更少、更智能的服务、直观的逻辑流,以及如何以及何时扩展每个部分的清晰想法。
尽可能坚持使用单体应用。让应用和你对正在构建的业务流程的理解逐渐成熟。然后,在合适的时机和地点,开始拆分微服务。
2. 它们紧密耦合
一个业务流程可能依赖于多个微服务协同工作,但每个服务都不应依赖其他服务来运行。否则,你就没有微服务了。你得到的是一个分布式单体架构,它兼具了两种情况的最坏之处。
我见过最糟糕的例子是一个应用,它有三个版本的微服务 API。对 API 进行版本控制是合理的,这本身没有错。但这些人的做法是让每个版本都同步依赖于之前的版本。V3 引用了 v2 和 v1,v2 又引用了 v1。
我见过相反的迁移策略,即开发人员实现新版本的 API,保留 v1 版本,并修改 v1 版本的逻辑,将请求转发到 v2 版本。这感觉很合理。反向耦合依赖关系毫无意义。这意味着他们永远无法摆脱旧的 API,故障排除将是一场噩梦。
在同一个技术栈中,几乎所有服务都依赖于消息系统(本例中是 RabbitMQ)内部的复杂逻辑。这导致频繁发生影响所有服务的级联故障。
3. 他们是被精心策划的
微服务(和 SOA)有一个“编排优于流程编制”的概念,这意味着编排的服务可以独立运行,而流程编制的服务则需要一个中央指挥。
我见过一种相当常见的场景:微服务由企业服务总线 (ESB) 实现,然后由 JBoss Fuse 等企业服务总线 (ESB) 驱动。所有请求和核心业务逻辑都必须经过 ESB,这可能是整个应用中最难扩展的组件,通常是由于状态管理方面的许可和技术限制。由于所有这些逻辑都集中在 ESB 中,因此除非 ESB 指示,否则围绕着 ESB 的微服务不知道该做什么。如果你想构建一个弹性系统,这可不是什么好事。
再次强调,这会让你再次陷入分布式单体架构的泥潭。ESB 本身就很复杂,而且通常很脆弱。因此,你的所有服务都会面临一个复杂、脆弱、难以扩展的单点故障瓶颈。这几乎肯定会给你带来麻烦。这并不是说 ESB 没有用武之地,只是它们与微服务架构不太契合。
API 网关似乎正在成为一种新的 ESB 形式,因此要注意类似的问题,并尽可能保持 API 网关的愚蠢(基本上只是使用它们来合并请求或添加身份验证)。
要有耐心和周到
精心架构的微服务需要大量的专注思考和研究。你肯定不想在读完第一篇关于这个主题的博客文章后就贸然涉足这个领域。重新定义服务边界并重新实现服务是我经历过的最痛苦的工程实践之一。我希望能够帮助你摆脱这种痛苦。
幸运的是,有一些很棒的资源可以提供帮助。我推荐以下这些:
不要因为 Netflix、Google 或 Facebook 使用微服务就去追求它们。当它们对你的应用有意义时才使用它们,即使它们对你来说可能完全没有意义,也要接受这一点。
微服务并非比单体架构“更好”。它们只是解决了一系列不同的问题,这些问题主要与规模和特定业务的运营方式有关。成为一名优秀工程师的一部分就是使用正确的工具来解决正确的问题。在开始使用微服务之前,请先停下来,确保这就是你正在做的事情。
文章来源:https://dev.to/liquid_chickens/ Three-qualities-of-failed-microservices-48ap