万字剖析Ribbon核心组件以及运行原理

🚀 优质资源分享 🚀

学习路线指引(点击解锁) 知识定位 人群定位
🧡 Python实战微信订餐小程序 🧡 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

大家好,本文我将继续来剖析SpringCloud中负载均衡组件Ribbon的源码。本来我是打算接着OpenFeign动态代理生成文章直接讲Feign是如何整合Ribbon的,但是文章写了一半发现,如果不把Ribbon好好讲清楚,那么有些Ribbon的细节理解起来就很困难,所以我还是打算单独写一篇文章来剖析Ribbon的源码,这样在讲Feign整合Ribbon的时候,我就不再赘述这些细节了。好了,话不多说,直接进入主题。

一、Ribbon的核心组件

1、Server

这是个很简单的东西,就是服务实例数据的封装,里面封装了服务实例的ip和端口之类的,一个服务有很多台机器,那就有很多个Server对象。

2、ServerList

?

| 123456789101112 | public interface ServerListextends Server> {  `public` `List getInitialListOfServers();` `/*** Return updated list of servers. This is called say every 30 secs* (configurable) by the Loadbalancer's Ping cycle /``public List getUpdatedListOfServers();  }` |

ServerList是个接口,泛型是Server,提供了两个方法,都是获取服务实例列表的,这两个方法其实在很多实现类中实现是一样的,没什么区别。这个接口很重要,因为这个接口就是Ribbon获取服务数据的来源接口,Ribbon进行负载均衡的服务列表就是通过这个接口来的,那么可以想一想是不是只要实现这个接口就可以给Ribbon提供服务数据了?事实的确如此,在SpringCloud中,eureka、nacos等注册中心都实现了这个接口,都将注册中心的服务实例数据提供给Ribbon,供Ribbon来进行负载均衡。

3、ServerListUpdater

通过名字也可以知道,是用来更新服务注册表的数据,他有唯一的实现,就是PollingServerListUpdater,这个类有一个核心的方法,就是start,我们来看一下start的实现。

?

| 12345678910111213141516171819202122232425262728293031 | @Override``public synchronized void start(``final UpdateAction updateAction) {``if (isActive.compareAndSet(``false``, true``)) {``final Runnable wrapperRunnable = new Runnable() {``@Override``public void run() {``if (!isActive.get()) {``if (scheduledFuture != null``) {``scheduledFuture.cancel(``true``);``}``return``;``}``try {``updateAction.doUpdate();``lastUpdated = System.currentTimeMillis();``} catch (Exception e) {``logger.warn(``"Failed one update cycle"``, e);``}``}``}; scheduledFuture = getRefreshExecutor().scheduleWithFixedDelay(``wrapperRunnable,``initialDelayMs,``refreshIntervalMs,``TimeUnit.MILLISECONDS``);``} else {``logger.info(``"Already active, no-op"``);``}``} |

通过这段方法我们可以看出,首先通过isActive.compareAndSet(false, true)来保证这个方法只会被调用一下,然后封装了一个Runnable,这个Runnable干了一件核心的事,就是调用传入的updateAction的doUpdate方法,然后将Runnable扔到了带定时调度功能的线程池,经过initialDelayMs(默认1s)时间后,会调用一次,之后都是每隔refreshIntervalMs(默认30s)调用一次Runnable的run方法,也就是调用updateAction的doUpdate方法。

所以这个类的核心作用就是每隔30s会调用一次传入的updateAction的doUpdate方法的实现,记住这个结论。

4、IRule

?

| 123456789101112131415 | public interface IRule{``/*``* choose one alive server from lb.allServers or``* lb.upServers according to key``* * @return choosen Server object. NULL is returned if none``*  server is available */ public Server choose(Object key); public void setLoadBalancer(ILoadBalancer lb); public ILoadBalancer getLoadBalancer(); } |

IRule是负责负载均衡的算法的,也就是真正实现负载均衡获取一个服务实例就是这个接口的实现。比如说实现类RandomRule,就是从一堆服务实例中随机选取一个服务实例。

5、IClientConfig

就是一个配置接口,有个默认的实现DefaultClientConfigImpl,通过这个可以获取到一些配置Ribbon的一些配置。

6、ILoadBalancer

?

| 123456789101112131415 | public interface ILoadBalancer {  public void addServers(List newServers); public Server chooseServer(Object key); public void markServerDown(Server server); @Deprecated``public List getServerList(``boolean availableOnly); public List getReachableServers(); public List getAllServers();``} |

这个接口的作用,对外主要提供了获取服务实例列表和选择服务实例的功能。虽然对外主要提供获取服务的功能,但是在实现的时候,主要是用来协调上面提到的各个核心组件的,使得他们能够协调工作,从而实现对外提供获取服务实例的功能。

这个接口的实现有好几个实现类,但是我讲两个比较重要的。

BaseLoadBalancer

?

| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 | public class BaseLoadBalancer extends AbstractLoadBalancer implements``PrimeConnections.PrimeConnectionListener, IClientConfigAware {  private final static IRule DEFAULT_RULE = new RoundRobinRule(); protected IRule rule = DEFAULT_RULE;``private IClientConfig config;  protected volatile List allServerList = Collections``.synchronizedList(``new ArrayList());``protected volatile List upServ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值