SpringCloud Netflix Ribbon客户端负载均衡
官方介绍:
https://www.springcloud.cc/spring-cloud-netflix.html

Ribbon是一个客户端负载平衡器,它可以很好地控制HTTP和TCP客户端的行为。
IDEA创建项目集成SpringCloud Ribbon
1 . pom.xml导入依赖
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--ribbon-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<!--重试机制-->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
- application.yml配置文件
server:
port: 8081
#指定注册中心服务提供者名称
spring:
application:
name: client-ribbon
eureka:
client:
# 禁用Eureka Client
enabled: false
#定义一个serverlist给我们使用负载均衡
#格式 {serviceId}:ribbon:listOfServers
# serviceId随意写
# 需要负载 的ip和端口,多个
hello-server:
ribbon:
listOfServers: localhost:8082,localhost:8083
- main入口方法
@SpringBootApplication
//配置文件 serviceId 负载均衡
@RibbonClients(@RibbonClient(value = "hello-server"))
public class LearnRibbonApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(LearnRibbonApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(LearnRibbonApplication.class);
}
}
定义config配置
@Configuration
public class Config {
// @LoadBalanced 负载均衡
@Bean
@LoadBalanced
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public IRule ribbonRule(){
//自定义规则 随机获取服务id
return new RandomRule();
}
@Bean
public IPing ribbonIping(){
//自定义ip规则,设置服务是否alive
return new PingConstant();
}
}
restTemplate远程调用
@RestController
public class CustomerController {
@Autowired
private RestTemplate restTemplate;
//在使用LoadBalancerClient 要把 @LoadBalanced 去掉
@Autowired
LoadBalancerClient loadBalancerClient;
@GetMapping("/getdata")
public Object getIndex(){///springcloud-eureka-client-two
ServiceInstance serviceInstance = loadBalancerClient.choose("hello-server");
String ip = serviceInstance.getHost();
int port = serviceInstance.getPort();
System.out.println("ip="+ip+",port="+port);
//返回值类型String
return restTemplate.getForObject("http://"+ip+":"+port+"/client2",String.class,"");
}
}
Ribbon是怎么实现装配的?
在Ribbon的jar包下有一个spring.factories的文件,有个自动配置类org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration

在RibbonAutoConfiguration配置类有SpringClientFactory,LoadBalancerClient和LoadBalancedRetryFactory重要的bean。
SpringClientFactory类的树:


NamedContextFactory类下创建父子容器:

ILoadBalancer接口:定义Server列表,选择Server
RibbonClientConfiguration配置类,配置IRule,Iping,ILoadBalancer,ServerListFilter,RibbonLoadBalancerContext的规则:


LoadBalancerClient:获取Server


//在使用LoadBalancerClient 要把 @LoadBalanced 去掉
@Autowired
LoadBalancerClient loadBalancerClient;
ServiceInstance serviceInstance = loadBalancerClient.choose("hello-server");
Server的获取流程就是上面的方式
IRule定义负载均衡策略
当有请求发出的时候,拦截请求,按照策略,通过策略指定的server转发出去。

拦截请求,AbstractClientHttpRequest.execute(),

拦截到请求,重新创建包装请求:


类名 | 含义 |
---|---|
BestAvailableRule | 最小调用数策略 |
ZoneAvoidanceRule | 区域规避策略(默认策略),没有后执行RoundRobinRule |
AbstractLoadBalancerRule | 抽象策略,策略的模板 |
RoundRobinRule | 轮询策略 |
RandomRule | 随机数策略 |
WeightedResponseTimeRule | 权重策略 |
AvailabilityFilteringRule | 线性抽样策略 |
自定义IRule规则
@Bean
public IRule ribbonRule(){
//自定义规则 随机服务id
return new RandomRule();
}
Iping容错机制
相当于心跳,每隔一段时间判断服务实例是否正常;
默认的Iping规则是new DummyPing();

自定义Iping规则
@Bean
public IPing ribbonIping(){
//自定义ip规则
return new PingConstant();
}
网友评论