1.基于源码优化注册中心服务注册、服务发现、服务正常(异常)下线的时效性、可用性

1.1源码中实际参数情况与配置文件配置参数对比

1.1.1 eureka-client

(1)服务注册
优化前:原生eureka:注册的服务到注册中心的时效性为40s;
优化后:集成到spring boot后,spring cloud体系重写注册逻辑,优化为毫秒级
(2)续约(服务心跳线程)
优化前:心跳线程(heartbeatThread)时间周期,默认参数30s;
优化后:修改yml文件eureka.instance.lease-renewal-interval-in-seconds=5,设置为5s执行一次,设置后,心跳线程每5s执行一次续约发送心跳的逻辑;
(3)服务发现
优化前:服务发现后台线程refreshThread 时间周期,默认参数为30s;
优化后:修改yml文件eureka.client.registry-fetch-interval-seconds=5,设置5s执行一次,设置后,服务发现后台线程每5s执行一次;

1.1.2 eureka-server

(1)读写缓存自动过期时间
优化前:默认180s执行一次过期
优化后:设置为60s eureka.server.response-cache-auto-expiration-in-seconds=60s,设置后,没60s会过期一次读写缓存
(2)只读缓存开启(一级缓存)
是否采用只读缓存策略,只读策略对于缓存的数据不会过期
eureka.server.use-read-only-response-cache=true
(3)只读缓存和读写缓存(二级缓存)同步
优化前:默认30s同步一次
优化后:设置为5s同步一次eureka.server.response-cache-update-interval-ms=5
(4)自我故障感知(即非正常下线)
优化前:后台eviction任务默认60s执行一次
优化后:设置为5s执行检查一次,eureka.server.eviction-interval-timer-in-ms=5
(5)心跳检查周期
优化前:默认90s 周期检查一次,实际上代码bug导致90 s 2检查一次
优化后:设置为10s检查一次,eureka.instance.lease-expiration-duration-in-seconds=10
由于bug,实际结果为10s
2检查一次
(6)自我保护机制禁用
自我保护机制判断逻辑:判断每分钟的应有心跳(写死了2 服务数)和实际心跳0.85的值做对比。
优化前:自我保护机制开启,但是由于代码硬编码写死了每分钟需要有2次心跳,在修改了续约次数后,会出现很容易进入自我保护机制状态,不剔除服务
优化后:禁用自我保护机制eureka.server.enable-self-preservation=false

1.1.3 ribbon

(1)注册表获取时效性
优化前:erverListRefreshInterval参数默认写死为30s,除了第一次创建拉取注册表的后台线程时,1s后获取注册表,之后会每30s拉取一次注册表
优化后:myService.ribbon.ServerListRefreshInterval=5000,设置ribbon拉取注册表的后台线程周期,改为5s一次
(2)重试规则优化
重试规则:
RoundRobinRule:系统内置的默认负载均衡规范,直接round robin轮询,从一堆server list中,不断的轮询选择出来一个server,每个server平摊到的这个请求,基本上是平均的
AvailabilityFilteringRule:这个rule就是会考察服务器的可用性
如果3次连接失败,就会等待30秒后再次访问;如果不断失败,那么等待时间会不断变长
如果某个服务器的并发请求太高了,那么会绕过去,不再访问
WeightedResponseTimeRule:带着权重的,每个服务器可以有权重,权重越高优先访问,如果某个服务器响应时间比较长,那么权重就会降低,减少访问
ZoneAvoidanceRule:根据区域和分区来进行负载均衡,说白了,就是机房的意思
BestAvailableRule:忽略那些连接失败的服务器,然后尽量找并发比较低的服务器来请求
RandomRule:随机找一个服务器
RetryRule:可以重试,就是通过round robin找到的服务器请求失败,可以重新找一个服务器
优化前:默认适用RoundRobinRule(顺序轮询)规则,均匀的将请求发送到不同的服务,不关心服务是否可用,容易出现在服务异常下线的一段时间内,会有部分请求异常的现像
优化后:借助ribbon的多种负载均衡规则,根据业务也选择不同的负载均衡规则。例如选择RetryRule,轮询找到服务器失败,重试从列表中找到下一台服务。

1.2结合feign和Hystrix组件的服务可用性、资源隔离的优化思路

(1)feignclien的fallback
fallback逻辑需要自己定制,在代码异常的场景下,如果没有定义fallback逻辑,在Hystrix断路器中执行降级的时候,会出现异常被吞的情况,只有走fallback逻辑才能看到异常
(2)Hystrix的资源隔离的参数优化思路
服务器配置:基于服务器配置和压测结果估算服务器的qps范围以及线程数量的合理性,例如4c 8g的服务器,tomcat参数设置为230线程数为佳,可以抗下1500-2000qps
下游服务的访问压力:基于服务的请求访问量,估算每个服务需要的线程池/信号量大小,例如申报/订单服务qps高,线程数/信号量就多分配一些,如果少就少分配一些
线程池模式下的队列选择:根据请求的平均响应时长,选择队列及设置队列的长度,例如,在请求处理速度较快的场景下,适用默认的SynchronousQueue,不排队,在请求处理时长较长的情况下,设置队列为BlockingQueue,并设置超时熔断参数的周期,例如默认1s,可以调整为2s
断路器开启:尽量打开短路器,当出现服务不可用的时候(某一段时间出现了一定数量的请求失败),短路器执行熔断操作,一段时间后(5s)半开启状态,尝试重新发送请求到该服务

1.3优化结果:

(1)主动注册/下线毫秒级 服务发现5-10s (5s拉取和5s同步读写缓存)
(2)自我感知下线(故障下线) 20-25s 服务发现30s-35s
(2)主动注册/下线毫秒级,ribbon获取注册表,5-15秒 (5s拉取和5s同步读写缓存,5s
Ribbon后台线程拉取注册表)
(4)服务异常下线的一段时间内,请求可以基于ribbon设置的负载均衡规则,规避掉失败服务,让整个系统继续运转
(5)在下游服务异常的时候,有fallback逻辑,可以正常返回,并且不会吞掉异常
(6)合理分配线程池/信号量资源,发挥服务器性能
(7)服务不可用的情况下,短路机制+半开启机制保证服务的熔断和重试