TranslateProject/translated/talk/20180419 5 guiding principles you should know before you design a microservice.md
2019-01-16 10:27:14 +08:00

156 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

设计微服务架构前您应该了解的5项指导原则
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BIZ_OpenInnovation.png?itok=l29msbql)
对于从微服务开始的团队来说最大的挑战之一就是坚持金发姑娘原则The *Goldilocks principle*):不要太大, 不要太小,不能太紧密耦合。之所以是挑战的原因是会对究竟什么是设计良好的微服务感到疑惑。
数十家 CTOs 通过采访分享了他们的经验, 这些对话说明了设计良好的微服务的五个特点。本文将帮助指导团队设计微服务。(有关详细信息, 请查看即将出版的书籍 [Microservices for Startups][1])。本文将简要介绍微服务的边界和主观的 ”规则“,以避免在深入了解五个特征之前就开始指导您的微服务设计。
### 微服务边界
[core benefits of developing new systems with microservices][2] (开发具有微服务的新系统的核心优势)其中之一是该体系结构允许开发人员独立构建和修改单个组件, 但在最大限度地减少每个 API 之间的回调数量方面可能会出现问题。 根据 Chris McFadden 的解决方法,[SparkPost ][3] 的工程副总裁,应用适当的服务边界去解决问题。
关于边界, 与 domain-driven design (DDD)—a framework for microservices (域驱动设计--微服务框架)有时难以理解和抽象的概念形成鲜明对比,本文重点介绍了与我们行业的一些顶级 CTOs 建立明确定义的微服务边界的实用原则。
### 避免主观的 ”规则“
如果您阅读了足够多的关于设计和创建微服务的建议,您一定会遇到下面的一些 ”规则“。 尽管将它们用作创建微服务的指南很有吸引力, 但加入这些主观规则并不是思考确定微服务的边界的原则性方式。
#### ”微服务应该有 X 行代码“
让我们直说:微服务中有多少行代码没有限制。微服务不会因为您写了几行额外的代码而突然变成一个巨无霸。关键是要确保服务中的代码具有很高的内聚性 (稍后将对此进行更多介绍)。
#### “将每个功能转换为微服务”
如果函数基于三个输入值计算某些内容并返回结果,它是否是微服务的理想候选项?它是否应该是单独可部署应用程序?这确实取决于函数是什么以及它是如何服务于整个系统。将每个函数转换为微服务在您的内容中可能根本没有意义。
其他主观规则包括不考虑整个内容的规则, 例如团队的经验、 DevOps Development和Operations的组合词容量、服务正在执行的操作以及数据的可用性需求。
### 精心设计的服务的5个特点
如果您读过关于微服务的文章, 您无疑会遇到关于什么是设计良好的服务的建议。简单地说, 高内聚和低耦合。如果您不熟悉这些概念, 有许多文章需要查看 [many][4] [articles][5] 。虽然他们提供了合理的建议,但这些概念是相当抽象的。下面, 基于与经验丰富的 CTOs 的对话, 在创建设计良好的微服务时需要牢记的关键特征。
#### #1: 不与其他服务共享数据库表
在 SparkPost 的早期, Chris McFadden 和他的团队必须解决一个问题,,每个 SaaS 生意Software-as-a-Service软件即服务都要面对的他们需要提供基本服务如身份验证、帐户管理和计费。
为了解决这个问题,他们创建了两个微服务:用户 API 和帐户 API。用户 API 将处理用户帐户、API 密钥和身份验证,而帐户 API 将处理所有与计费相关的逻辑。一个非常符合逻辑的分离--但没过多久,他们发现了一个问题。
McFadden 解释说,“我们有一个名为 ”用户 API “的服务,还有一个名为”帐户 API “的服务。问题是,他们之间实际上有几个来回的电话。因此, 您会在帐户中执行一些操作,并在用户中具有调用和终结点,反之亦然”
这两个服务的耦合太紧密了。
在设计微服务时, 如果您有多个服务引用同一个表, 则它是一个危险的信号,因为这可能意味着您的数据库是耦合的源头。
这确实是关于服务与数据的关系, 这正是Oleksiy Kovrin[Swiftype SRE Elastic][6] 的领导者, 告诉我。“我们在开发新服务时使用的主要基本原则之一是, 它们不应跨越数据库边界。每个服务都应依赖于自己的一组基础数据存储。这使我们能够集中访问控制、审计日志记录、缓存逻辑等。”
Kovrin 接着解释说,如果数据库表的子集 “与数据集的其余部分没有或很少连接,则这是一个强烈的信号, 表明组件可以被隔离到单独的 API 或单独的服务中”。
Darby Frey [Lead Honestly][7] 的联合创始人,与此的观点相呼应:”每个服务都应该有自己的表 [并且] 永远不应该共享数据库表。“
#### #2: 数据库表数量最小化
微服务的理想尺寸足够小,但不会更小。每个服务的数据库表的数量也是如此。
Steven Czerwinski[Scaylr][8] 的工程主管, 在接受采访时解释说 Scaylr 的最佳选择是 ”一个或两个服务的数据库表“。
SparkPost's Chris McFadden 同意”我们有一个suppression限制微服务它处理 跟踪, 数以百万计和数十亿的条目周围的限制,但它都非常集中只是围绕限制,所以实际上只有一个或两个表。其他服务也是如此,比如 *webhooks*
#### #3: 考虑有状态和无状态
在设计微服务时,您需要问问自己它是否需要访问数据库,或者它是否会是处理 TB 级数据 (如电子邮件或日志) 的无状态服务。
Julien Lemoine [Algolia][9] 的 CTO解释说::“我们通过定义服务的输入和输出来定义服务的边界。有时服务是网络 API ,但它也可能是在数据库中使用文件和生成记录的进程 (这就是我们的日志处理服务)。
事先要清楚状态,这将引导一个更好的服务设计。
#### #4: 考虑数据可用性需求
在设计微服务时,请记住哪些服务将依赖于此新服务, 以及在该数据不可用时的全系统影响。考虑到这一点,您可以正确地设计此服务的数据备份和恢复系统。
Steven Czerwinski 在 Scaylr 提到,由于关键客户行空间映射数据的重要性,它将以不同的方式复制和分离。
他补充说”每个分片信息在自己的小分区里。如果因为这部分客户群体不会有他们的可用日志而下降那很糟糕但它只影响5% 的客户而不是100% 的客户。
#### #5: 真理的唯一来源
设计服务,使其成为系统中某些内容的唯一实际来源
例如,当您从电子商务网站订购内容时, 则会生成订单 ID ,其他服务可以使用此订单 ID 来查询订单服务,以获取有关订单的完整信息。使用 [publish/subscribe pattern][10] ,在服务之间传递的数据应该是订单 ID 而不是订单本身的属性信息。只有订单服务具有完整的信息,并且是给定订单的唯一实际来源。
### 大型团队的注意事项
考虑到上面列出的五个注意事项,较大的团队应了解其组织结构对微服务边界的影响。
对于大型组织,整个团队可以专门拥有服务,在确定服务边界时, 有组织性的考虑因素就会发挥作用。还有两个需要考虑的因素: **独立的发布计划**和**不同的正常运行时间**的重要性。
Khash Sajadi [Cloud66.][11] 的 CEO 说:”我们所看到的微服务最成功的实现要么基于软件设计原则 (例如域驱动设计和面向服务的体系结构) 要么基于反映组织方法的设计原则“
”所以 (对于) 支付团队“ Sajadi 继续说,,”他们有支付服务或信用卡验证服务, 这就是他们向外界提供的服务。所以这不一定是关于软件的。这主要是关于为外界提供更多服务的业务单位 “
### 双披萨原理
Amazon 是一个拥有多个团队的大型组织的完美示例。正如在一篇文章中所提到的, [API Evangelist][12] Jeff Bezos向所有员工发出授权告知他们公司内的每个团队都必须通过 API 进行沟通。任何没有被解雇的人都会被解雇。
这样所有数据和功能都通过接口公开。Bezos 还设法让每个团队分离,定义他们的资源是什么, 并通过 API 使它们可用。亚马逊正在从地面上建立一个系统。这使得公司内的每一支团队都能成为彼此的合作伙伴。
Travis Reeder [Iron.io][13] 的CTO谈论关于 Bezos 的内部提议。
”Jeff Bezos 规定所有团队都必须构建 API 才能与其他团队进行沟通,“ Reeder 说。”他也是提出‘双披萨’规则的人:一支球队不应该比两个比萨饼能养活的大。
“我认为这里也可以适用同样的方法:无论一个小型团队是否能够开发、管理和富有成效。如果它开始变得笨重或开始后退。可能会变得太大” Reeder 告诉我。
### 最后注意事项: 您的服务是否具有正确的大小和正确定义?
在微服务系统的测试和实施阶段,有一些指标需要记住。
#### 指标 #1: 服务之间是否存在过度依赖?
如果两个服务不断地相互回调,那么这就是耦合的强烈信号,也是它们可能更好地合并为一个服务的信号。
回到 Chris McFadden 的例子, 他有两个 API 服务、帐户和用户不断地相互通信, McFadden 提出了一个合并服务的想法, 并决定将其称为 “原告 API”。事实证明 这是一项富有成效的战略。”我们开始做的是消除这些链接 [这是] 内部 API 调用投注他们之间“ McFadden 告诉我。这有助于简化代码。
#### 指标 #2: 设置服务的开销是否超过了服务独立的好处?
Darby Frey 解释说,“每个应用都需要将其日志聚合到某个位置,并需要进行监视。你需要设置它的警报。你需要有标准的作业程序,并在事情发生时运行书籍。您必须管理 SSH 对该事物的访问。为了让一个应用单纯运行, 必须存在一个巨大的基础。
### 主要外包
设计微服务往往会让人感觉更像是一门艺术, 而不是一门科学。对工程师来说, 这可能不是很好。外面有很多一般性的建议, 但有时可能有点太抽象了。让我们回顾一下在设计下一组微服务时要注意的五个具体特征:
1. 不与其他服务共享数据库表
2. 数据库表数量最小化
3. 考虑有状态和无状态
4. 考虑数据可用性需求
5. 真理的唯一来源
下次设计一组微服务并确定服务边界时,回顾这些原则应该会使任务变得更容易。
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/4/guide-design-microservices
作者:[Jake Lumetta][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[lixinyuxx](https://github.com/lixinyuxx)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:https://opensource.com/users/jakelumetta
[1]:https://buttercms.com/books/microservices-for-startups/
[2]:https://buttercms.com/books/microservices-for-startups/should-you-always-start-with-a-monolith
[3]:https://www.sparkpost.com/
[4]:https://thebojan.ninja/2015/04/08/high-cohesion-loose-coupling/
[5]:https://en.wikipedia.org/wiki/Single_responsibility_principle
[6]:https://www.elastic.co/solutions/site-search
[7]:https://leadhonestly.com/
[8]:https://www.scalyr.com/
[9]:https://www.algolia.com/
[10]:https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern
[11]:https://www.cloud66.com/
[12]:https://apievangelist.com/2012/01/12/the-secret-to-amazons-success-internal-apis/
[13]:https://www.iron.io/