附录A 网络弹性模式
在云环境中运行时,应用程序需要具有弹性。特别容易出现故障的一个重要领域是网络通信。添加网络弹性的一种常见模式是创建一个导入到应用程序中的库,该库提供本附录中描述的网络弹性模式。但是,导入的库很难维护以多种语言编写的服务,并且当新版本的网络库发布时,会给应用程序增加测试和重新部署的负担。
代替使应用程序处理网络弹性逻辑,可以将代理置于适当的位置,作为应用程序的保护和增强层。代理的优势在于避免应用程序需要额外的复杂代码,并尽量减少开发人员的工作量最初和持续的发展。
可以在连接层(物理或SDN),应用程序或透明代理中处理网络弹性逻辑。虽然代理不是传统网络堆栈的一部分,但它们可用于透明地管理应用程序的网络弹性。
透明代理可以在基础架构中的任何位置运行,但与应用程序的距离越近越有利。他们还需要在协议中尽可能全面,以及他们可以代理的开放系统互连模型(OSI模型)层。
通过实施以下模式,代理在基础架构的弹性中扮演着积极的角色:
- 负载均衡
- 卸载
- 服务发现
- 重试和截止日期
- 断路
代理也可以用来为应用程序添加功能。一些功能包括:
- 安全和认证
- 路由(入口和出口)
- 洞察力和监测
负载均衡
负载平衡应用程序的方法有很多种,以及为什么您应始终将负载平衡器放在云原生应用程序之前的诸多原因:
DigitalOcean在“5个DigitalOcean负载平衡器使用案例”中解释了一些很好的理由:
- 水平缩放
- 高可用性
- 应用程序部署
- 动态流量路由
协调透明代理(例如envoy和linkerd)是负载平衡应用程序的一种方式。具有透明代理句柄负载平衡的一些好处是:
- 对所有端点的请求视图允许更好的负载平衡决策。
- 基于软件的负载平衡器可灵活选择正确的方式来平衡负载。
透明代理不必盲目地将流量传递给下一个路由器。正如Bunyan在其博客文章“超越循环:负载均衡延迟”中指出的,他们可以集中协调以对基础设施有更广泛的了解。这使得负载均衡能够全局优化流量路由,而不是仅为本地优化快速分组切换。
随着对端点的更多了解以及哪些服务正在发送和接收请求,代理可以更合理地向哪里发送流量。
加载脱落
“站点可靠性工程”手册解释了卸载与负载平衡不同。尽管负载平衡试图找到正确的后端来发送流量,但是如果应用程序无法接受请求,负载剔除会有意地丢弃流量。
通过删除负载来保护应用程序实例,可以确保应用程序不会重新启动或被迫进入不利条件。删除请求比等待超时并要求重新启动应用程序要快得多。
当某些事情中断或流量过多时,减载可以帮助保护应用程序实例。当事情正常运行时,应用程序应该通过服务发现发现其他相关服务。
服务发现
服务发现通常由运行服务的编排系统处理。透明代理可以绑定到相同的数据并提供附加功能。
代理可以通过将多个源绑定在一起(例如,DNS和键值数据库)并将它们呈现在统一接口中来增强标准服务发现。这允许实现者在不重写所有应用程序代码的情况下改变其后端。如果在应用程序之外处理服务发现,则可以更改服务发现工具而不必重写任何应用程序代码。
由于代理可以对基础架构中的请求提供更全面的视图,因此可以决定端点何时健康与否。这与其他功能配合使用,例如负载均衡和重试,以将流量路由到最佳端点。
当允许服务彼此发现时,代理服务器还可以考虑额外的元数据。他们可以实现逻辑,如节点延迟或“距离”,以确保为请求发现正确的服务。
重试和截止日期
通常,应用程序会使用内置逻辑来知道如何处理对外部服务失败的请求。这也可以由代理无需额外的应用程序代码来处理。
代理拦截应用程序的所有入口和出口流量并路由请求。如果传出请求失败,代理可以自动重试,而无需涉及应用程序。如果请求因任何其他原因返回,则代理可以根据其配置中的规则进行适当处理。
这很好,只要应用程序对延迟有弹性。否则,代理应根据申请截止日期返回失败通知。
截止日期允许应用程序指定允许请求的时间长度。由于代理可以“追踪”到目的地和返回的请求,因此它可以在使用代理的所有应用程序中强制执行最终期限策略。
当超过最后期限时,失败将返回给应用程序,并且可以决定适当的操作。选项可能会降级服务,但应用程序也可能选择将错误发回给用户。
断路
该模式以相同的断路器室内布线命名。当一切正常工作时,电路默认为“关闭”状态,并允许流量流过断路器。当检测到故障时,电路“打开”并打破流量。
重试模式使应用程序能够重试操作,以期它会成功。断路器模式阻止应用程序执行可能失败的操作。
——Alex Homer,云设计模式:云应用程序指令性架构指南
断开的电路可以是单个端点或整个服务。打开后,不会发送任何流量,并且所有发送流量的尝试都将立即返回失败。
与家庭电路不同,即使处于开放状态,代理也会测试失败的端点。当检测到故障后再次可用时,可将损坏的端点置于“半开”状态。此状态将发送少量流量,直到端点被标记为失败或健康。
这种模式可以使得应用程序快速失败,并且只能发送到健康端点,从而使应用程序更快。通过不断检查端点,网络可以自行修复并智能地路由流量。
除了这些弹性功能外,代理还可以通过以下方式增强应用程序。
TLS和身份验证
代理可以终止传输层安全性(TLS)或代理支持的任何其他安全性。这使得安全逻辑能够集中管理,而不是在每个应用程序中重新实现。然后可以在整个基础架构中更新新的安全协议或证书,而无需重新部署应用程序。
身份验证也是如此。但是,授权仍应由应用程序管理,因为它通常是更细粒度的应用程序特定功能。在应用程序监督它们之前,用户会话cookie可以由代理验证。这意味着只有通过认证的流量才会被应用程序看到。
这不仅可以节省应用程序的时间,还可以防止某些类型的滥用的停机时间。
路由(入口和出口)
当代理在所有应用程序之前运行时,它们控制流入和流出应用程序的流量。他们还可以管理流入和流出集群的流量。
正如反向代理可以用于在N层体系结构中路由到后端一样,服务代理也可能暴露于集群外部的流量,并用于路由到达的请求。这是代理可以用来知道流量位置的另一个数据点来自何处以及它正在发送的位置。
通过对所有服务到服务通信的深入了解,反向代理意味着可以比传统的反向代理更好地了解路由选择。
Insight和监控
利用所有关于基础设施内流量流的知识,代理系统可以公开关于单个端点和整个集群范围内的流量视图的指标。这些数据点传统上已经在专有网络系统或难以自动化的协议中暴露出来(例如, SNMP)。
由于代理立即知道端点无法访问的时间,所以他们首先知道端点何时不健康。编排系统还可以检查应用程序运行状况,但应用程序可能不知道向编排工具报告正确的状态是不健康的。有了服务于同一服务的所有终端的知识,代理也可以成为监控服务运行状况的最佳位置。