Ribbon实现客户端负载均衡
什么是Ribbon?
客户端负载均衡组件。
前期准备:
搭建一个Eureka集群和一个注册服务
https://www.cnblogs.com/noneplus/p/11374883.html
- 创建服务提供者msc-provider-5002,msc-provider-5003
- 创建消费者msc-consumer-80
pom依赖
服务提供者msc-provider-5001,msc-provider-5002,msc-provider-5003:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- Eureka客户端启动需要依赖web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
消费者msc-consumer-80:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!-- Eureka客户端启动需要依赖web模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
服务提供者5001配置
- 主启动类:(提供者并不需要进行注解配置)
- TestController(测试负载均衡)
package zkrun.top.controller;
import org.springframework.web.bind.annotation.*;
@RestController
public class TestController {
@GetMapping(value = "/info/get")
public String response()
{
return "msc_provider_5001";
}
}
- application.yaml(基本无修改,对比Eureka配置)
server:
port: 5001
spring:
application:
name: msc-provider #应用名称
eureka:
client:
service-url:
defaultZone: http://eureka6001.com:6001/eureka/,http://eureka6002.com:6002/eureka/,http://eureka6003.com:6003/eureka/
instance:
instance-id: msc-provider-5001
prefer-ip-address: true #访问路径可以显示IP地址
复制5001的代码到5002和5003
- 主启动类(修改类名)
- TestController(修改返回值)
- application.yaml(修改端口和instance-id)
大致的效果就是访问不同的端口,有不同的返回值:
消费者msc-consumer-80配置
- RibbonConfig
package zkrun.top.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RibbonConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate()
{
return new RestTemplate();
}
}
- Controller_Consumer
package zkrun.top.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class Controller_Consumer {
private static final String REST_URL_PREFIX = "http://MSC-PROVIDER";
@Autowired
private RestTemplate restTemplate;
@RequestMapping(value = "/consumer/info/get")
public String request()
{
return restTemplate.getForObject(REST_URL_PREFIX + "/info/get", String.class);
}
}
- yaml
server:
port: 80
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka6001.com:6001/eureka/,http://eureka6002.com:6002/eureka/,http://eureka6003.com:6003/eureka/
- 主类(@RibbonClient(name="MSC_PROVIDER"))
package zkrun.top;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name="MSC_PROVIDER")
public class App_msc_consumer_80
{
public static void main(String[] args)
{
SpringApplication.run(App_msc_consumer_80.class, args);
}
}
运行测试:
启动Eureka6001,6002,6003
启动Provider5001,5002,5003
启动Consumer80
访问:
http://localhost/consumer/info/get
点击刷新就会有轮询效果:
负载均衡算法切换
在RibbonConfig下添加
@Bean
public IRule myRule()
{
return new RandomRule();// Ribbon默认是轮询,自定义为随机
//return new RoundRobinRule();// Ribbon默认是轮询
}
支持的算法:
代码参考:https://github.com/Noneplus/JavaDev-Note/tree/master/SpringCloud代码