SpringCloud学习笔记(2):使用Ribbon负载均衡

简介SpringCloudRibbon是基于NetflixRibbon实现的一套客户端负载均衡工具,在注册中心对Ribbon客户端进行注册后,Ribbon可以基于某种负载均衡算法,如轮询(默认)、随机、加权轮询、加权随机等自动帮助服务消费者调用接口。项目介绍sc-parent,父模块(请参照SpringCloud学习笔记(1):Eureka注册中心)sc-eureka,注册中心(请参照Spring...

SpringCloud学习笔记(2):使用Ribbon负载均衡

简介

Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,在注册中心对Ribbon客户端进行注册后,Ribbon可以基于某种负载均衡算法,如轮询(默认)、随机、加权轮询、加权随机等自动帮助服务消费者调用接口。

项目介绍

  1. sc-parent,父模块(请参照SpringCloud学习笔记(1):Eureka注册中心)
  2. sc-eureka,注册中心(请参照SpringCloud学习笔记(1):Eureka注册中心)
  3. sc-provider-random,随机端口的提供者
  4. sc-consumer,使用Ribbon负载均衡的消费者

随机端口的提供者

1.在父模块下创建子模块项目sc-provider-random,pom.xml:

<project xmlns=“http://maven.apache.org/POM/4.0.0“ xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“ xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd“>  <modelVersion>4.0.0</modelVersion>  <parent> <groupId>com.cf</groupId> <artifactId>sc-parent</artifactId> <version>0.0.1-SNAPSHOT</version>  </parent>  <artifactId>sc-provider-random</artifactId>    <dependencies> <dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>  </dependencies></project>

2.创建启动类provider.ProviderApplication:

package provider;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class ProviderApplication { public static void main(String[] args) {  SpringApplication.run(ProviderApplication.class, args); }}

3.创建Controller:provider.controller.BookController

package provider.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RequestMapping(“/book“)@RestControllerpublic class BookController {  @GetMapping(“/list“) public String getBookList(){  System.out.println(“------------我被访问了-----------“);  return “[\“Java入门到放弃\“,\“C  入门到放弃\“,\“Python入门到放弃\“,\“C入门到放弃\“]“; }}

4.创建application.yml:

server:  port: 0 #默认8080,配置随机端口需要设置为0spring:  application: name: sc-provider-randomeureka:  client: serviceUrl: defaultZone: http://localhost:8080/eureka/  instance: instance-id: ${spring.application.name}:${random.value} #实例名随机生成

5.依次启动注册中心sc-eureka以及两个提供者sc-provider-random,提供者sc-provider-random每次启动端口都不一样,可以看到sc-provider-random的两个实例都在注册中心注册:

使用Ribbon负载均衡的消费者

1.在父模块下创建子模块项目sc-consumer,pom.xml:

<project xmlns=“http://maven.apache.org/POM/4.0.0“ xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“ xsi:schemaLocation=“http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd“>  <modelVersion>4.0.0</modelVersion>  <parent> <groupId>com.cf</groupId> <artifactId>sc-parent</artifactId> <version>0.0.1-SNAPSHOT</version>  </parent>  <artifactId>sc-consumer</artifactId>    <dependencies> <dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>  <!-- spring-cloud-starter-netflix-eureka-client依赖中已经包含ribbon --> <!-- <dependency>  <groupId>org.springframework.cloud</groupId>  <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> -->  </dependencies></project>

2.创建启动类consumer.ConsumerApplication:

package consumer;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.web.client.RestTemplate;@SpringBootApplicationpublic class ConsumerApplication { public static void main(String[] args) {  SpringApplication.run(ConsumerApplication.class, args); }  //为RestTemplate整合Ribbon,使其具备负载均衡的能力 @LoadBalanced @Bean public RestTemplate restTemplate(){  return new RestTemplate(); }}

3.创建调用提供者服务的Controller:consumer.controller.ConsumerController

package consumer.controller;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;@RestControllerpublic class ConsumerController { @Autowired private RestTemplate restTemplate;  @GetMapping(“/getBookList“) public String getBookList(){  //sc-provider-random 为提供者服务名  return restTemplate.getForObject(“http://sc-provider-random/book/list“, String.class); }}

注意:在使用Ribbon负载均衡时,服务名称不能有下划线,否则会出现valid hostname异常

4.创建application.yml:

server:  port: 8083spring:  application: name: sc-consumer eureka:  client: registerWithEureka: false serviceUrl:defaultZone: http://localhost:8080/eureka/ 

5.依次启动注册中心sc-eureka、两个提供者sc-provider-random、消费者sc-consumer,并访问http://localhost:8083/getBookList:

多次访问后,通过控制台的日志打印可以发现消费者时通过轮询的方式访问两个提供者实例。

更改负载均衡策略

Ribbon默认使用RoundRobinRule(轮询)来做为负载均衡策略,我们可以实现IRule接口或者使用Ribbon提供的现成的负载均衡策略来替换默认的轮询策略。如下,使用随机访问的策略来替代默认的轮询,在消费者启动类中添加:

 @Bean public IRule randomRule(){  return new RandomRule();//使用随机访问的策略来替代默认的轮询 }

自定义负载均衡策略

一个自定义负载均衡策略小例子,依旧是轮询访问策略,只是每个服务实例访问5次后才会访问下一个服务实例。

1.创建类consumer.rule.MyRule:

package consumer.rule;import java.util.List;import com.netflix.client.config.IClientConfig;import com.netflix.loadbalancer.AbstractLoadBalancerRule;import com.netflix.loadbalancer.ILoadBalancer;import com.netflix.loadbalancer.Server;public class MyRule extends AbstractLoadBalancerRule { private int currIndex = 0;//当前服务实例索引  private int currCount = 0;//当前服务实例被访问次数  private static final int MAX_COUNT = 5;//每个服务实例最大访问次数为5 public Server choose(ILoadBalancer lb, Object key) {  if (lb == null) {return null;  }  Server server = null;  while (server == null) {if (Thread.interrupted()) { return null;}List<Server> upList = lb.getReachableServers();List<Server> allList = lb.getAllServers();int serverCount = allList.size();if (serverCount == 0) { /*  * No servers. End regardless of pass, because subsequent passes  * only get more restrictive.  */ return null;} 
源文地址:https://www.guoxiongfei.cn/cntech/26842.html