超时模式适用于一般类型的问题,它能帮助系统从意料之外的事件中恢复过来
![](https://img2023.cnblogs.com/blog/3076680/202306/3076680-20230625162750165-109306308.png)
1. “模式采用量”绝不是好的质量指标
1.1. 应该形成一种“面向恢复”的思维模式
1.2. 良好的模式能为开发工程师提供架构和设计方面的指导,从而减少、消除或缓解系统中的裂纹产生的影响
1.2.1. 在新发布软件后,它们能让你睡个安稳觉
2. 超时
2.1. 超时是一种简单的机制,只要认为响应不会到来,就可以停止等待
2.2. 代码不能永远等待响应,它迟早需要放弃等待
2.3. 早些年
2.3.1. 网络问题只影响那些从事操作系统、网络协议、远程文件系统等低层级软件开发的程序员
2.4. 今天
2.4.1. 每个系统都是分布式系统
2.4.2. 每个应用程序都必须应对网络的基本特点:网络会出故障
2.4.2.1. 电缆可能会断开
2.4.2.2. 传输线路上的交换机或路由器可能会坏掉
2.4.2.3. 正在寻址的计算机可能会崩溃
2.4.3. 即使已经建立了通信,参与其中的任何部件都可能随时中断
3. 超时机制/模式
3.1. 良好的超时机制可以提供失误隔离功能
3.1.1. 其他服务或设备中出现的问题不一定会成为你的问题
3.2. 在远离复杂硬件层的抽象层,良好的超时设置越来越罕见
3.2.1. 一些高级API只有很少的超时设置,有些几乎没有明确的设置
3.2.2. 许多API只提供了一个带有超时时间的调用和一个更简单、更容易但永久阻塞的调用
3.2.3. 商业软件客户端程序库缺乏超时设置
3.2.3.1. 这些库通常代表系统直接进行套接字调用
3.3. 超时可以用于单个服务
3.3.1. 任何资源池都可能枯竭
3.3.2. 在向资源池检入一个资源之前,调用线程会被阻塞
3.3.3. 无论资源是否可用,所有引起线程阻塞的资源池都必须有一个超时时间,以确保调用线程最终会解除阻塞
3.4. 处理所有潜在的超时会给代码带来不必要的复杂性
3.4.1. 网络连接代码完全充斥着针对各类超时的错误处理逻辑
3.4.2. 有一半的代码是进行错误处理,而不是提供特性
3.5. 以生产环境(而不是QA环境)为目标,其本质就是处理“是生存还是毁灭”这样的终极问题
3.5.1. 用于错误处理的代码会增强系统的韧性
3.5.2. 系统的用户可能不会因此而感激你,系统不发生停机就没人会留意你,但你晚上能睡得更好
3.6. 超时模式和快速失败模式都解决了延迟问题
3.6.1. 快速失败模式适用于传入系统的请求
3.6.2. 超时模式则主要适用于系统发出的出站请求
3.7. 超时模式还可以通过阻止客户端处理整个结果集,缓解“无限长结果集”的问题
3.8. 超时模式适用于一般类型的问题,它能帮助系统从意料之外的事件中恢复过来
4. 方案
4.1. 使用通用网关为连接处理、错误处理、查询执行和结果处理提供模板
4.1.1. 将这种通用的交互模式收集到一个类中,采用断路器模式时就会变得更加容易
4.1.2. 断路器可以记录一段时间内的超时情况,如果超时过于频繁,断路器就会跳闸
4.2. 那些使用回调函数或响应式编程风格的编程语言运行时,也能更轻松地设定超时时间
4.3. 将超时模式应用于集成点、阻塞线程和缓慢响应
4.4. 当操作时间过长,有时无须明确其原因时,只需要放弃操作并继续做其他事
4.5. 超时通常与重试一同出现
4.5.1. 在“尽力而为”的设计理念下,软件会试图重复执行一次超时操作
4.5.2. 在系统失效后立即重试,会产生一系列结果,其中只有一些是有益的
4.5.3. 如果由于重大问题而导致操作失败,那么立即重试的结果可能是再次失败
4.5.4. 在数据中心的内部,系统失效可能是因为连接的另一端出现问题
4.5.4.1. 快速重试很有可能再次失败
4.6. 慢慢地重试排队等待的任务,能使系统更加稳健
4.6.1. 延迟重试
4.6.2. 大多数情况下,应该把操作任务放入队列,稍后再重试
4.7. 务必给客户一个答案
4.7.1. 由于某种超时而无法完成操作,最好返回一个结果
4.7.1.1. 失败了
4.7.1.2. 成功了
4.7.1.3. 其他提示信息