Spring Cloud Netflix Zuul 重试会自动跳过经常超时的服务实例的简单说明和分析
在使用E版本的Spring Cloud Netflix Zuul内置的Ribbon重试功能时,发现Ribbon有一个很精妙的特性:
如果某个服务的某个实例经常需要重试,Ribbon则会在自己维护的一个缓存(serverStatsCache)里将其临时标记为不可用(isCircuitBreakerTripped),后续的所有请求都不会到达该服务实例,直到30(maxCircuitTrippedTimeout的默认值)秒之后,才会放一个请求再次去请求该服务实例。
这其实是Ribbon新增的负载均衡策略之一:AvailabilityFilteringRule(可用性过滤)
—————————————————————————————————————————————————————————————————
———————————————分割线—————以下是一些简单的代码跟踪分析—————观看帮助:截图不是很重要,重要的是文字描述————
—————————————————————————————————————————————————————————————————
当使用Spring Cloud F版本的Gateway的重试功能时,发现并没有该策略,愈发对其感兴趣,想知道如何实现的,索性DEBUG跟着断点走了一百下。。。。在Zuul项目中跟代码分析的思路如下:
0、创建一个spring-cloud-starter-netflix-zuul的项目,和eureka、两个服务,其中一个服务处理时间较长,能触发Ribbon的“熔断”。
1、第一个想到的就是通过日志看一看Ribbon在重试失败的时候做了什么,要看日志当然要打开DEBUG日志级别,在application.yml配置文件中添加如下:
logging:
level:
root: debug
2、清理所有不相干的日志,发现发送HTTP请求的时候走的是RetryTemplate的doExeccute方法,反复debug几遍,发现其中的context在执行到以下代码时忽然有了服务实例信息:

这是一个非常关键的线索,于是重新debug一路跟到给context的serviceInstance赋值的地方

继续跟

上图第56行可以看到赋值,第54行才是选择服务实例,继续



接着:

上图是我改后的源码,做了一些实验,发现当某个服务实例总是触发超时重试后,服务列表经过predicate.getEligibleServers(list,key)方法会把该服务实例给过滤掉。继续跟73行代码
中间略去几张截图,直到跟到

其中的apply方法对服务实例列表中的每个实例进行了过滤,继续跟到其实现

重点来了,用来判断服务实例可不可用的有两个Predicate,其中第二个AvailabilityPredicate就是我们的重点,跟到第二个类的apply方法:

发现总是超时的服务实例,其熔断已经打开,而73行的
stats.getSingleServerStat(input.getServer())
则是整个Ribbon熔断的关键,

通过上图的变量名:serverStatsCache我们就能看明白,这个变量里保存着服务实例的状态,

进一步查看ServerStats中的细节,


是否熔断的判断规则是最后一次触发熔断加上30秒(如下图),和当前时间对比

那么上一次熔断的时间是什么时候设置的呢?

在该方法被调用的时候,至于该方法什么时候被调用的:





上边五张图对其调用时机进行了展示,简单来说就是在发生
java.net.SocketTimeoutException: Read timed out
异常的时候。
到此分析完毕。
分析完后百度上搜一下ServerStats类中的关键字,如
niws.loadbalancer.default.circuitTripMaxTimeoutSeconds
可以看到对Ribbon已经有了很多优秀而系统的源码分析,有时间可以读一下进一步提高。
本文旨在帮助大家分析Ribbon重试和自带熔断机制,并提供一种源码分析的思路,希望对同行有所帮助。
(完毕)
Spring Cloud Netflix Zuul 重试会自动跳过经常超时的服务实例的简单说明和分析的更多相关文章
- SpringCloud学习笔记(20)----Spring Cloud Netflix之服务网关Zuul的各种姿势
1. 禁用过滤器 # zuul.<SimpleClassName>.<filterType>.disable=true # 例如禁用 自定义的过滤器 zuul.MyFilter ...
- Spring Cloud (十三) Zuul:静态路由、静态过滤器与动态路由的实现
前言 本文起笔于2018-06-26周二,接了一个这周要完成的开发任务,需要先等其他人的接口,可能更新的会慢一些,还望大家见谅.这篇博客我们主要讲Spring Cloud Zuul.项目地址:我的gi ...
- spring cloud连载第三篇之Spring Cloud Netflix
1. Service Discovery: Eureka Server(服务发现:eureka服务器) 1.1 依赖 <dependency> <groupId>org.spr ...
- 基于Spring Cloud Netflix的TCC柔性事务和EDA事件驱动示例
Solar Spring Cloud为开发者提供了快速构建分布式系统中的一些常见工具,如分布式配置中心,服务发现与注册中心,智能路由,服务熔断及降级,消息总线,分布式追踪的解决方案等. 本次实战以模拟 ...
- Spring Cloud Netflix多语言/非java语言支持之Spring Cloud Sidecar
Spring Cloud Netflix多语言/非java语言支持之Spring Cloud Sidecar 前言 公司有一个调研要做,调研如何将Python语言提供的服务纳入到Spring Clou ...
- spring cloud 配置zuul实用
在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡 ...
- Spring Boot + Spring Cloud 实现权限管理系统 后端篇(二十一):服务网关(Zuul)
在线演示 演示地址:http://139.196.87.48:9002/kitty 用户名:admin 密码:admin 技术背景 前面我们通过Ribbon或Feign实现了微服务之间的调用和负载均衡 ...
- Spring Cloud Netflix项目进入维护模式
任何项目都有其生命周期,Spring Could Netflix也不例外,官宣已进入维护模式,如果在新项目开始考虑技术选型时要考虑到这点风险,并考虑绕道的可能性. 原创: itmuch IT牧场 这 ...
- Spring Cloud Netflix概览和架构设计
Spring Cloud简介 Spring Cloud是基于Spring Boot的一整套实现微服务的框架.他提供了微服务开发所需的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策 ...
随机推荐
- Centos7服务器中通过编译源码安装MySQL
基于在Centos7服务器上使用 yum 安装MySQL5.7到默认路径 在修改文件存储位置的时候,折腾了一番没有将成功将datadir修改为我想要的位置 我决定再尝试一下通过编译源码来自定义安装: ...
- Kafka生产者案例报警告SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
一.SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". 这个报警告的原因简单来说时因为slf4j的版本 ...
- Codefoces Gym 101652 【最大连续和】
<题目链接> 题目大意: 给你一段只由 'B'和'R'组成的字符串,问你在连续的区间内,"B"和"R"的差值最大是多少,输出该区间:如果对于差值相等 ...
- 利用反射编写私有 Private 方法的单元测试
利用反射编写私有 Private 方法的单元测试 最近在添加一个新feature时,鉴于要给自己的代码一是增加代码的强壮性,二是增加代码测试的覆盖率.但是遇到了有些方法是 Private 的,但是在调 ...
- .net(二)
1.维护数据库的完整性.一致性.你喜欢用触发器还是自写业务逻辑?为什么? 答:尽可能用约束(包括CHECK.主键.唯一键.外键.非空字段)实现,这种方式的效率最好:其次用触发器,这种方式可以保证无论何 ...
- scrapy 安装
windows 1.wheelpip install wheel2.lxmlhttp://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml3.PyOpensslhttp ...
- es6那些事儿
一.参考链接 http://www.ecma-international.org/ecma-262/6.0/index.html http://www.ecma-international.org/e ...
- 在Node.js使用Promise的方式操作Mysql
最近在学习Node.js,虽然早就听说了回调地狱结果过了一周就遇到了.所以花时间学习了了一下Promise.虽然还有Async/await.co.生成器等选择,但是因为本人基础较差,以及时间问题所以决 ...
- Java笔记(十二) 文件基础技术
文件基础技术 一.文件概述 一)基本概念 1.文件的分类: 1)文本文件:文件中每个二进制字节都是某个可打印字符的一部分.如.java文件 2)二进制文件:文件中每个二进制字节不一定用来表示字符,也可 ...
- [P3369]普通平衡树(Splay版)
模板,不解释 #include<bits/stdc++.h> using namespace std; const int mxn=1e5+5; int fa[mxn],ch[mxn][2 ...