首页 > 其他分享 >Ribbon是如何进行负载的

Ribbon是如何进行负载的

时间:2023-08-29 15:33:56浏览次数:31  
标签:负载 调用 服务 如何 clientConfig Ribbon 加载

1.Ribbon是如何进行负载的

    配置类:RibbonClientConfiguration
     @Bean
	@ConditionalOnMissingBean
	public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
			ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,
			IRule rule, IPing ping, ServerListUpdater serverListUpdater) {
		if (this.propertiesFactory.isSet(ILoadBalancer.class, name)) {
			return this.propertiesFactory.get(ILoadBalancer.class, config, name);
		}

          //默认的负载均衡类
		return new ZoneAwareLoadBalancer<>(config, rule, ping, serverList,
				serverListFilter, serverListUpdater);
	}
    
  //DynamicServerListLoadBalancer
  public DynamicServerListLoadBalancer(IClientConfig clientConfig, IRule rule, IPing ping,
                                         ServerList<T> serverList, ServerListFilter<T> filter,
                                         ServerListUpdater serverListUpdater) {
        super(clientConfig, rule, ping);
        this.serverListImpl = serverList;
        this.filter = filter;
        this.serverListUpdater = serverListUpdater;
        if (filter instanceof AbstractServerListFilter) {
            ((AbstractServerListFilter) filter).setLoadBalancerStats(getLoadBalancerStats());
        }
        //初始化
        restOfInit(clientConfig);
    }

//方法
 void restOfInit(IClientConfig clientConfig) {
        boolean primeConnection = this.isEnablePrimingConnections();
        // turn this off to avoid duplicated asynchronous priming done in BaseLoadBalancer.setServerList()
        this.setEnablePrimingConnections(false);
        enableAndInitLearnNewServersFeature();

        updateListOfServers();
        if (primeConnection && this.getPrimeConnections() != null) {
            this.getPrimeConnections()
                    .primeConnections(getReachableServers());
        }
        this.setEnablePrimingConnections(primeConnection);
        LOGGER.info("DynamicServerListLoadBalancer for client {} initialized: {}", clientConfig.getClientName(), this.toString());
    }


  负载均衡类:DynamicServerListLoadBalancer

  //定时任务处理类
  PollingServerListUpdater
  @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);
                    }
                }
            };
            
            //默认时间 30秒 因此一个新的服务端上线后,客户端需要最多30秒才能进行使用
            scheduledFuture = getRefreshExecutor().scheduleWithFixedDelay(
                    wrapperRunnable,
                    initialDelayMs,
                    refreshIntervalMs,
                    TimeUnit.MILLISECONDS
            );
        } else {
            logger.info("Already active, no-op");
        }
    }
//


2. Ribbon负载均衡策略

  1. RoundRobinRule(轮询策略,按照服务顺序依次循环调用) 默认
  2. WeightedResponseTimeRule(权重比策略,优先选择权重比高的服务,也就是服务响应时间比较短的,响应时间越长权重比越低)
  3. RandomRule(随机策略,服务提供者列表随机选择一个服务)
  4. BestAvailableRule(最小连接数策略,获取服务列表中连接数最小的服务实例)
  5. RetryRule(重试策略,重试获取已经失效的服务,指定时间没有获取到返回NULL)
  6. AvailabilityFilteringRule(可用性敏感策略,过滤非健康服务实例,选择lianji)
  7. ZoneAvoidanceRule(区域敏感策略)

3.具体的调用执行

@Override
  public Response execute(Request request, Request.Options options) throws IOException {
  	try {
  		URI asUri = URI.create(request.url());
  		String clientName = asUri.getHost();
  		URI uriWithoutHost = cleanUrl(request.url(), clientName);
  		FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
  				this.delegate, request, uriWithoutHost);
          
          //获取配置 即初始化配置 
  		IClientConfig requestConfig = getClientConfig(options, clientName);
          
          //lbClient会创建client 此时才会加载服务端 每间隔30秒调用一次
  		return lbClient(clientName)
  				.executeWithLoadBalancer(ribbonRequest, requestConfig).toResponse();
  	}
  	catch (ClientException e) {
  		IOException io = findIOException(e);
  		if (io != null) {
  			throw io;
  		}
  		throw new RuntimeException(e);
  	}
  }
  

4. Ribbon-eager-load(饥饿加载)模式

Ribbon 对于负载 Client 是在服务启动后,发生调用的时候才会去创建 Client,所以在第一次发生 http 请求调用的时候,不光要算上 http 的请求时间,还要算上 Client 的创建时间,所以第一次调用的时候才会很慢,具体内容参考第三点
Ribbon 的 DynamicServerListLoadBalancer 会将 feign 客户端进行负载,然后进行调用,第一次调用的时间就是会长一些,第二次调用直接进行请求可以看到调用时间很快。

5. 开启饥饿负载

ribbon:
nacos:
  enabled: true # 开启naocos轮询
eager-load:
 enabled: true  # 开启Ribbon的饥饿加载模式(防止第一次请求超时的问题)
 clients: Lxlxxx-system2 # 指定需要开启的服务(需要开启Ribbon的饥饿加载模式)
 ReadTimeout: 10000
 ConnectTimeout: 10000
 MaxAutoRetries: 0
 MaxAutoRetriesNextServer: 1
 OkToRetryOnAllOperations: false

在项目启动的时候,可以从日志看到,已经把 Lxlxxx-system2 服务进行加载,从而避免了第一次请求超时的情况

其实这种饥饿加载模式,类似于“客户端负载预热”的一个操作,项目启动的时候进行加载,防止服务之间调用可以因为数据量、业务逻辑处理复杂性导致接口超时,如果你的服务之间调用业务处理比较复杂、且慢,不妨可以试试这种解决方式。

标签:负载,调用,服务,如何,clientConfig,Ribbon,加载
From: https://www.cnblogs.com/hopeway-shaon/p/17664557.html

相关文章

  • 视频汇聚/视频云存储/视频监控管理平台EasyCVR接入海康SDK协议后无法播放该如何解决?
    开源EasyDarwin视频监控/安防监控/视频汇聚EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,视频安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多路视频流,也能支持视频定时轮播。视频监控汇聚平台EasyCVR支持多种播放......
  • 当某个excel工作簿的某个单元格的值发生变动时, 自动执行python某脚本, 如何实现?
    要实现当Excel工作簿中的某个单元格值发生变化时自动执行Python脚本,你可以考虑以下步骤:监视单元格变化:首先,你需要实现监视Excel工作簿中的特定单元格是否发生了变化。这可以通过使用VBA(VisualBasicforApplications)宏来实现。打开Excel工作簿,按下ALT+F11打开VBA编辑器,然后......
  • 国标视频平台EasyGBS如何使用对应密钥上传到其他平台
    GB28181视频平台EasyGBS是一个基于国标GB28181协议的视频云服务平台。它支持多路设备同时接入,并能将视频流以RTSP、RTMP、FLV、HLS、WebRTC等格式分发给多个平台和终端。该平台提供视频监控直播、云端录像、云存储、检索回放、智能告警以及语音对讲等功能。在视频能力方面,EasyGBS支......
  • 【民生】【省钱】最便宜的电话卡办理方式 | 最便宜的手机卡办理方式 | 话费如何用最省
    目录:1、最便宜的电话卡办理方式。2、话费如何用最省钱?3、如何充话费最省钱?或在哪里充值最便宜?4、注意事项及总结。一、最便宜的电话卡办理方式就是普通电话卡手机卡办理,如何办理最便宜,在哪里办理?(不是物联网卡)。官网:新办卡:1)、中国移动:已改为APP或者小程序中办理:下载官......
  • 如何使用本地电脑搭建一个属于自己的网站
    本地电脑搭建Web服务器并用cpolar发布至公网访问@[TOC]前言随着互联网的快速发展,网络也成为我们生活中不可缺少的必要条件,为了能在互联网世界中有自己的一片天地,建立一个属于自己的网页就成为很多人的选择。但互联网行业作为资本密集的行业,委托别人建立一个像样的网站要花费不少,不......
  • 你是如何阅读jdk源码的?
    阅读别人的代码作为开发人员是一件经常要做的事情。一个是学习新的编程语言的时候通过阅读别人的代码是一个最好的学习方法,另外是积累编程经验。如果你有机会阅读一些操作系统的代码会帮助你理解一些基本的原理。还有就是在你作为一个质量保证人员或一个小领导的时候如果你要做白盒......
  • 泡奶机防干烧功能如何实现的
    泡奶机的防干烧功能是通过光电液位传感器实现的。光电液位传感器内置了红外发射管和光敏接收器,并采用了棱镜结构作为检测部位。当泡奶机处于无水状态时,发射管所发出的光经过透镜后会折射至接收器。而当泡奶机中有水时,光会折射到液体中,从而使接收器收不到或只能接收到少量光线。通过......
  • MODBUS RTU协议中浮点数是如何存储,读到浮点数寄存器的数值如何转换成所需的浮点数
    原文连接浮点数保存的字节格式如下:地址+0+1+2+3内容SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM这里S代表符号位,1是负,0是正E偏移127的幂,二进制阶码=(EEEEEEEE)-127。M24位的尾数保存在23位中,只存储23位,最高位固定为1。此方法用最较少的位数实现了较高的有效位数,提高了精......
  • 【个人杂谈】假如我是一个前端工程师,我该如何在日常的学习过程中使用费曼学习法?
    什么是费曼学习法?费曼学习法是一种学习方法,它由诺贝尔物理学奖得主理查德·费曼(美籍犹太裔物理学家,加州理工学院物理学教授,1965年诺贝尔物理奖得主)提出。该方法的核心思想是通过将所学的知识以简单明了的方式解释给别人,来加深自己对知识的理解和掌握。具体来说,费曼学习法包括以......
  • 【Vue】vue3 中 如何将el-table的表格数据下载为.xlsx格式文件
    安装依赖首先,你需要安装xlsx和file-saver这两个库。npminstallxlsxfile-saver--save有兴趣可以看看两个库的官方说明,直接看下面使用也没问题。xlsx官方介绍TheSheetJSCommunityEditionoffersbattle-testedopen-sourcesolutionsforextractingusefuldata......