demo 中分别测试了请求调用链 closed 和 open 两种情况:
/* Experiment 1: success path */// servergo run main.go// clientfor i in $(seq 10); do curl -x '' localhost:8080 ;done/* Experiment 2: circuit open */// serverSERVER_ERROR=1 Go run main.go// clientfor i in $(seq 10); do curl -x '' localhost:8080 ;done查看源码
重试问题在上面的熔断器模式中,如果服务 B 缩容,会发生什么?大量已经从 A 发出的请求会返回 5xx error 。可能会触发熔断器切换到 open 的错误报警 。因此我们需要重试以防间歇性的 network hiccup 发生 。
一段简单的重试代码示例:
package mainfunc callWithRetryV1() (err error) { for index := 0; index < 3; index++ { // call producer API err := callChargeProducerAPI() if err != nil { return err } } // adding backoff // adding jitter return nil}查看源码
重试模式为了实现乐观锁,我们可以为不同的服务配置不同的重试次数 。因为立即重试会对下游服务产生爆发性的请求,所以不能用立即重试 。加一个 backoff 时间可以缓解下游服务的压力 。一些其他的模式会用一个随机的 backoff 时间(或在等待时加 jitter) 。
一起来看下列算法:
- Exponential: bash * 2attemp
- Full Jitter: sleep = rand(0, base * 2attempt)
- Equal Jitter: temp = base * 2attemp; sleep = temp/2+rand(0, temp/2)
- De-corredlated Jitter: sleep = rand(base, sleep*3)

文章插图
05
客户端的数量与服务端的总负载和处理完成时间是有关联的 。为了确定什么样的重试模式最适合你的系统,在客户端数量增加时很有必要运行基准测试 。详细的实验过程可以在这篇文章中看到 。我建议的算法是 de-corredlated Jitter 和 full jitter 选择其中一个 。
两者结合

文章插图
Example configuration of both tools
【图解 Go 微服务中的熔断器和重试】熔断器被广泛用在无状态线上事务系统中,尤其是在聚合点上 。重试应该用于调度作业或不被 timeout 约束的 worker 。经过深思熟虑后我们可以同时用熔断器和重试 。在大型系统中,service mesh 是一种能更精确地编排不同配置的理想架构 。
参考文章
- https://github.com/afex/hystrix-go/
- https://github.com/eApache/go-resiliency
- https://github.com/Netflix/Hystrix/wiki
- https://www.awsarchitectureblog.com/2015/03/backoff.html
- https://dzone.com/articles/go-microservices-part-11-hystrix-and-resilience
推荐阅读
- 如何做好门店服务 如何提高客户进店服务
- 使用Transformer构建自己的机器翻译服务
- 不用工具直接从微软官网下载Win10正式版ISO镜像
- 我终于搞懂了微服务,太不容易了...
- 一行代码引来的安全漏洞,就让我们丢失了整个服务器的控制权
- 玩转Win10时间线技巧汇总
- 淘宝客怎么设置佣金比例和服务费 淘宝店铺佣金
- 车辆出现故障,这4项免费救援服务随叫随到,不要傻傻地找4S店了
- 大红袍的口感,有点稍微的扭曲感
- 微商和网店哪个靠谱 开网店好还是做微商好
