随着越来越多企业开始落地微服务架构,Service Mesh和相关的解决方案在社区内的讨论热度开始逐渐上涨。Service Mesh所提倡的“全栈可观察性”、透明安全性、系统弹性等特性令人着迷,但它真的是云原生应用的绝配吗?本文将对Service Mesh何时make sense、何时不那么make sense作出一些思考。
做好微服务架构可以让我们更敏捷
当下来看,产品和服务的“time to market”决定了企业的竞争力,能够对市场和客户需求快速反应的公司想不成功都难。微服务架构为软件敏捷性和整个工作流的“速度”提供了强有力的支持,通过授权不同团队分别处理应用的不同部分,决策是“去中心化”的。
“去中心化”的决策带来了两个关键结果。首先,软件团队可以在架构、发布、测试等方面作出“本地化”的***决策,不需要依赖全局标准。举个例子,每个团队都有自己的发布工具,而不是单一的标准化应用发布。第二,团队可以更快进行决策,传统模式下韵味、架构等等集中功能之上的阻碍减少了。
微服务架构不是“免费”的——带来了新的失败模式
采用微服务对您的组织、流程和体系结构具有深远的影响。微服务架构本身是一个分布式系统,在基于微服务架构的应用中,业务逻辑分布在通过网络相互通信的多个服务之间,而分布式系统有更多的故障模式(failure mode)。
考虑到这些失败模式,有一个体系结构和过程来防止小的失败变成大的失败是非常重要的。当我们很“快”的时候,失败是不可避免的,例如服务更新时引入了错误,服务在负载下崩溃等等。
随着应用变得越来越复杂,对于失败管理的需求也越来越迫切。当应用由少量微服务组城市,故障还比较容易隔离和排除,但想象数十个、上百个微服务,以及分布在各地的团队,我们的失败管理体系需要与应用一起“伸缩”。
管理失败
我们一般会采取三种失败管理策略:主动测试(proactive testing)、缓解(mitigation)、快速想用(rapid response)。
- 主动测试:利用流程和系统来测试应用或服务,以便尽早发现故障。QA通常包含在这一方法中,虽然传统测试团队专注于预发布测试,但现在经常扩展到生产测试。
- 缓解:实施特定策略以便在特定故障发生时减少影响和损失。例如,取保服务多个实例间的负载均衡,当单个实例失败,整个服务仍然可以相应
- 快速反应:通过流程和系统快速识别和处理特定故障
Service mesh
当服务失败时,会对其上游和下游服务产生影响。通过正确管理服务之间的通信,可以极大地减轻失败服务的影响。这就是Service Mesh的用武之地。
Service Mesh管理服务级别(例如7层代理)通信,提供了强大的原语,可用于所有三种失败管理策略:
动态路由,可用于不同的发布和测试策略,如金丝雀路由、流量阴影或蓝绿部署
弹性,通过诸如断路和速率限制等策略来减轻故障的影响
可观察性,通过收集度量标准,为服务间通信添加context(例如跟踪数据)来提高响应时间
Service Mesh以一种对应用开发人员非常透明的方式添加这些特性。
Service Mesh可以帮助我们更快构建应用吗?
决定Service Mesh对于我们的企业是否有益,首先要思考两个关键问题:
- 服务拓扑结构有多复杂?
- 如何将Service Mesh集成到软件开发生命周期中?
服务拓扑
如果只是单个微服务,Service Mesh的好处是有限的。增量版本也可以通过现有的基础设施(如Kubernetes或API网关)来完成。
然而随着服务拓扑结构越来越复杂,Service Mesh将发挥巨大威力。需要考虑的关键约束是服务调用链的深度。如果您有一个浅层的拓扑结构,您的monolith直接调用了十几种微服务,那么Service Mesh的好处仍然是有限的。当您引入更多的服务到服务的通信时,服务A调用服务B调用服务C,Service Mesh就变得十分重要了。
将您的服务网格集成到您的SDLC中
Service Mesh对于服务是同名的,它是一个丰富的7层网络,微服务不需要任何的代码修改。
然而部署Service Mesh并不会自动加速应用的速率和敏捷性。我们需要将Service Mesh集成到开发过程中。
将实现故障管理策略作为SDLC的一部分
Service Mesh为故障管理提供了强大的原语,接下来我们将讨论各个失败管理策略以及如何应用到SDLC中。
主动测试
微服务应用的测试策略应该尽可能贴近真实情况。考虑到多服务应用的复杂性,当前的测试策略强调在生产中进行测试(或使用生产数据)。
Service Mesh通过控制L7传输到服务的流量来在生产环境中进行测试。例如,服务网格可以将1%的流量路由到服务的v1.1版本, 99%的流量路由到v1.0(金丝雀部署)。这些功能通过声明式路由规则(例如linkerd dtab或Istio路由规则)公开。
Service Mesh不是主动测试的唯一方法。其他补充策略包括使用容器调度器(如Kubernetes)进行滚动更新、可以进行金丝雀部署的API网关或chaos engineering。
有了所有这些策略,谁管理测试工作流的问题就变得很明显了。在Service Mesh中,路由规则可以由管理网格的同一团队集中管理。
缓解
由于各种原因,服务可能会失败:代码错误、资源不足、硬件故障。限制失败服务的爆炸半径对于整个应用程序继续运行(尽管处于降级状态)非常重要。
Service Mesh通过负载平衡、断路器和服务到服务通信的速率限制等弹性模式来减轻故障的影响。例如在重载下的服务可以限制速率,以便仍然处理某些响应,而不会导致整个服务在负载下崩溃。
减轻失败的其他策略包括使用智能RPC库(例如Hystrix)或依赖容器调度程序。像Kubernetes这样的容器调度器支持健康检查、自动扩展和对不响应健康检查的服务的动态路由。
当为给定的服务适当地配置这些缓解策略时,它们是最有效的。例如,不同的服务可以处理不同数量的请求,需要不同的速率限制。如何制定利率限制等政策?Netflix已经实现了一些自动配置算法来设置这些值。其他方法是将这些功能公开给服务作者,他们可以正确配置服务。
可观察性
失败是不可避免的。实现可观察性——跨越监控、警报/可视化、分布式跟踪和日志记录——对于将响应时间最小化到给定的故障是非常重要的。
Service Mesh自动收集关于服务到服务通信的详细指标,包括吞吐量、延迟和可用性的数据。此外,服务网格可以注入必要的headers来支持分布式跟踪。注意,这些headers仍然需要由服务本身传播。
收集类似度量的其他方法包括使用监视代理、通过statsd收集度量以及通过库实现跟踪(例如,Jaeger工具库)。
可观察性的一个重要组成部分是向服务作者公开警报和可视化。收集度量只是***步,考虑您的服务作者如何创建适合于给定服务的警报和可视化对于关闭可观察性循环非常重要。