关键要点
- 主动测试、缓解症状和快速响应是微服务架构故障管理的三个核心策略。
- 如果你只有少量微服务或浅层拓扑,请不要急着考虑采用服务网格,可以先看看有没有其他可选的故障管理策略。
- 如果你正在部署服务网格,为了将服务网格集成到软件开发生命周期中,你需要做好付出长期努力的准备。
随着越来越多的公司采用微服务架构, Istio 、 Linkerd 和 Cilium 等服务网格也越来越受关注。服务网格提供了非常有吸引力的特性:全堆栈可观测性、透明的安全性、系统弹性等。但是,服务网格真的是云原生应用程序的正确解决方案吗?本文将讨论服务网格在什么情况下是有意义的,以及什么时候不应该使用服务网格。
微服务,如果做对了,会让你走得更快
在当今世界,上市时间是一项基本的竞争优势。快速响应市场和客户反馈对于建立一个成功的业务来说至关重要。微服务是加速软件敏捷性和速度工作流的一个强大范式。不同的开发团队同时开发应用程序的不同部分,所以决策是分散的。
分散的决策导致了两个重要的后果。首先,软件团队可以在架构、发布、测试等方面做出局部最优决策,而不依赖全局的最优标准。这种决策最常见的例子是版本发布:每个团队都有自己的发布路线,而不是一起发布一个单体应用。其次,可以更快地做出决策,因为软件团队与集中式部门(如运营、架构等)之间的沟通成本降低了。
微服务不是免费的——它们引入了新的故障模式
采用微服务对组织、流程和架构有着深远的影响。在本文中,我们将重点介绍关键的架构变化之——微服务是分布式系统。在基于微服务的应用程序中,业务逻辑分布在通过网络相互通信的多个服务之间。分布式系统有更多的故障模式,正如“分布式计算的谬误”这篇文章里所强调的那样。
鉴于这些故障模式,建立一个防止小问题成为大故障的架构和流程至关重要。在快速发展过程中,故障是不可避免的。例如,在更新服务时会引入 bug,服务在高负载下会崩溃,等等。
随着应用程序复杂性的增长,对故障管理的需求也日益迫切。如果应用程序是由少数微服务组成的,故障往往更容易隔离和排除。随着应用程序增长到数十个或数百个微服务,并且分布在不同的地理位置,那么故障管理系统需要与应用程序一起扩展。
故障管理
故障管理有三种基本策略:主动测试、缓解症状和快速响应。
- 主动测试。实现用于测试应用程序和服务的流程和系统,以便尽早识别出故障。这里也包括传统的“质量保证”(QA),尽管传统的测试团队更专注于预发布测试,但现在他们的工作也包括进行生产环境的测试。
- 缓解症状。实施策略,以减少故障的影响。例如,在多个服务实例之间进行负载均衡,这样可以确保如果单个实例发生故障,整体服务仍然可用。
- 快速反应。实现可以快速识别和解决故障的流程和系统。
服务网格
当服务发生故障时,会对其上游和下游服务产生影响。正确管理服务之间的通信可以大大缓解故障所带来的影响。这个时候,服务网格就可以派上用场。
服务网格负责管理服务级别(即 Layer 7 )的通信。服务网格提供了强大的原语,可以用于实现上述的三种故障管理策略。可以使用服务网格来实现:
- 动态路由,用于不同的发布和测试策略,如金丝雀路由、流量影子或蓝 / 绿部署。
- 弹性,通过断路器和速率限定等策略减轻故障的影响。
- 可观测性,通过收集指标并将上下文(例如跟踪数据)添加到服务间通信中来帮助改进响应时间。
服务网格以一种对应用程序开发人员来说基本透明的方式添加这些特性。但是,我们很快会看到,这种透明度有一些微妙之处。
服务网格会帮助我更快地构建软件吗?
要想知道服务网格对你和你的组织来说是否有意义,首先要问自己两个问题。
- 你的服务拓扑有多复杂?
- 你如何将服务网格集成到软件开发生命周期中?
你的服务拓扑
通常情况下,组织会从单个与现有单体应用程序相连的微服务开始。在这种情况下,服务网格的好处是有限的。如果微服务发生故障,要定位故障很简单。单个微服务的故障影响范围是很限制的。还可以通过现有的基础设施(如 Kubernetes 或 API 网关)来完成增量发布。
但是,随着服务拓扑复杂度的增加,服务网格的好处开始渐显。需要考虑到的关键约束是服务调用链的深度。如果你的拓扑很浅,也就是说单体应用直接调用十几个微服务,那么这个时候服务网格的好处仍然相当有限。随着引入更多的服务间通信,其中服务 A 调用服务 B,服务 B 再调用服务 C,这个时候服务网格变得更加重要。
将服务网格集成到 SDLC 中
服务网格对运行在网格上的服务来说是透明的。可以把服务网格看成是一个特性更丰富的 L7 网络。要让一个服务在服务网格上运行,不需要做出代码变更。
但是,部署服务网格并不会自动改进软件开发速度和敏捷性。你必须将服务网格集成到开发过程中。我们将在下一节更详细地探讨这一点。
将故障管理策略作为 SDLC 的一部分
服务网格为故障管理提供了强大的原语,不过也存在一些服务网格的替代方案。在本节中,我们将介绍各种故障管理策略,并讨论如何将这些策略应用于 SDLC。
主动测试
微服务应用程序的测试策略应尽可能真实。鉴于多服务应用程序的复杂性,现代测试策略更强调在生产环境进行测试(或使用生产数据)。
服务网格通过控制流向服务的L7 流量,可以实现在生产环境中进行测试。例如,服务网格可将1%的流量路由到服务的v1.1,将99%的流量路由到v1.0(金丝雀部署)。这些可以通过声明式路由规则(例如 linkerd dtab 或 Istio 路由规则)进行配置。
服务网格并不是主动测试的唯一方法,还有其他补充策略,包括使用容器调度程序(如 Kubernetes)进行滚动更新、使用可以进行金丝雀部署的API 网关或混沌工程。
有了这些策略,那么应该由谁来管理测试工作流?。在服务网格中,路由规则可以由管理服务网格的团队一并集中式管理。然而,这种方式不可扩展,因为个别服务开发者可能想要控制何时以及如何推出新版本服务。因此,如果由服务开发者来管理路由规则,那么你该如何告诉他们可以做什么以及不可以做什么?如何管理冲突的路由规则?
缓解症状
由于各种原因,服务可能会出现故障:代码错误、资源不足、硬件故障。限制故障服务的影响范围至关重要,至少整体应用程序仍能继续运行,尽管处于降级状态。
服务网格通过弹性模式来减轻故障的影响,例如负载均衡、断路器和服务间通信的速率限定。举个栗子,负载较重的服务可能会受到速率限定,这样可以继续处理一些响应,而不会导致整个服务在负载重压下崩溃。
其他缓解失败的策略包括使用智能RPC 库(例如 Hystrix )或依赖容器调度程序。Kubernetes 之类的容器调度器支持健康检查、自动扩展和动态路由。
这些缓解策略在针对特定服务进行适当配置时最为有效。例如,不同的服务可以处理不同的请求量,因此需要不同的速率限定。如何制定速率限定等策略?Netflix 已经实现了一些自动配置算法来设置这些值。还有就是将这些功能暴露给服务开发者,让他们做出正确的配置。
可观测性
故障是不可避免的。实现可观测性——监控、警报/ 可视化、分布式跟踪和日志——对于最大限度缩短故障响应时间来说至关重要。
服务网格自动收集服务间通信的详细指标,包括吞吐量、延迟和可用性方面的数据。另外,服务网格可以注入必要的头部信息以支持分布式跟踪。请注意,这些头部信息仍然需要由服务本身进行传播。
其他收集指标的方法包括使用监控代理、通过 statsd 收集指标以及通过库(例如 Jaeger 增强库)来实现跟踪。
可观测性的一个重要组成部分是向服务开发者暴露警报和可视化。收集指标只是第一步,让服务开发者创建适合于给定服务的警报和可视化对于可观测性闭环来说非常重要。
一切都是关于工作流!
服务网格的部署机制很简单。但是,正如之前的讨论想要表明的那样,将服务网格应用于工作流会更复杂。成功采用服务网格的关键在于认识到网格会影响你的开发流程,并做好将网格集成到这些流程中的准备。并不存在一种完全正确的方法用于将网格集成到流程中,新的最佳实践仍在不断出现。
关于作者
Richard Li 是几家高科技创业公司的参与者。此前,Richard 是 Duo Security 的产品与战略副总裁。在加入 Duo 之前,Richard 曾担任 Rapid7 战略与企业发展副总裁。他还领导创建了 Rapid7 的产品管理部门。Richard 还在 Red Hat 的销售、市场营销和工程领域担任多个领导职务。
查看英文原文: Service Mesh: Promise or Peril?
评论