【Hoxton.SR1版本】Spring Cloud Ribbon负载均衡服务调用
目录
一、简介
二、Ribbon架构说明
三、负载均衡演示
四、Ribbon负载均衡策略
五、如何替换默认的轮训策略?
六、自定义轮询算法
七、总结
一、简介
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如超时、重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助我们基于某种规则(如简单轮训、随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。
Ribbon相关官网可以参考如下地址:https://github.com/Netflix/ribbon
由上面的官网,我们可以看到Ribbon已经进入了维护模式:
但是由于Ribbon功能太强大,并且目前在生产环境大量使用,Spring Cloud想推出Load Balancer去替代Ribbon,但是目前为止,还没完全替代Ribbon。
- Ribbon能干嘛?
Ribbon主要提供服务负载均衡调用的功能,简单的说,就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)
,常见的负载均衡有软件Nginx,LVS,硬件F5等。主要分为下面两种方式:
- 集中式负载均衡
例如Nginx就是集中式负载均衡,Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由nginx实现请求转发,即负载均衡是由服务器实现的。
- 进程内负载均衡
Ribbon就属于进程内负载均衡,是本地负载均衡,在调用微服务接口的时候,会在注册中心获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。
二、Ribbon架构说明
Ribbon大体架构如下图所示:
说明:服务消费者自身集成Ribbon客户端负载均衡软件,它会去服务注册中心查询当前可用的服务注册列表,然后根据用户指定的负载均衡策略,去请求目前空闲的一个服务提供者进行调用。
三、负载均衡演示
其实在前面几节文章中我们都实现了Ribbon负载均衡的功能,我们可以启动:
五个微服务,这几个微服务在前面章节中都已经详细实现过,这里不再过多说明。浏览器多次访问:http://localhost/consumer/payment/get/3,观察运行结果:
可见,我们默认是按照轮训的负载均衡策略进行远程调用,实质最主要的配置就是RestTemplate + @LoadBalanced注解实现。
/*** @Description 全局配置文件类* @Date 2020/7/25 15:45* @Author weishihuai* 说明: 此处配置也可以放在主启动类中*/
@Configuration
public class CustomConfig {//注册到spring ioc容器中@Bean@LoadBalanced //开启负载均衡功能public RestTemplate restTemplate() {return new RestTemplate();}}
细心的小伙伴可能会发现,查看我们服务消费方的maven依赖,我们看到其实我们并没有引入Ribbon的相关依赖包,但是为啥它也能实现服务的负载均衡呢?
原因其实是:在新版本的SpringCloud中,当引入了spring-cloud-starter-netflix-eureka-client Eureka客户端依赖包之后,其实就自动帮我们引入Ribbon负载均衡的依赖。下面我们查看spring-cloud-starter-netflix-eureka-client这个包依赖的其他包信息:
四、Ribbon负载均衡策略
Ribbon负载均衡策略主要的组件就是IRule组件,根据特定算法从服务列表中选取一个要访问的服务。IRule是一个接口,源码如下:
package com.netflix.loadbalancer;public interface IRule {Server choose(Object var1);void setLoadBalancer(ILoadBalancer var1);ILoadBalancer getLoadBalancer();
}
主要的策略实现类有下面几种,UML类图如下所示:
- RoundRobinRule:轮训算法,也是默认算法
- RandomRule : 随机策略算法;
- RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内进行重试;
- BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务;
- AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例;
- WeightedResponseTimeRule:对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择;
五、如何替换默认的轮训策略?
其实并不是所有业务场合都适合使用默认的轮训算法进行负载均衡,有时候我们确实有需要去替换掉默认的轮训算法,接下来我们讲解如何替换默认的轮训策略,指定其他策略算法或者自定义自己的策略规则。
这里需要注意一点:
官方文档明确给出了警告:自定义配置类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的。简单的说,自定义Ribbon算法的时候,自定义类不能够放在@ComponentScan下扫描的包以及子包下,因此MyRule.java不能放在SpringBoot启动类的包以及子包下。例如下图这种结构:
主要步骤有以下两步:
【a】自定义ribbon配置类
package com.wsh.myrule;import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** @Description 自定义ribbon配置类不能够放在@ComponentScan下扫描的包以及子包下.* @Date 2020/8/4 15:16* @Author weishihuai* 说明: */
@Configuration
public class CustomRibbonConfig {@Beanpublic IRule customRule() {//定义为随机策略return new RandomRule();}}
【b】启动类指定我们自己的负载均衡算法
@SpringBootApplication
@EnableEurekaClient
//指定我们自己配置的负载均衡策略
@RibbonClient(name = "SPRINGCLOUD-PAYMENT-SERVICE", configuration = CustomRibbonConfig.class)
public class OrderServiceApplication80 {public static void main(String[] args) {SpringApplication.run(OrderServiceApplication80.class, args);}
}
【c】启动项目,通过浏览器访问三次:http://localhost/consumer/payment/get/3,运行结果如下图所示:
可见,我们替换了随机策略后,ribbon客户端在挑选服务的时候就采用的随机性去选择空闲的服务进行调用了。
六、自定义轮询算法
接下来,我们仿照着RoundRobinRule轮询策略的源码,自己手写一个简单的轮训负载均衡算法。
【a】服务提供者8001、8002微服务的controller增加对应的方法
@GetMapping(value = "/payment/customLoadBalancer")public String customLoadBalancer() {return "当前服务实例端口号:" + serverPort;}
【b】服务消费者order80注释掉@LoadBalanced,关闭自带的负载均衡功能
@Configuration
public class CustomConfig {//注册到spring ioc容器中@Bean
// @LoadBalanced //开启负载均衡功能public RestTemplate restTemplate() {return new RestTemplate();}}
【c】自定义LoadBalancer接口
package com.wsh.springcloud.loadbalance;import org.springframework.cloud.client.ServiceInstance;import java.util.List;/*** @Description 自定义LoadBalancer* @Date 2020/8/4 16:13* @Author weishihuai* 说明:*/
public interface CustomLoadBalancer {/*** 从Eureka服务注册列表中获取某个服务实例** @param serviceInstanceList 服务注册列表* @return*/ServiceInstance getInstances(List<ServiceInstance> serviceInstanceList);}
【d】自定义LoadBalancer实现类
package com.wsh.springcloud.loadbalance;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;/*** @Description 自定义LoadBalancer实现类* @Date 2020/8/4 16:13* @Author weishihuai* 说明:*/
@Component
public class CustomLoadBalancerImpl implements CustomLoadBalancer {private static final Logger logger = LoggerFactory.getLogger(CustomLoadBalancerImpl.class);//原子整形类private AtomicInteger atomicInteger = new AtomicInteger(0);/**** @return*/public final int getAndIncrement() {int current;//记录第几次访问int visitIndex;//自旋锁比较do {//获取当前值current = this.atomicInteger.get();visitIndex = current >= Integer.MAX_VALUE ? 0 : (current + 1);} while (!this.atomicInteger.compareAndSet(current, visitIndex)); //采用CAS算法保证原子操作logger.info("第几次访问次数 : {}", visitIndex);return visitIndex;}@Overridepublic ServiceInstance getInstances(List<ServiceInstance> serviceInstanceList) {int index = getAndIncrement() % serviceInstanceList.size();return serviceInstanceList.get(index);}}
【e】服务消费者order80增加如下方法:
@GetMapping("/consumer/payment/customLoadBalancer")public String customLoadBalancer() {List<ServiceInstance> instances = discoveryClient.getInstances("SPRINGCLOUD-PAYMENT-SERVICE");if (instances == null || instances.size() <= 0) {return null;}ServiceInstance serviceInstance = customLoadBalancer.getInstances(instances);//获取服务提供者的URIURI serviceInstanceUri = serviceInstance.getUri();return restTemplate.getForObject(serviceInstanceUri + "/payment/customLoadBalancer", String.class);}
【f】启动项目,浏览器访问多次:http://localhost/consumer/payment/customLoadBalancer,运行结果如下图:
可见,如上四次访问,ribbon客户端采用了轮询策略进行了访问。
七、总结
以上就是Ribbon服务负载均衡搭建的详细过程,相关项目的代码我已经放在Gitee上,有需要的小伙伴可以去拉取进行学习:https://gitee.com/weixiaohuai/springcloud_Hoxton,由于笔者水平有限,如有不对之处,还请小伙伴们指正,相互学习,一起进步。
【Hoxton.SR1版本】Spring Cloud Ribbon负载均衡服务调用相关推荐
- Spring Cloud Ribbon 负载均衡客户端调用示例
承接 Spring Cloud 最简入门示例 这一篇, 本篇演示如何使用负载均衡客户端 Ribbon 调用在Eureka注册的服务. Ribbon 是什么? Ribbon是Netflix 的开源项目, ...
- 【详解】Ribbon 负载均衡服务调用原理及默认轮询负载均衡算法源码解析、手写
Ribbon 负载均衡服务调用 一.什么是 Ribbon 二.LB负载均衡(Load Balancer)是什么 1.Ribbon 本地负载均衡客户端 VS Nginx 服务端负载均衡的区别 2.LB负 ...
- SpringCloud[04]Ribbon负载均衡服务调用
文章目录 Ribbon负载均衡服务调用 1. 概述 1. Ribbon是什么 2. Ribbon能做什么 2. Ribbon负载均衡演示 1. 架构说明 2. Ribbon的POM依赖 3. Rest ...
- Ribbon负载均衡服务调用
一:关于Ribbon Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端 负载均衡的工具. 简单的说,Ribbon是Netflix发布的开源项目,主要 ...
- Spring Cloud Ribbon负载均衡策略详解
通过之前的文章可以知道, Ribbon负载均衡器选择服务实例的方式是通过"选择策略"实现的, Ribbon实现了很多种选择策略,UML静态类图如上图. IRule是负载均衡的策略接 ...
- Spring Cloud Ribbon 负载均衡策略
1.接口 IRule public interface IRule{//选择serverpublic Server choose(Object key);//设置LoadBalancerpublic ...
- Spring Cloud的负载均衡Spring Cloud Ribbon和Spring Cloud Feign
一.客户端负载均衡:Spring Cloud Ribbon. Spring Cloud Ribbon是基于HTTP和TCP的客户端负载工具,它是基于Netflix Ribbon实现的.通过Spring ...
- 客户端负载均衡Ribbon之一:Spring Cloud Netflix负载均衡组件Ribbon介绍
Netflix:['netfliːks] ribbon:英[ˈrɪbən]美[ˈrɪbən] n. 带; 绶带; (打印机的) 色带; 带状物; v. 把-撕成条带; 用缎带装饰; 形成带状; ...
- Spring Cloud LoadBalancer(负载均衡)
简介 了解过Spring Cloud,就知道,之前Spring Cloud中默认的负载均衡组件为ribbon,ribbon是Netflix开源的组件,但是目前已经停止更新了.所以Spring官方推出了 ...
- ribbon, restTemplate 负载均衡服务调用
ribbon ribbon concept ribbon核心组件IRule 模仿源码重写轮询 ribbon concept spring cloud ribbon 是基于Netflix ribbon实 ...
最新文章
- Android 学习视频
- 物联网技术的基站能耗监控解决方案
- 2021年 IOS的发布流程(企业版那 无法下载,无法安装)
- 基于ASAM ODS标准的试验数字化平台-WDP
- arm synchronization primitives
- 【作业】第一章课后作业
- 电机学他励直流发电机matlab,华南理工电机学随堂练习答案完整版
- DOA_GAN的近似复现
- 【牛客内部题:富婆价值最大化!】模拟贪心C++
- 基于python3+opencv3遥感影像的湖泊边界提取
- Sharepoint + Office Infopart + Quick Apps for Sharepoint搭建无纸化工作平台
- Windows10忘记Microsoft账户密码桌面登录进不去,不重装系统删除微软账户更改本地用户登录
- 从奥本海默的浮沉谈科学与政治的关系
- Snipaste 提高十倍生产力工作效率,堪称最强神器
- C#WPF开发环境配置
- 芯出海tiktok云控制系统
- vue 大屏数据展示组件
- 数独问题求解二:解题思路(1)
- python系统学习日记 L22~L24 练习
- ST股票投机(*ST航通)
热门文章
- java实时推送_JAVA 基于websocket的前台及后台实时推送
- 全局 快捷键_表格快捷键
- 函数 strcmp_【函数分享】每日PHP函数分享(2020630)
- 跑毒的乌龟-0 : 随机漫步
- 线性代数 : 方程组的几何解释
- C/C++[codeup 1808]字符串查找删除
- Data Visualization [--0]
- 机器学习- 吴恩达Andrew Ng Week9 知识总结 Recommender Systems
- swift5的下标Subscripts 花式玩法
- 计算机网络实验报告 接墙上的,计算机网络实验报告模板.doc