网站推广信息怎么做,做效果图的网站有哪些,工程建设的基本步骤,微信小程序开发模板网站一、先看下流程图 备注#xff1a;红色后面都为拦截器的逻辑#xff0c;主要是加载配置文件【LoadBalancerAutoConfiguration】#xff0c;对发送http请求的RestTemplate进行包装拦截#xff0c;逻辑拦在拦截器里面。
二、LoadBalancerAutoConfiguration
负载均衡用到配置…一、先看下流程图 备注红色后面都为拦截器的逻辑主要是加载配置文件【LoadBalancerAutoConfiguration】对发送http请求的RestTemplate进行包装拦截逻辑拦在拦截器里面。
二、LoadBalancerAutoConfiguration
负载均衡用到配置类LoadBalancerAutoConfiguration
LoadBalancerAutoConfiguration主要做2个事情。1、生成Bean: LoadBalancerInterceptor 拦截器
2、生成Bean: RestTemplateCustomizer 这个是RestTemplate的包装对象里面拿到上面生成的拦截器
然后把拦截器添加到RestTemplate里面去。restTemplate每次执行方法请求时都会调用【intercept方法】执行拦截
在intercept方法里面通过【服务名】获取了该服务对应的【负载均衡器ILoadBalancer】的实例对象
然后调用该实例的chooseServer方法获取一个具体【服务实例】然后发送http请求服务提供者。三、LoadBalancerClient
在Ribbon中有个非常重要的组件LoadBalancerClient它是【负载均衡的客户端】通过LoadBalancerClient的方法
我们只需要传一个【服务名】那么LoadBalancerClient就会根据【服务名】返回对应的【负载均衡器】而LoadBalancerClient是一个接口真正的实现类正是RibbonLoadBalancerClient逻辑都在choos方法里面
先通过【服务Id】拿到ILoadBalancer这个也叫【负载均衡器】下面看下ILoadBalancer【负载均衡器】ILoadBalancer的实现类有ZoneAwareLoadBalancer
主要包含以下2个内容
1、里面的allServerList列表已经缓存了所有的服务列表
2、里面还有个属性IRule这个就是真正负载均衡算法的核心当负载均衡器调用chooseServer方法时会通过负载均衡算法IRule返回哪一个具体的Server这个就是我们最终要调用的服务Ip端口。ILoadBalancer接口定义了Ribbon中核心的两项内容【服务获取】与【服务选择】
可以说ILoadBalancer是Ribbon中最重要的一个组件它起到了承上启下的作用既要连接 Eureka获取服务地址
又要调用IRule利用负载均衡算法选择服务服务获取
Ribbon在选择之前需要获取服务列表而Ribbon本身不具有服务发现的功能
所以需要借助Eureka来解决获取服务列表的问题, 其实在获取实例的过程中
1、先他得到一个EurekaClient的实例然后借助EurekaClient的服务发现功能来获取服务的实例列表。
2、在获取了实例信息后判断服务的状态如果为UP那么最终将它加入serverList中。在获取得到serverList后会进行缓存操作。首先进入BaseLoadBalancer的setServerList方法
里面会往下面2个缓存赛数据将拉取的serverList赋值给缓存列表allServerList。 protected volatile ListServer allServerList Collections.synchronizedList(new ArrayListServer());
protected volatile ListServer upServerList Collections.synchronizedList(new ArrayListServer());Ribbon从Eureka中得到了服务列表缓存在本地List后存在一个问题如何保证在调用服务的时候服务仍然处于可用状态
也就是说应该如何解决缓存列表脏读问题在默认负载均衡器ZoneAwareLoadBalancer#setupPingTask方法中里面创建了一个定时任务使用ping的方式判断服务是否可用。怎么ping的呢不是判断网络通不通这个ping只是他的方法这么叫实际上还是通过查询EurekaServer返回服务的状态来判断。
因为本地的serverList为缓存值可能与eureka中不同所以从eureka中去查询该实例的状态
如果eureka里面显示该实例状态为UP就返回true说明服务可用。
通过调用EurekaServer的接口获取到服务的状态列表后进行循环如果状态改变加入到changedServers中
并且把所有可用服务加入newUpList最终更新upServerList中缓存值除了使用ping的方式去检测服务是否在线外Ribbon还使用了别的方式来更新服务列表。使用了定时调度线程池调用了PollingServerListUpdater#start方法来进行更新服务操作Ribbon为了解决服务列表的脏读现象采用了两种手段
1、更新列表 定时任务
2、ping机制 定时任务更新机制和ping机制功能基本重合并且在ping的时候不能执行更新在更新的时候不能运行ping所以很难检测到ping失败的情况。负载均衡算法 Ribbon默认使用的是ZoneAvoidanceRule也叫【区域亲和】负载均衡算法优先调用一个zone区间中的服务
并使用轮询算法。当然也可以由我们自己实现IRule接口重写其中的choose方法来实现自己的负载均衡算法然后通过Bean的方式注入到spring容器中。
当然也可以将不同的服务应用不同的IRule策略这里需要注意的是Spring cloud的官方文档中提醒我们
如果多个微服务要调用不同的IRule那么创建出IRule的配置类不能放在ComponentScan的目录下面
这样所有的微服务都会使用这一个策略。总结
综上所述在Ribbon的负载均衡中大致可以分为以下几步
1、拦截请求通过请求中的url地址截取服务名称
2、通过LoadBalancerClient获取ILoadBalancer
3、使用Eureka获取服务列表
4、通过IRule负载均衡策略选择具体服务
5、ILoadBalancer通过IPing及定时更新机制来维护服务列表
6、重构该url地址最终调用HttpURLConnection发起请求了解了整个调用流程后我们更容易明白为什么Ribbon叫做客户端的负载均衡。与nginx服务端负载均衡不同
1、nginx在使用反向代理具体服务的时候调用端不知道都有哪些服务。
2、Ribbon在调用之前已经知道有哪些服务可用直接通过本地负载均衡策略调用即可。
而在实际使用过程中也可以根据需要结合两种方式真正实现高可用。