SpringCloud Ribbon负载均衡
# Ribbon 负载均衡
Spring Cloud Ribbon 是一个基于 Http、TCP 的客服端负载均衡工具,它是基于 Netflix Ribbon 实现的。主要解决高量访问均匀的分布到每个节点
# 负载均衡示例
提供者需要形成集群,负载均衡的功能集成到消费方,进行请求均衡分配
提供者
提供者 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>springcloud-father</artifactId>
<groupId>com.sans</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>user-service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 通用Mapper启动器 -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
提供者 application.yml
server :
port : ${prot:9000}
spring :
application:
name : user-service
eureka :
client :
service-url :
# 注册的服务端地址
defaultZone : HTTP://127.0.0.1:10086/eureka
# ··· 其他
提供者项目 大致流程 (opens new window) (==controller、mapper、pojo、service、启动类 组件==
- 配置需要改 端口号 , 提供者 和 调用者 端口以防冲突
- controller提供的接口: http://localhost:8080/user/2 (按ID查用户)
user-service 形成集群
启动配置组件 配置参数 prot
分别为:9000、9001、9002
虚拟机选项参数:-Dprot=9000
(重复创建3个user-service不同端口
消费者
消费者 pom.xml
<!--调用者只需一个web依赖-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
消费者 application.yml
spring :
application :
name : consumer-demo
eureka :
client :
service-url :
defaultZone : http://127.0.0.1:10086/eureka
消费者项目 启动器类 ,在RestTemplate方法上添加 @LoadBalanced
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
// Ribbon 启动负载均衡
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
Eureka中已经集成了Ribbon,因此无需引入新依赖
消费者 contoller
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("{id}")
public User findById(@PathVariable Long id) {
// 方式1 : 绝对路径
// String url = "HTTP://localhost:9091/user/"+id;
// 方式2 : 通过 discoveryClient对象 获取 ip、port
// List<ServiceInstance> list = discoveryClient.getInstances("user-service");
// ServiceInstance instance = list.get(0);
// String url = "HTTP://"+instance.getHost()+":"+instance.getPort()+"/user/"+id;
// 方式3 : 通过 Ribbon 拦截替换获取 (service名称 会自动替换为 ip、port
String url = "HTTP://user-service/user/"+id;
return restTemplate.getForObject(url , User.class);
}
}
Ribbon会拦截请求进行识别服务名称进行分析 ip、port ,自动替换 ip、port
测试
访问 http://localhost:8080/consumer/1 (查看服务节点,根据端口判断节点
跟踪
LoadBalancerInterceptor
类 拦截器跟踪
execute()
方法跟踪 断点
控制器检查断点变量
每次访问 ,节点都是不一样的!!!
# Ribbon 负载均衡策略
Ribbon 负载均衡策略方式是通过内置集成的算法获取到预期的节点,默认是 轮询策略
。
以下列出更多有关负载均衡的策略:
策略类 | 策略名 | 说明 |
---|---|---|
RandomRule | 随机策略 | 随机选择server |
RoundRobinRule | 轮询策略 | server集合,遍历server集合,并有序的选中 servcer |
RetryRule | 失败重试策略 | 首先以 轮询策略 执行,当某个server失败,重试下一个server,则以此类推,直至遍历完server,如果都不成功,直接返回失败 |
BestAvailableRule | 最低并发策略 | 选择 负载压力最小的 server |
AvailabilityFilteringRule | 可用过滤策略 | 选择 无连接失败、无高并发 且健康的server |
ZoneAvoidanceRule | 区域权重策略 | 选择 指定区域 、可用 的server (自定义 |
# 策略应用示例
在以上的基础上进行修改
消费者 application.yml
添加 负载均衡策略
user-service:
ribbon:
NFLoadBalancerRuleClassName : com.netflix.loadbalancer.RandomRule
配置的格式说明:
{服务器名称}.ribbon.NFLoadBalancerRuleClassName : com.netflix.loadbalancer.{策略类}
测试
@RunWith (SpringRunner.class)
@SpringBootTest(classes = ConsumerApplication.class)
public class ConsumerControllerTest {
@Autowired
RibbonLoadBalancerClient client;
@Test
public void test() {
for (int i = 0 ; i < 100 ; i++) {
ServiceInstance instance = this.client.choose("user-service");
System.out.println(instance.getHost() +" : "+ instance.getPort());
}
}
}
/*
观察不同端口的访问 顺序 进行辨别
*/
自行添加测试依赖
仓库代码 : https://gitee.com/Bozhu12/spring-cloud-examples.git (opens new window)