您的位置:首页 > 其它

azure最佳实践系列1-自我修复的设计

2017-07-28 00:07 302 查看
如何设计你的应用,能够在系统错误时做到自我修复?
在分布式系统中,会经常遇到错误。硬件也会遇到异常情况。网络有时会出现短暂的错误。整个地区出现了服务中断。即便如此,关于这些问题的方案也是要提前规划的。
因此,需要设计一个能够在错误出现时完成自我修复的系统,主要包括以下3个部分:
发现错误。
正确的对待错误。
使用日志并监控错误,提高可操控性。

对故障类型的响应取决于应用的可用性的需求。例如,如果你需要系统是高可用的,你可能会希望在故障发生时,系统自动切换到辅助区域。然而,这种部署比单一区域的价格高的多。

而且,不要只考虑像区域切换这样的大事件,事实上很少见。你需要将重点放在如何处理本地的短期故障,例如网络链接错误或数据库连接错误。

推荐做法
Retry failed operations. Transient failures may occur due to momentary loss of network connectivity, a dropped database connection, or a timeout when a service is busy. Build retry logic into your application to handle transient failures. For many Azure services, the client SDK implements automatic retries. For more information, see Transient fault handling and Retry Pattern.
对失败操作进行重试。网络链接错误,数据库连接错误或服务调用的超时都会造成短暂的系统错误。在很多zure服务中,客户端的SDK都实现了自动重试模式。有关更多信息,可参见Transient fault handling(https://docs.microsoft.com/en-us/azure/architecture/best-practices/transient-faults)和Retry Pattern(https://docs.microsoft.com/en-us/azure/architecture/patterns/retry)

保护远程服务(断路器)。当出错时,进行重试是对的。不过如果错误始终存在,最终就会囤积太多对失败服务的请求。这可能会引起级联错误。在操作被判断可能会失败时,使用断路器模式(https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker)来加速失败(不进行远程调用)。

隔离关键资源(挡板)。在子系统中的错误有时会有级联。当错误引起一些资源,例如线程或socket没有及时释放,会造成资源衰竭。为了避免这种情况,需要把系统隔离到不同的分组中,这样一来,一个分组中内部的错误就不会影响到整个系统。

负载均衡。应用可能会遇到突然的流量高峰,导致后端服务被压垮。为了避免这种情况,可以使用基于队列的负载均衡模式(https://docs.microsoft.com/en-us/azure/architecture/patterns/queue-based-load-leveling),对请求进行排队,依次执行。队列扮演了缓存的角色,平缓了负载高峰。

故障转移。如果一个实例不可达,转移(请求)到另一个实例。对于无状态的对象来说,例如web服务器,可以放多个实例在负载均衡器或traffic manager的背后。对于有状态的对象来说,例如数据库,可以使用副本(同步状态)再故障转义。应用需要根据不同的数据复制方式来处理最终的一致性问题。

补偿失败的事务。一般来说,要避免分布式事务,因为它们需要在服务间和资源进行协调。比较倾向于小的独立事务组成一种操作。如果操作失败,需要使用补偿事务模式(https://docs.microsoft.com/en-us/azure/architecture/patterns/compensating-transaction)来撤销已经完成的步骤。

检查长时间运行的事务。检查点在为长时间运行的事务失败时提供弹性。当操作重启时(例如VM),可以从上一次的检查点的位置继续上次操作。

优先级。有时你可能无法短时间解决一个问题。不过你可以提供核心功能。例如,一个显示书籍目录的应用。如果应用无法获取封面的缩略图,则可能会显示占位符的图像。再如,一个电商网站,显示产品建议没有订单的处理重要。

请求节流。有时一小部分客户端会在系统中产生大量负载,降低了应用程序的整体可用性。在这种情况下,可以对这部分客户端进行节流。参见节流模式(https://docs.microsoft.com/en-us/azure/architecture/patterns/throttling)。

阻止恶意的客户端。对客户端节流不等于这个客户端是恶意的。只是因为这个客户端超出了服务器的流量限制。但是如果一个客户端持续的对系统产生高负载,或者其他对系统不利的行为。你就需要对这个客户端的连接进行阻止。需要定义取消阻止的处理方式,用户可以申请取消阻止。

使用选举领导模式(https://docs.microsoft.com/en-us/azure/architecture/patterns/leader-election)。当进行任务协调时,可使用领导选举模式来选出一个协调器。这样一来,协调器就不是单一的失败节点。当协调器失败时,新节点就被选出了。不需要从头开始写领导者选举算法,可以考虑使用现有的zookeeper(https://en.wikipedia.org/wiki/Apache_ZooKeeper)算法。

对故障进行测试。通常都是成功的做法得到了充分的测试而失败的情况则被忽略了。系统可能在生产环境中运行了很长时间,都不会产生故障。可使用故障注入的方式来手动出发故障并模拟。这样一来,就能够测试系统的弹性。

拥抱混沌工程。混沌工程通过在生产实例中随机注入故障或异常情况来扩展故障注入的概念。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: