Merge pull request #12022 from lixinyuxx/master

20180419
This commit is contained in:
runningwater 2019-01-16 13:50:46 +08:00 committed by GitHub
commit 7b27ca5892
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 155 additions and 158 deletions

View File

@ -1,158 +0,0 @@
translated by lixinyuxx
5 guiding principles you should know before you design a microservice
======
![](https://opensource.com/sites/default/files/styles/image-full-size/public/lead-images/BIZ_OpenInnovation.png?itok=l29msbql)
One of the biggest challenges for teams starting off with microservices is adhering to the Goldilocks Principle: Not too big, not too small, and not too tightly coupled. Part of this challenge arises from confusion about what, exactly, constitutes a well-designed microservice.
Dozens of CTOs shared their experiences through interviews, and those conversations illuminated five characteristics of well-designed microservices. This article will help guide teams as they design microservices. (For more information, check out the upcoming book [Microservices for Startups][1]). This article will briefly touch on microservice boundaries and arbitrary "rules" to avoid before diving into the five characteristics to guide your design of microservices.
### Microservice boundaries
One of the [core benefits of developing new systems with microservices][2] is that the architecture allows developers to build and modify individual components independently—but problems can arise when it comes to minimizing the number of callbacks between each API. The solution, according to Chris McFadden, VP of engineering at [SparkPost][3] , is to apply the appropriate service boundaries.
With respect to boundaries, in contrast to the sometimes difficult-to-grasp and abstract concept of domain-driven design (DDD)—a framework for microservices—this article focuses on practical principles for creating well-defined microservice boundaries with some of our industry's top CTOs.
### Avoid arbitrary "rules"
If you read enough advice about designing and creating a microservice, you're bound to come across some of the "rules" below. Although it's tempting to use them as guideposts for creating microservices, adhesion to these arbitrary rules is not a principled way to determine thoughtful boundaries for microservices.
#### "A microservice should have X lines of code"
Let's get one thing straight: There are no limitations on how many lines of code there are in a microservice. A microservice doesn't suddenly become a monolith just because you write a few lines of extra code. The key is ensuring there is high cohesion for the code within a service (more on this later).
#### "Turn each function into a microservice"
If a function computes something based on three input values and returns a result, is it a good candidate for a microservice? Should it be a separately deployable application of its own? This really depends on what the function is and how it serves to the entire system. Turning each function into a microservice simply might not make sense in your context.
Other arbitrary rules include those that don't take into account your entire context, such as the team's experience, DevOps capacity, what the service is doing, and availability needs of the data.
### 5 characteristics of a well-designed service
If you've read about microservices, you've no doubt come across advice on what makes a well-designed service. Simply put, high cohesion and loose coupling. There are [many][4] [articles][5] on these concepts to review if you're not familiar with them. And while they offer sound advice, these concepts are quite abstract. Below, based on conversations with experienced CTOs, are key characteristics to keep in mind when creating well-designed microservices.
#### #1: It doesn't share database tables with another service
In the early days of SparkPost, Chris McFadden and his team had to solve a problem that every SaaS business faces: They needed to provide basic services like authentication, account management, and billing.
To tackle this, they created two microservices: a Users API and an Accounts API. The Users API would handle user accounts, API keys, and authentication, while the Accounts API would handle all of the billing-related logic. A very logical separation—but before long, they spotted a problem.
"We had one service that was called the User API, and we had another one called the Account API. The problem was that they were actually having several calls back and forth between them. So you would do something in accounts and have a call and endpoint in users or vice versa," McFadden explained.
The two services were too tightly coupled.
When it comes to designing a microservice, it's a red flag if you have multiple services referencing the same table, as it likely means your DB is a source of coupling.
It is really about how the service relates to the data, which is exactly what Oleksiy Kovrin, head of [Swiftype SRE, Elastic][6], told me. "One of the main foundational principles we use when developing new services is that they should not cross database boundaries. Each service should rely on its own set of underlying data stores. This allows us to centralize access controls, audit logging, caching logic, etc.," he said.
Kovyrin went on to explain that if a subset of your database tables "have no or very little connections to the rest of the dataset, it is a strong signal that component could be isolated into a separate API or a separate service."
Darby Frey, co-founder of [Lead Honestly][7], echoed this sentiment: "Each service should have its own tables [and] should never share database tables."
#### #2: It has a minimal amount of database tables
The ideal size of a microservice is small enough, but no smaller. And the same goes for the number of database tables per service.
Steven Czerwinski, head of engineering, [Scaylr][8], explained during an interview that the sweet spot for Scaylr is "one or two database tables for a service."
SparkPost's Chris McFadden agreed: "We have a suppression microservices, and it handles, keeps track of, millions and billions of entries around suppressions, but it's all very focused just around suppression, so there's really only one or two tables there. The same goes for other services like webhooks."
#### #3: It's thoughtfully stateful or stateless
When designing your microservice, you need to ask yourself whether it requires access to a database or whether it's going to be a stateless service processing terabytes of data like emails or logs.
Julien Lemoine, CTO of [Algolia][9], explained, "We define the boundaries of a service by defining its input and output. Sometimes a service is a network API, but it can also be a process consuming files and producing records in a database (this is the case of our log-processing service)."
Be clear about statefulness up front and it will lead to a better-designed service.
#### #4: Its data availability needs are accounted for
When designing a microservice, keep in mind what services will rely on this new service and the system-wide impact if that data becomes unavailable. Taking that into account allows you to properly design data backup and recovery systems for this service
Steven Czerwinski mentioned that at Scaylr, critical customer row space mapping data is replicated and separated in different ways due to its importance.
In contrast, he added, "The per shard information, that's in its own little partition. It sucks if it goes down because that portion of the customer population is not going to have their logs available, but it's only impacting 5 percent of the customers rather than 100 percent of the customers."
#### #5: It's a single source of truth
Design a service to be the single source of truth for something in your system
For example, when you order something from an e-commerce site, an order ID is generated. This order ID can be used by other services to query an order service for complete information about the order. Using the [publish/subscribe pattern][10], the data that is passed around between services should be the order ID, not the attributes/information of the order itself. Only the order service has complete information and is the single source of truth for a given order.
### Considerations for larger teams
Keeping in mind the five considerations listed above, larger teams should be aware of the impacts of their organizational structure on microservice boundaries.
For larger organizations, where entire teams can be dedicated to owning a service, organizational consideration comes into play when determining service boundaries. And there are two considerations to consider: **independent release schedule** and **different uptime importance**.
"The most successful implementation of microservices we've seen is either based on a software design principle like domain-driven design, for example, and service-oriented architecture, or the ones that reflect an organizational approach," said Khash Sajadi, CEO of [Cloud66.][11]
"So [for the] payments team," Sajadi continued, "they have the payment service or credit card validation service, and that's the service they provide to the outside world. So it's not necessarily anything about software. It's mostly about the business unit [that] provides one more service to the outside world."
### The two-pizza principle
Amazon is a perfect example of a large organization with multiple teams. As mentioned in an article published in [API Evangelist][12], Jeff Bezos issued a mandate to all employees informing them that every team within the company had to communicate via API. Anyone who didn't would be fired.
This way, all the data and functionality was exposed through the interface. Bezos also managed to get every team to decouple, define what their resources are, and make them available through the API. Amazon was building a system from the ground up. This allows every team within the company to become a partner of one another.
I spoke to Travis Reeder, CTO of [Iron.io][13], about Bezos' internal initiative.
"Jeff Bezos mandated that all teams had to build API's to communicate with other teams," Reeder said. "He's also the guy who came up with the 'two-pizza' rule: A team shouldn't be larger than what two pizzas can feed.
"I think the same could apply here: Whatever a small team can develop, manage, and be productive with. If it starts to get unwieldy or starts to slow down, it's probably getting too big," Reeder told me.
### Final considerations: Is your service the right size and properly defined?
During the testing and implementation phase of your microservice system, there are indicators to keep in mind.
#### Indicator #1: Is there over-reliance between services?
If two services are constantly calling back to one another, then that's a strong indication of coupling and a signal that they might be better off combined into one service.
Going back to Chris McFadden's example where he had two API services, accounts, and users that were constantly communicating with one another, McFadden came up an idea to merge the services and decided to call it the Accuser's API. This turned out to be a fruitful strategy.
"What we started doing was eliminating these links [which were the] internal API calls between them," McFadden told me. "It's helped simplify the code."
#### Indicator #2: Does the overhead of setting up the service outweigh the benefit of having the service be independent?
Darby Frey explained, "Every app needs to have its logs aggregated somewhere and needs to be monitored. You need to set up alerting for it. You need to have standard operating procedures and run books for when things break. You have to manage SSH access to that thing. There's a huge foundation of things that have to exist in order for an app to just run."
### Key takeaways
Designing microservices can often feel more like an art than a science. For engineers, that may not sit well. There's lots of general advice out there, but at times it can be a bit too abstract. Let's recap the five specific characteristics to look for when designing your next set of microservices:
1. It doesn't share database tables with another service
2. It has a minimal amount of database tables
3. It's thoughtfully stateful or stateless
4. Its data availability needs are accounted for
5. It's a single source of truth
Next time you're designing a set of microservices and determining service boundaries, referring back to these principles should make the task easier.
--------------------------------------------------------------------------------
via: https://opensource.com/article/18/4/guide-design-microservices
作者:[Jake Lumetta][a]
选题:[lujun9972](https://github.com/lujun9972)
译者:[译者ID](https://github.com/译者ID)
校对:[校对者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/

View File

@ -0,0 +1,155 @@
设计微服务架构前您应该了解的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/