面向开发人员的 7 个微服务最佳实践

在本文中,我们将介绍一些微服务最佳实践,并提出一些方法来帮助你设计、编排和保护微服务架构。

你可能听过很多人对微服务赞不绝口。它们敏捷、简单,并且在面向服务的架构时代进行了全面改进。但是,伴随着微服务的所有好处而来的是一系列新的挑战。

在本文中,我将介绍一些微服务最佳实践。此外,我也将提供一些行之有效的方法来帮助你设计、编排和保护你的微服务架构。通过了解这些实践,你将在成功的项目上有一个良好的开端。

微服务的好处和挑战

然而,在我们深入研究微服务最佳实践之前,我们应该首先谈谈微服务的一些好处和挑战,以及为什么首先要使用它们。

简而言之,微服务是一种改进的软件架构,可让你:

  • 更快地部署和扩展。应用程序被拆分为一个个微服务后,可以实现更快的部署和更快的扩展。
  • 减少停机时间。降低一项不可用服务对你的主要业务功能的影响,从而提高你的整体业务正常运行时间。
  • 确保可用性。保持微服务之间的功能离散,限制实例宕机时的影响。

当然,有了这些好处,我们面临着一系列新的挑战,包括服务间通信、安全性和可扩展性。

  • 服务间通信。对于单体应用程序,所有模块都可以轻松地相互通信。当你从单体架构中提取一个功能到微服务应用程序时,曾经的内部函数调用变成了需要对该外部微服务进行身份验证和授权后的外部 API 调用。
  • 安全层。认证和授权,在单体应用中,可以在入口处一次性处理。随着向微服务的过渡,每个微服务都需要执行一些身份验证和授权以强制执行访问控制。要求用户每次使用不同的微服务都要登录是不现实的,因此需要建立一个统一的认证策略。
  • 可扩展性。尽管微服务允许你独立快速扩展,但要有效地做到这一点,需要良好的应用程序管理甚至更好的工具。你的可扩展的有效性取决于你的微服务编排平台,我们将在下面详细地讨论。

微服务最佳实践

通过对微服务的好处和挑战的概述,现在让我们深入研究一些最佳实践。这些最佳实践将帮助你创建一个强大、易于管理、可扩展且安全的微服务系统。

1. 单一职责

采用微服务架构需要遵循单一职责原则。如果单个微服务负责的业务太多,其故障或不可用将会对系统的其余部分产生多米诺骨牌效应。

微服务应该就是:微服务。保持微服务的业务域较小,只专用于一项逻辑功能。如果出现任何问题,这将降低影响。此外,较小的服务更易于维护–更容易更新和更快的开发。

2. 数据存储分离

连接到同一个数据库的多个微服务本质上仍然是一个单体架构。每个微服务都应该尽可能地拥有自己的数据持久层。这不仅确保了与其他微服务的隔离,而且如果特定数据集变得不可用,还可以最大限度地减少故障影响范围。

有时,不同的微服务访问同一数据库中的数据似乎是有意义的。但是,更深入的检查可能会发现一个微服务仅适用于数据库表的子集,而另一个微服务仅适用于完全不同的表子集。如果两个数据子集完全正交,这将是将数据库分离为单独服务的好方法。这样,单个服务依赖于其专用的数据存储,并且该数据存储的故障不会影响除该服务之外的任何服务。

这种数据分离带来了灵活性的增加。例如,假设我们有两个微服务,都共享相同的文件存储服务。一项微服务经常接触大量资产,但文件大小很小。另一个微服务只有几个它会定期访问的文件,但这些文件的大小有数百 GB。

对这两个微服务使用通用文件存储服务会降低优化成本的灵活性,因为你同时拥有大文件和小文件以及定期和不定期访问的混合。如果每个微服务都有自己的数据持久层,那么你就可以更灵活地找到最适合该单个微服务需求的提供者或服务。

成本优化、选项的灵活性以及对单一解决方案的更少依赖——这些都是分离不同微服务数据的原因。

3. 服务间通信方式

微服务如何相互通信,需要深思熟虑。否则,单个不可用的服务可能会导致整个应用程序崩溃。

想象一个在线商店的微服务系统。一个微服务接受网站下的订单。另一个微服务向客户发送一条文本通知,告知其收到了他们的订单。另一个微服务通知仓库发出产品。最后,另一个微服务更新库存计数。

微服务之间有两种通信方式:同步和异步。如果我们使用同步通信来处理上述示例,Web 服务器可能会通过首先向客户通知服务发送请求来处理新订单。客户通知服务响应后,Web 服务器向仓库通知服务发送请求,然后再次等待响应。最后,Web 服务器向库存更新程序发送请求。我们的同步方法如下所示:

微服务之间的同步通信

当然,假设客户通知服务发生故障。在这种情况下,通知客户的请求可能会超时或返回错误,或者可能让 Web 服务器无限期地等待响应。仓库通知服务可能永远不会收到发货请求。

在异步通信中,服务发送请求并继续其生命周期而无需等待响应。在异步方法中,Web 服务器发送“通知客户”请求,然后完成其任务。客户通知服务负责通知客户并向仓库通知服务发送异步请求,仓库通知服务负责向库存更新服务发送请求。它可能看起来像这样:

微服务之间的异步通信

当然,在这个模型中,我们看到异步通信仍然会导致链依赖,单个服务的故障仍然会中断应用程序。

异步通信的一种简单但有效的方法是采用发布/订阅模式。当感兴趣的事件发生时,生产者(在本例中为微服务)将该事件的记录发布到消息队列服务。对此类事件感兴趣的任何其他微服务作为该事件的消费者订阅消息队列服务。微服务只与消息队列服务通信,而不是彼此通信。

对于我们的示例,它可能如下所示:

消息队列服务促进异步通信

消息队列是一个独立的服务,与所有微服务分离。它负责接收已发布的事件并将这些事件通知订阅者。

有很多工具可以完成这种异步通信(例如,Kafka 或 RabbitMQ)。

有些情况下,微服务之间需要同步通信。大多数请求-响应交互出于必要是同步的。例如,查询数据库的 API 服务器必须等待查询响应;获取缓存数据的 Web 服务器必须等待键值存储响应。

当需要同步通信时,你可以选择使用开源Kong Gateway来确保你的通信快速可靠地路由到正确的微服务。

4. 兼容性

尽可能保持向后兼容性,这样你的使用者就不会遇到坏的 API。

然而,尽管我们作为软件工程师尽了最大的努力,但有时我们还是需要弃用过时的 API,因为我们不会一直运行它们。这时,可以使用API 网关请求转换插件,你的微服务可以通过在原始 API 响应旁边轻松注入弃用通知或附加类似于Kubernetes的“弃用标头”来提醒你的 API 使用者。

5. 微服务编排

微服务的编排是成功的关键因素。从技术上讲,你可以使用 systemd 和 Docker 或 podman 之类的东西在虚拟机上运行容器,但这不能提供与容器编排平台相同级别的弹性。这会对采用微服务架构带来的正常运行时间和可用性优势产生负面影响。对于有效的微服务编排,你需要依赖经过实战考验的容器编排平台,该领域的领导者是Kubernetes

Kubernetes 管理所有容器的构建和部署,同时处理负载均衡、缩放、高可用性副本集和网络通信问题。

你可以在本地独立部署 Kubernetes,也可以使用 Azure Kubernetes Service、Red Hat OpenShift 或 Amazon Elastic Kubernetes Service 等。Kubernetes 内置的调度、弹性甚多和网络功能使微服务编排比在传统操作系统上容易得多。

将 Kubernetes 与Kuma服务网格和Kong Ingress Controller 结合使用,你就拥有了可发现、受监控和弹性的微服务——就像魔法一样。

6. 微服务安全

随着你的应用程序包含越来越多的微服务,确保适当的安全性可能会变得复杂。执行安全策略对于保护你的整个应用程序免受恶意用户、入侵机器人和错误代码的侵害至关重要。无论你是在 VM 上还是在 Kubernetes 中运行,都需要注重身份验证、授权、流量控制和速率限制等。

7. 指标和监控

基于微服务的架构,可能会产生成百上千个小型模块化服务。虽然这在提高速度、可用性和覆盖范围方面产生了巨大的潜力,但庞大的微服务系统需要一种全面性和系统性的监控方法。通过密切关注你的所有微服务,你将确保它们按应有的方式运行,可供你的用户使用,并正确使用资源。当这些期望中的任何一个未得到满足时,你可以通过采取适当的行动来做出调整。

幸运的是,在监控方面你不需要重新发明轮子。有多种广泛采用的监控解决方案可以无缝集成到你的基础架构中。一些解决方案使用指标导出器 SDK,可以通过在微服务中添加一两行代码来集成。其他的可以作为插件与你的 API 网关或服务网格集成,用于监控网络问题和资源使用情况。

当你的监控工具收集指标时,这些指标可以被可视化工具使用——漂亮的仪表板可以帮助你查看微服务背后的数字。上周四晚上 8:00 有多少用户在线?自我们发布新功能以来,CPU 负载增加了多少?API 的延迟是多少?

通过监控你的微服务,你可以对微服务的健康和可用性做出明智的决定。当你这样做时,你会让你的用户满意。

总结

微服务是一个激动人心的旅程!除了可以获得更快的部署和可扩展性、减少停机时间以及全面提高业务可用性等好处外,当你在安全、兼容性、指标和监控和编排平台等投入最佳实践后, 会收获更多客户的满意度。

K8S中文社区微信公众号

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址