SpringCloud笔记(Dalston)——Netflix之Ribbon负载均衡
创始人
2025-05-31 00:30:21

Ribbon使用

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,简单的说,Ribbon是Netflix 发布的开源项目,主要功能是提供客户端软件的负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供了一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮你基于某种规则(如简单轮训,随机连接等)去连接这些机器。我们也很容易实现自定义的负载均衡算法。

代码示例

注册中心

这里是Eureka作为服务注册中心,为Ribbon提供服务端信息的获取,比如说服务的IP地址和端口,使用前面搭建好的项目(eureka-server)。

Provider

  1. 在idea中新建两个项目运行主类,选择前面创建好的项目(eureka-provider)。
    在这里插入图片描述
  2. 设置不同运行主类,使用不同端口号,然后启动三个不同端口号的provider。
    在这里插入图片描述

接口实现

调用不同的服务端,会返回对应服务端的接口。

@RestController
@RequestMapping("/api")
public class PoroviderController {@Value("${server.port}")private String serverPort;@PostMapping("/sayHello")public String sayHello(String name) {return "我是服务端" + serverPort + ",你好" + name;}
}

Consumer

新建一个spring-boot工程,取名为consumer-ribbon,在pom文件引入ribbon需要的依赖。

添加依赖

org.springframework.cloudspring-cloud-starter-eureka
org.springframework.cloudspring-cloud-starter-ribbon

配置端口、注册中心等

server:port: 8091
eureka:client:# false表示不向注册中心注册自己register-with-eureka: falseservice-url:defaultZone: http://localhost:8761/eureka/
spring:application:name: consumer-ribbon

RestTemplate配置

  • SpringCloud为客户端负载均衡创建了特定的注解@LoadBalanced,我们只需要使用该注解修饰创建RestTemplate实例的@Bean函数,SpringCloud就会让RestTemplate使用相关的负载均衡策略,默认情况下使用Ribbon。
  • 除了@LoadBalanced之外,Ribbon还提供@RibbonClient注解。该注解可以为Ribbon客户端声明名称和自定义配置。 name属性可以设置客户端的名称, configuration属性则会设置Ribbon相关的自定义配 类。
@Configuration
public class RestTemplateConfig {/*** @return org.springframework.web.client.RestTemplate* @description 注入一个可以进行负载均衡的RestTemple用于服务问调用* @author fengfan* @date 2022/5/18 14:43*/@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}}

全局配置负载

@Configuration
public class RibbonConfig {/*** @return com.netflix.loadbalancer.IRule* @description 配置随机负载策略* @author fengfan* @date 2022/5/20 16:04*/@Beanpublic IRule iRule(){return new RandomRule();}
}

单独配置负载

  1. 配置文件方法实现
# 服务提供方的单独配置设置(服务名称大小写必须和注册的一样)
EUREKA-PROVIDER:ribbon:ConnectTimeout: 1000 #服务请求连接超时时间(毫秒)ReadTimeout: 3000 #服务请求处理超时时间(毫秒)OkToRetryOnAllOperations: true #对超时请求启用重试机制MaxAutoRetriesNextServer: 1 #切换重试实例的最大个数MaxAutoRetries: 1 # 切换实例后重试最大次数NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #修改负载均衡算法
  1. 代码配置实现
@Configuration
public class MyRuleConfig {@Beanpublic IRule iRule() {return new RandomRule();}
}
@SpringBootApplication
@EnableEurekaClient
/*** 在启动改微服务的时候就能去加载我们自定义的Ribbon配置类,从而配置生效* 注意:MyRuleConfig 必须是 @Configuration ,但请注意,它不在主应用程序上下文* 的 @ComponentScan 中,否则将由所有 @RibbonClients 共享。* 如果您使用 @ComponentScan (或 @SpringBootApplication ),* 则需要采取措施避免包含(例如将其放在一个单独的,不重叠的包中,或者指定要在 @ComponentScan )*/
@RibbonClient(name = "EUREKA-PROVIDER", configuration = MyRuleConfig.class)
public class ConsumerRibbonApplication {public static void main(String[] args) {SpringApplication.run(ConsumerRibbonApplication.class, args);}}

自定义负载策略

这里自己将RandomRule抄一份,实际情况根据需求自己实现

public class ZDYRule extends AbstractLoadBalancerRule {@Overridepublic void initWithNiwsConfig(IClientConfig iClientConfig) {}@Overridepublic Server choose(Object o) {return this.choose(this.getLoadBalancer(), o);}public Server choose(ILoadBalancer lb, Object key) {if (lb == null) {return null;} else {Server server = null;while(server == null) {if (Thread.interrupted()) {return null;}List upList = lb.getReachableServers();List allList = lb.getAllServers();int serverCount = allList.size();if (serverCount == 0) {return null;}int index = this.chooseRandomInt(serverCount);server = (Server)upList.get(index);if (server == null) {Thread.yield();} else {if (server.isAlive()) {return server;}server = null;Thread.yield();}}return server;}}protected int chooseRandomInt(int serverCount) {return ThreadLocalRandom.current().nextInt(serverCount);}
}
@Configuration
public class MyRuleConfig {@Beanpublic IRule iRule() {return new ZDYRule();}
}

客户端调用实现

@RestController
@RequestMapping("/api")
public class ConsumerRibbonController {@Resourceprivate RestTemplate restTemplate;@PostMapping("/getServerInfo")public String getServerInfo(){MultiValueMap body = new LinkedMultiValueMap<>();body.add("name", "consumer8081");ResponseEntity responseEntity = restTemplate.postForEntity("http://EUREKA-PROVIDER/api/sayHello", body, String.class);return responseEntity.getBody();}
}

Ribbon的负载均衡策略

  • com.netflix.loadbalancer.RandomRule:从提供服务的实例中以随机的方式;
  • com.netflix.loadbalancer.RoundRobinRule:以线性轮询的方式,就是维护一个计数器,从提供服务的实例中按顺序选取,第一次选第一个,第二次选第二个,以此类推,到最后一个以后再从头来过;
  • com.netflix.loadbalancer.RetryRule:在RoundRobinRule的基础上添加重试机制,即在指定的重试时间内,反复使用线性轮询策略来选择可用实例;
  • com.netflix.loadbalancer.WeightedResponseTimeRule:对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择;
  • com.netflix.loadbalancer.BestAvailableRule:选择并发较小的实例;
  • com.netflix.loadbalancer.AvailabilityFilteringRule:先过滤掉故障实例,再选择并发较小的实例;
  • com.netflix.loadbalancer.ZoneAwareLoadBalancer:采用双重过滤,同时过滤不是同一区域的实例和故障实例,选择并发较小的实例。

测试

在这里插入图片描述

多次请求的服务端,端口随机变化,证明配置成功。
在这里插入图片描述

相关内容

热门资讯

冬季户外运动安全手册丨这份登山... 冬季山林裹着银霜 吸引着许多户外运动爱好者去探索 但冬季气温低、路面滑 登山徒步的风险随之增加 别...
六安十大著名网红景点有哪些 六安,这座充满魅力的城市,不仅有着悠久的历史文化,还拥有众多在网络上备受瞩目的网红景点。这些景点吸引...
4道简单又好吃的高薪面点师食谱... 在寒冷的冬季,您是否在寻找一些美味又营养的家庭食谱?是否希望孩子能爱上健康的饮食?今天,我们就来分享...
原创 香... 记得大学宿舍楼下有家小餐馆,老板做的煎鸡腿香得能顺着楼梯飘到五楼。我们几个室友经常凑钱买一份,就为抢...
原创 大... 大学食堂的酸辣土豆丝,是我们宿舍四年的集体记忆。每次打饭阿姨舀起那一勺泛着油光的土豆丝,酸辣味就直往...