SpringCloud Netflix(四) : Ribbon负载均衡
简介
Ribbon是一个客户端IPC库,在云中进行了测试。它提供了以下特性
负载均衡
容错性
异步反应模型中的多协议(HTTP、TCP、UDP)支持
缓存和批量处理
基础使用
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> <version>2.2.2.RELEASE</version> </dependency>
@Bean @LoadBalanced //默认采用的是RoundRobinRule,轮询策略 public RestTemplate restTemplate(){ return new RestTemplate(); }
自定义负载均衡策略
通过查看Riddon的源码可以看出,Riddon的负载均衡策略类都继承了AbstractLoadBalancerRule
package com.netflix.loadbalancer; import com.netflix.client.IClientConfigAware; public abstract class AbstractLoadBalancerRule implements IRule, IClientConfigAware { private ILoadBalancer lb; public AbstractLoadBalancerRule() { } public void setLoadBalancer(ILoadBalancer lb) { this.lb = lb; } public ILoadBalancer getLoadBalancer() { return this.lb; } }
package com.netflix.loadbalancer; public interface IRule { Server choose(Object var1); void setLoadBalancer(ILoadBalancer var1); ILoadBalancer getLoadBalancer(); }
自定义负载均衡策略实现
配置类不能放在@SpringBootApplication应用
同级目类下,否则它由所有@RibbonClients
共享,就达不到特殊化指定的目的了
CustomConfiguration
类必须是@Configuration
类,但请注意,对于主应用程序上下文,它不在@ComponentScan
中。否则,它由所有@RibbonClients
共享。如果您使用@ComponentScan
(或@SpringBootApplication
),则需要采取措施避免将其包括在内(例如,可以将其放在单独的,不重叠的程序包中,或指定要在@ComponentScan
)。
-
创建负载均衡策略的配置类
@Configuration public class MyRuleConfig { @Bean public IRule ribbonRule(){ return new MyRule(); } }
public class MyRule extends AbstractLoadBalancerRule { private static Logger log = LoggerFactory.getLogger(MyRule.class); private int total = 0; private int index = 0; @Override public void initWithNiwsConfig(IClientConfig iClientConfig) { } @Override public Server choose(Object o) { return this.choose(this.getLoadBalancer(),o); } public Server choose(ILoadBalancer lb, Object key) { if (lb == null) { return null; } else { 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) { return null; } //自定义负载均衡方法,每个服务执行3次,依次轮询 if (total<3){ server = (Server) upList.get(index);//根据索引从可获得的服务中获取服务 total++; }else { total=0; if (index>=upList.size()-1){ index=0; }else { index++; } } if (server == null) { Thread.yield(); } else { if (server.isAlive()) { return server; } server = null; Thread.yield(); } } return server; } } }
@Configuration //name为服务提供者配置的spring.application.name,configuration为自定义负载均衡的配置类 @RibbonClient(name = "SPRINGCLOUD-PROVIDER", configuration = MyRuleConfig.class) public class BeanConfig { @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }