前言
分布式应用的挑战之一就是如何管理 远程服务 的 可用性 和它们的 响应。虽然服务可用性和服务响应都涉及到服务的通信,但它们是两个完全不同的东西。服务可用性 是服务消费者 连接服务 并能够 发送请求 的能力,服务响应 则关注服务的 响应时间。这里就涉及微服务中的 超时反模式。
正文
超时反模式
微服务是一种 分布式的架构,它所有的组件(也就是服务)会被部署为单独的应用程序,并通过某种 远程访问协议 进行通讯。分布式应用的挑战之一就是如何管理 远程服务 的 可用性 和它们的 响应。虽然服务可用性和服务响应都涉及到服务的通信,但它们是两个完全不同的东西。服务可用性 是服务消费者 连接服务 并能够 发送请求 的能力,服务响应 则关注服务的 响应时间。
如图 1-1
的所示,如果此时服务消费者 无法连接 到服务提供者的时候,通过会在毫秒级的时间里得到通知和反馈。这时候 服务消费者 可以选择是 直接返回错误信息 还是 进行重试。但是如果服务提供者接收了请求却 不进行响应 该怎么办?在这种情况下服务消费者可以选择 无限期等待 或者 设置超时时间,使用超时时间看起来是个好办法,但是它会导致 超时反模式。
1. 使用超时
你可能感觉非常困惑,难道设置一个超时时间不是一件好事吗?在大部分的情况下超时时间的错误设置都会带来问题。比如当你上网购物的时候,你提交了订单,服务一直在处理没有返回,你在超时的时候再提交订单,显然服务器需要更复杂的逻辑来处理重复提交订单的问题。
那么超时时间设置多少合适呢?
- 第一种是基于 数据库的超时 来计算服务的超时时间。
- 第二种是计算 负载下最长的处理时间,把它乘以
2
作为 超时时间。
在图 2-2
中,通常的情况下 平均响应时间 是 2
秒,在 高并发 的情况下 最长时间 是 5
秒,因为可以使用加倍技术服务的超时时间设置为 10
秒。
图 1-2
的解决方案似乎看起来很完美,它使每一个服务消费者必须等待 10
秒,其实只是为了 判断服务没有响应。在大多数情况下,用户在等待提交按钮或放弃和关闭屏幕之前不会等待超过 2
到 3
秒。那就必须要有更好的办法来解决。
2. 使用断路器模式
与上面 超时 的方法相比,使用 断路器 的方式更为稳妥。这种设计模式就像家里的电器的保险丝一样,当负载过大,或者电路发生故障或异常时,电流会不断升高,为防止升高的电流有可能损坏电路中的某些重要器件或贵重器件,烧毁电路甚至造成火灾。保险丝会在电流异常升高到一定的高度和热度的时候,自身熔断切断电流,从而起到保护电路安全运行的作用。
图 1-3
说明了 断路器模式 是如何工作的。当服务保持响应时,断路器将关闭,允许通过请求。如果远程服务突然变得不能响应,断路器就会打开,从而阻止请求通过,直到服务再次响应。当然这并不像你家中的保险丝,断路器 本身可以 持续监测服务。
断路器模式 相比 设置超时 的优点是,使用者可以 立即 知道服务已变得不响应,而不必等待超时,使用者将在 毫秒内 服务不响应,而不是等待 10
秒获得相同的信息。
另外断路器可以通过几种方式进行 监控。最简单的方法是 对远程服务 进行简单的 心跳检查,这种方式只是告诉断路器服务是活的,但是要想获取服务存活的详细信息,就需要 定期(比如 10
秒)获取一次服务的详细信息。还有一种方式是 实时用户监控,这种方式可以 动态调整,一旦达到 阈值,断路器可以进入 半开放状态,可以设置 一定数量的请求是通过(说 10
个请求中有 8
个通过)。
相关链接
- 微服务的反模式和陷阱(一) - 数据驱动的迁移反模式
- 微服务的反模式和陷阱(二) - 超时反模式
- 微服务的反模式和陷阱(三) - 共享反模式
- 微服务的反模式和陷阱(四) - 到达报告反模式
- 微服务的反模式和陷阱(五) - 沙粒陷阱
- 微服务的反模式和陷阱(六) - 无因的开发者陷阱
- 微服务的反模式和陷阱(七) - 随大流陷阱
- 微服务的反模式和陷阱(八) - 其它架构模式
- 微服务的反模式和陷阱(九) - 静态契约陷阱
- 微服务的反模式和陷阱(十) - 通信协议使用的陷阱
欢迎关注技术公众号: 零壹技术栈
本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。