原文地址:http://wei-meilin.blogspot.com/2019/03/my2cents-eight-things-leads-to.html。
编者按
作者以较为嘲讽的口吻列举了在开发云原生微服务系统时可能出现的8个错误,告诫开发人员要注意避免这些问题。其观点集中在业务划分、解耦合、重复代码和过度的API交互等方面。作者以自嘲的方式把这些想法用"我的两分钱"比喻,译者意译为"随笔"以方便理解。
大部分标注“我的两分钱”的文章只是一些想法。你只需要快速愉快的阅读,不用太深入,但值得做笔记:)
1. 设置错误的领域边界
这是一种工作保障策略,它让参与项目的每个人在开发和测试中无休止地循环,而无法将服务投入生产环境!首先,一切都从简单开始,逐渐发现有越来越多的功能、业务逻辑被添加到微服务中,最后甚至不得不重新命名整个该死的东西。
1
临床症状和副作用
- 不断增长的微服务变得过于臃肿,或者域中的每个微服务都调用你的服务。(有时核心微服务具有相同的行为,但你不应该在单个域中看到如此多的这类服务)。这违反了简单、可维护和敏捷的微服务原则。
- 到处都是重复的微服务/代码。你可以找到一些重复的代码或微服务,它们被复制和部署到其他域中。
2
如果你陷入了无休止的实现和测试地狱,就退一步看看如何分隔域。您是否接受(译注:此处原文有字母丢失)了一个来自其他领域的上下文,或者将不同的概念混合到一个领域中?也许回到设计阶段考虑边界是值得的。为了避免到处重复,请确保有适当的文档,比如在域之间使用OpenAPI标准的文档。
2. 混合微服务的职责
想吃意面的话这是一个不错的选择。在意面上放些肉丸子让它更美味?在服务中混合一些有状态的进程将会给您带来更多!
3
混合
- 组合微服务
- 功能性的核心业务
- 无状态整合
- 有状态的进程
临床症状和副作用
- 客户端调用变得复杂,如果不提供特定服务的组合视图,客户端可能需要组合并在其中处理某种核心业务。
- 服务之间的关系就好像意大利面条之间的关系,很容易无法追踪到数据流和业务逻辑在微服务中的调用关系。
- 太多的耦合,无状态和有状态依赖于存储解决方案,向下扩展也可能有潜在问题。
我写了很多关于这一主题的博客,主要观点都是担心拆分。确保你的云原生微服务是干净、精练和敏捷的,这意味着你需要确保业务组合和实际业务功能需要单独分开到不同的实例并独立部署,以便获得更好的结构化和模块化。为了可伸缩性和灵活性,确保微服务的组合/编排是无状态的。用专门的存储解决方案在其他实例上保留长时间运行的进程来保持状态。
3. 和外界因素/需求太多的耦合
有耐心总是好的,如果你想练习在你平静的时候能更加的耐心,通过与遗留系统的深度耦合将训练你成为耐心大师,并且能够在敏捷和缓慢的遗留更新周期之间找到平衡,并且更擅长代码管理。
临床症状和副作用
- 持续的从核心业务更新到更好控制的外部系统。外部系统决定和做出变更请求,更短的反应时间可能会导致问题。
- 一旦双方建立了契约,就需要特别小心版本的更新。
3
部署周期因系统而异,但是与更敏捷、更动态的云原生应用相比,棕色地带的应用(译注:作者本意应该是比喻新旧代码或功能耦合的有污染的应用)生命周期更长。为了更快,请始终考虑在你的棕色/绿色地带的应用程序之间设置一个屏蔽保护。因此,它适应更少的变化,并帮助绿色领域继续进行敏捷开发。在你的核心域微服务中,请避免添加任何依赖于外部消费者或特定于外部消费者的内容,因为这可能导致过多的自定义,从而破坏了确定的上下文边界。确保你有其他面向模块的公共库或外部系统来进行定制,并对内部业务模型隐藏复杂性。
4. 微服务中重复的业务无关的代码
作为一个开发人员,如果有人依赖你会让你感到被需要的满足感。为什么每天有24小时是有原因的,你得工作20小时,因为你的重要性,系统部署上线的时候你需要在那儿。
临床症状和副作用
4
- 没有集中控制,所有重试、重路由、版本控制和部署策略都存储在每个独立的实例中。
- 开发和开发运维人员之间的职责不明确,同样的,对于能够访问环境运行情况的监控来说,网络策略更好。
设置重试和路由策略可以让应用更加健壮。用更集中化的视图来了解这些策略是如何处理的,而不是将它们分散到各个微服务上。减轻开发人员处理应用程序中所有事情的负担,以及更好的管理和监控。
5. 服务网格化,所有的连接通过API
进行API调用非常简单,服务网格是现在每个人都在做的事情。每种技术都有一个库来处理REST/JSON。让我们用API来连接系统中的所有组件!
临床症状和副作用
- 反应慢,因为请求并响应是大多数人使用它的方式。等待时间可能会越来越长,长进程也会有更多的锁。这将成为性能瓶颈。
- 没有工具化的云基础架构。
当微服务首次出现时,人们希望远离ESB,因此许多人不再使用消息传递代理,并使用API作为服务之间唯一的连接方法,因为OpenAPI标准允许你在可用的内容之间构建一个良好的目录。但是事件驱动是有原因的,为了实现真正的可伸缩性,更好的解耦,你需要停止在调用之间进行粘性依赖。事件驱动允许你只向相关方发送事件,因为它是异步的,所以在等待响应时不会浪费任何资源。
6. 乱序的事件
6
用事件来轰炸系统,把任何事件都通知到每个角落,这会让你的系统超级的反抗!顺便说一下,为什么不把所有的东西都序列化并存储所有的事件呢?为了更好的可追踪性!
临床症状和副作用
- 事件无处不在,你意识到必须监听大量的事件来做出反应。
- 不需要的代码过滤掉事件。
- 混淆状态变化和应该采取的行为。
- 不知道保存或丢失事件消息哪个更好
有各种类型的事件,如果不谨慎的处理事件分发到哪儿以及如何分发,就很可能以不需要的事件结束并消耗不必要的资源。关注一些通用的,比如包含数据、状态和命令的事件。你希望尽量减少数据消息的数量,因为它需要更长的处理时间和更多的存储工作。分拆和过滤数据可能更有效。处理状态事件重试和回滚命令事件也应该是事件策略的一部分。
7. 数据孤岛
一个微服务一个数据源,专家如是说。
临床症状和副作用
- 数据源之间的数据不一致或同步较慢。
- 创建了不需要的微服务只是为了确保数据的一致性。
- 事件到处更新状态。
7
当您拥有独立的数据源时,就有创建数据孤岛的风险,而且由于微服务的分布式特性和更复杂的数据存储场景,管理数据一致性变得更加困难。你可以开始研究如何使用许多现有的解决方案来捕获数据变更,比如在进程中发生的流事件变更,或者从主存储中监听更改。
8. 有限的自动化
手动要灵活得多,以前在服务器上使用JavaEE应用时也是如此。自动化需要太多的时间来安装设置,有时间的时候再处理吗?
临床症状和副作用
- 更新缓慢
- 到生成环境需要漫长而痛苦的步骤
在计划中需要做的第一件事一定是自动化。如何应用自动化的CI/CD流程和部署策略,如何实现云原生微服务系统的敏捷性。我过去做过一些基于Jenkins的CI/CD自动化。See Github Link.
好了,这就是我的两分钱。如果你认为还有其他可能导致糟糕的云原生微服务开发的事情,请和我分享!