![0547d6eb6d5f0a43f4ba188369e82a73.png](https://i-blog.csdnimg.cn/blog_migrate/cbb21d4522d2a257d4e60b2712944b91.jpeg)
负载均衡
- 概述
Ribbon实现客户端的负载均衡,负载均衡器提供很多对http和tcp的行为控制。Spring cloud Feign已经集成Ribbon,所以注解@FeignClient的类,默认实现了ribbon的功能。
- 主要包含如下组件:
- IRule:根据特定算法中从服务列表中选取一个要访问的服务
- IPing:在后台运行的一个组件,用于检查服务列表是否都活
- ServerList:存储服务列表。分为静态和动态。如果是动态的,后台有个线程会定时刷新和过滤服务列表;
- ServerListFilter:DynamicServerListLoadBalancer用于过滤从ServerList实现返回的服务器的组件
- ServerListUpdater:被DynamicServerListLoadBalancer用于动态的更新服务列表
- IClientConfig:定义各种配置信息,用来初始化ribbon客户端和负载均衡器
- ILoadBalancer:定义软件负载平衡器操作的接口。动态更新一组服务列表及根据指定算法从现有服务器列表中选择一个服务
- 作用
- 服务器发现
- 选择服务器操作
- 获取所有的服务器列表------不再硬编码服务的地址
- 服务监听
Ribbon是一个为客户端提供负载均衡功能的服务,它内部提供了一个叫做ILoadBalance的接口代表负载均衡器的操作,我们可以在配置文件中Load Balancer后面的所有机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。
![91c521ec4cc6f5fe3bac79be65118cf6.png](https://i-blog.csdnimg.cn/blog_migrate/48fe2b9712090e2ed76522cc867780d0.jpeg)
- 使用步骤
- 引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
//--------------springcloud-H版引入eureka-client自带ribbon--------------------------//
<!--eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
![8037eab170de7e3a4cc0de73d9453c70.png](https://i-blog.csdnimg.cn/blog_migrate/8f57e232ce2fc8e4e57b4b32ed119ff7.jpeg)
- 添加配置
//配置类不能放在@ComponetScan包及其子包下
@Configuration
public class MySelfRule {
@Bean
public IRule myRule() {
return new RandomRule(); // 定义为随机
}
}
- 主程序添加@RibbonClient
@SpringBootApplication
@EnableEurekaClient
//在启动该微服务的时候就能去加载我们的自定义Ribbon配置类,从而使配置生效
@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
//name为要访问的服务名称
//configuration为轮询策略
public class DeptConsumer80_App{
public static void main(String[] args){
springapplication.run(DeptConsumer80_App.class, args);
}
}
- 自定义负载均衡
- 实现LoadBalancer
@Component
public class MyLB implements LoadBalancer{
private AtomicInteger atomicInteger = new AtomicInteger(0);
public final int getAndIncrement() {
int current;
int next;
do {
current = this.atomicInteger.get();
next = current >= 2147483647 ? 0 : current + 1;
} while(!this.atomicInteger.compareAndSet(current,next));
System.out.println("****第几次访问,次数next: " + next);
return next;
}
// 负载均衡轮询算法,rest接口第几次请求数 % 服务器集群总数 = 实际调用服务器位置下标
@Override
public ServiceInstance instances(List< ServiceInstance > serviceInstances) {
int index = getAndIncrement() % serviceInstances.size();
return serviceInstances.get(index);
}
}
- 使用
@GetMapping("/consumer/payment/lb")
public String getPaymentLB() {
// 通过容器中的 discoveryClient和服务名来获取服务集群
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
if(instances == null || instances.size() <= 0) {
return null;
}
// 传入服务集群来计算出获取具体的服务实例
ServiceInstance serviceInstance = loadBalancer.instances(instances);
URI uri = serviceInstance.getUri();
return restTemplate.getForObject(uri+"/payment/lb",String.class);
}
Rule-----自带7种
RoundRobinRule
轮询规则,默认规则。同时也是更高级rules的回退策略
AvailabilityFilteringRule
这个负载均衡器规则,会先过滤掉以下服务:
- a. 由于多次访问故障而处于断路器跳闸状态
- b. 并发的连接数量超过阈值
然后对剩余的服务列表按照RoundRobinRule策略进行访问
WeightedResponseTimeRule
根据平均响应时间计算所有服务的权重,响应时间越快,服务权重越重、被选中的概率越高。刚启动时,如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,会切换到WeightedResponseTimeRule。
RetryRule
先按照RoundRobinRule的策略获取服务,如果获取服务失败,则在指定时间内会进行重试,获取可用的服务
BestAvailableRule
此负载均衡器会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
RandomRule
随机获取一个服务
IPing
NIWSDiscoveryPing
不执行真正的ping。如果Discovery Client认为是在线,则程序认为本次心跳成功,服务活着
PingUrl
此组件会使用HttpClient调用服务的一个URL,如果调用成功,则认为本次心跳成功,表示此服务活着。
NoOpPing
永远返回true,即认为服务永远活着
DummyPing
默认实现,默认返回true,即认为服务永远活着
ServerList
功能:存储服务列表。分为静态和动态。如果是动态的,后台有个线程会定时刷新和过滤服务列表
常用ServerList 实现有以下几种:
ConfigurationBasedServerList
从配置文件中获取所有服务列表
DiscoveryEnabledNIWSServerList
从Eureka Client中获取服务列表。此值必须通过属性中的VipAddress来标识服务器集群。DynamicServerListLoadBalancer会调用此对象动态获取服务列表
DomainExtractingServerList
代理类,根据ServerList的值实现具体的逻辑
ServerListFilter
ZoneAffinityServerListFilter
过滤掉所有的不和客户端在相同zone的服务,如果和客户端相同的zone不存在,才不过滤不同zone有服务。
启用此配置使用以下配置
<clientName>.ribbon.EnableZoneAffinity=true
ZonePreferenceServerListFilter
ZoneAffinityServerListFilter的子类。和ZoneAffinityServerListFilter相似,但是比较的zone是发布环境里面的zone。过滤掉所有和客户端环境里的配置的zone的不同的服务,如果和客户端相同的zone不存在,才不进行过滤。
ServerListSubsetFilter
ZoneAffinityServerListFilter的子类。此过滤器确保客户端仅看到由ServerList实现返回的整个服务器的固定子集。 它还可以定期用新服务器替代可用性差的子集中的服务器。
要启用此过滤器,请指定以下属性:
<clientName>.ribbon.NIWSServerListClassName=com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList
# the server must register itself with Eureka server with VipAddress "myservice"
<clientName>.ribbon.DeploymentContextBasedVipAddresses=myservice
<clientName>.ribbon.NIWSServerListFilterClassName=com.netflix.loadbalancer.ServerListSubsetFilter
# only show client 5 servers. default is 20.
<clientName>.ribbon.ServerListSubsetFilter.size=5