当我们讨论微服务时,更多的是学习技术上怎么实现,而当你掌握了微服务技术之后,你会发现微服务的划分也是个难点。在微服务划分时,一般情况下都会考虑按业务功能划分、确保服务和服务之间要解偶等等,而实际在设计微服务系统时这些方法可能依然会存在很多问题。那么到底如何正确的划分微服务,以下文章可以提供很好的参考。
你的微服务是否太小?或者太紧密耦合?本设计指南可以提供帮助。
设计微服务往往更像是一门艺术而不是科学。本文提出五个建议:
- 它不会与其他服务共享数据库表
- 它拥有最少量的数据库表
- 它设计为有状态的或无状态的
- 其数据可用性需求
- 这是真相的唯一来源
避免任意规则
在设计和创建微服务时,不要陷入使用任意规则的陷阱。如果你阅读了足够多的建议,你会遇到下面的一些规则。虽然吸引人,但这些并不都是划分微服务边界的正确方法。如下:
1.“微服务应该有 X 行代码”
让我们弄清楚一件事。对于微服务中有多少行代码没有限制。微服务不会因为你写了几行额外的代码而突然变成单体巨石。关键是确保服务中的代码具有很高的凝聚力(稍后会详细介绍)。
2.“将每个函数变成微服务”
如果一个函数是根据三个输入值计算出某些东西,并返回一个结果,那么这个函数就是一个微服务吗?这个函数是否是一个可单独部署的应用程序吗?其实真的取决于函数是什么以及它如何服务于整个系统。
其他任意规则包括那些不考虑整个上下文的规则,例如团队的经验,DevOps 容量,服务在做什么以及数据的可用性需求等。
精心设计的服务的特点
如果您已阅读过有关微服务的文章,毫无疑问,您会发现有关设计良好的服务的建议。简而言之:高凝聚力和松散耦合。如果你不熟悉这些概念,有很多关于这些概念的文章。虽然合理的建议,但这些概念是相当抽象的。
我已经和数十位 CTO 就这个话题进行了交流,向他们学习他们如何划分微服务界限,下面为你们提供了一些潜在的特性。
特性#1:它不会与其他服务共享数据库表
当设计一个微服务时,如果你有多个引用同一个表的服务,这是一个红色警告,因为它可能意味着你的数据库是耦合的来源。
“每个服务都应该有自己的表 [并且] 不应共享数据库表。”– Darby Frey,Lead Honestly 共同创始人
这实际上是关于服务与数据的关系,这正是 Elastic Swiftype SRE 的负责人 Oleksiy Kovrin 告诉我的:
“我们在开发新服务时使用的主要基本原则之一是它们不应该跨越数据库边界。每项服务都应该依靠自己的一套底层数据存储。这使我们能够集中访问控制,审计日志记录,缓存逻辑等等,“他说。
Kovyrin 继续解释说,如果数据库表的一部分“与数据集的其余部分没有或很少有关系,这是一个强烈的信号,即组件可能可以被隔离到一个单独的 API 或单独的服务中。”
特性#2:它具有最少量的数据库表
正如第 1 章所提到的,微服务的理想尺寸应该足够小,但不能过小一点。每个服务的数据库表的数量也是一样。
Scaylr 工程负责人 Steven Czerwinski 在接受采访时向我解释说,Scaylr 的甜蜜点是“一个服务 + 一个或两个数据库表”。
特点#3:它有设计为有状态或无状态
在设计微服务时,您需要问自己是否需要访问数据库,或者它是否将成为处理 TB 数据(如电子邮件或日志)的无状态服务。
“我们通过定义服务的输入和输出来定义服务的边界。有时服务是网络 API,但它也可能是一个处理输入文件并在数据库中生成记录的过程(这是我们的日志处理服务的情况)“– Julien Lemoine
要清楚这个前沿,它会导致更好的设计服务。
特点#4:它的数据可用性需求被考虑在内
在设计微服务时,您需要记住哪些服务将依赖于这项新服务,以及如果数据不可用,对系统的影响是什么。考虑到这一点,您可以为此服务正确设计数据备份和恢复系统。
当与 Steven Czerwinski 谈话时,他提到他们的关键客户行空间映射数据由于其重要性而以不同方式复制和分离到不同分区。
“而每个分片信息,都是在自己的小分区中。如果所在分区宕机,那么就没有备份可用,但它只影响 5%的客户,而不是 100%的客户,“Czerwinski 解释说。
特点#5:这是一个真理的单一来源
要牢记的最后一个特点是设计一个服务,使其成为系统中某件事情的唯一真理来源。
举例来说,当您从电子商务网站订购某物品时,会生成订单 ID。此订单 ID 可供其他服务用于查询订单服务以获取有关订单的完整信息。使用 pub / sub 概念,在服务之间传递的数据应该是订单 ID,而不是订单本身的属性 / 信息。只有订单服务具有完整的信息,并且是给定订单的唯一真实来源。
考虑更大的团队
对于大型系统而言,在确定服务边界时,组织架构考虑将发挥作用。有两点需要注意:独立发布时间表和不同的上线时间的重要性。
Cloud66 首席执行官 Khash Sajadi 表示:“我们所见过的最成功的微服务实施要么基于软件设计原则,例如基于领域驱动设计、面向服务架构 SOA 或反映组织方式的架构。
“所以对于支付团队来说,”Sajadi 继续说道,“他们有支付服务或信用卡验证服务,这是他们向外界提供的服务。这主要是关于向外界提供更多服务的业务部门。“
“[亚马逊 CEO: 杰夫贝佐斯]提出了 ’ 两个比萨饼 ’ 的规则 – 一个团队不能多到两个披萨饼还不够他们吃的地步。”– Iron.io 首席技术官 Travis Reeder
亚马逊是拥有多个团队的大型组织的完美典范。正如在 API 推荐人发表的一篇文章中提到的,杰夫贝佐斯向所有员工发布了一份授权通知他们,公司内的每个团队都必须通过 API 进行沟通。任何不会的人将被解雇。
这样,所有的数据和功能都通过接口暴露出来。贝佐斯还设法让每个团队解耦,定义他们的资源,并通过 API 使其可用。亚马逊总是自底而上从头开始建立一个系统。这可以让公司内的每个团队成为彼此的合作伙伴。
我与 Iron.io 的首席技术官 Travis Reeder 谈到了贝佐斯的内部计划。
“杰夫贝佐斯强制所有 team 都必须建立 API 来与其他 team 进行沟通,他也提出了 ’ 两个披萨 ’ 规则,一个团队不能多到两个披萨饼还不够他们吃的地步。”他说。
“我认为这同样适用于这样情况:当一个小团队在开发、管理和生产方面开始变得笨拙或开始变慢,这说明这个团队可能已经太大了,“Reeder 告诉我。
如何判断服务是否太小,或许没有正确定义
在微服务系统的测试和实施阶段,需要牢记下面两条出现现象。
要注意的第一个现象是服务之间的任何过度依赖。 如果两个服务不断地互相调用,那么这已经是一个强烈的耦合信号,他们如果并成一个服务可能更好。
第二个现象:建立服务的开销超过了让其独立的好处。 在这种情况下不如合并成一个服务。
Darby Frey 解释说:“每个应用程序需要将其日志汇总到某处并需要进行监控。您需要设置报警。然后需要有标准的响应操作程序,并在事情中断时运行。你必须管理 SSH 的访问权限。为了让应用程序正常运行,必须准备大量基础设施支持。“
参考
原文
译文