SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算方法,将Netflix的中间服务连接在一起。Ribbon客户端主键提供一系列完善的配置项如何连接超时,重试等,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
一、Ribbon的配置
1.修改pom文件
org.springframeword.cloud
spring-cloud-starter-eureka
org.springframeword.cloud
spring-cloud-starter-ribbon
org.springframeword.cloud
spring-cloud-starter-config
2.修改配置文件
eureka:
client: #客户端注册Eureka服务列表内
register-with-eureka:false
service-url:
defaultZone:http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3.修改bean的注入配置
@Bean
@LoadBalanced //负载均衡
public RestTemplate getRestTemplate(){
return new RestTemplate;
}
4.修改主启动类
@SpringBootApplication
@EnableEurekaClient //本服务启动后悔自动注册进Eureka服务中
public class DeptConsumer80_App{
SpringApplication.run(DeptConsumer80_App.class,args);
}
5.修改微服务端口
//private static final String REST_URL_PREFIX="http://localhost:8001"
//修改成
private static final String REST_URL_PREFIX="http://MICROSERCICECLOUD-DEPT"
Ribbon和Eureka整合后Consumer可以直接调用服务而不再关心地址和端口号
二、Ribbon实现负载均衡
Ribbon在工作时分成两步
第一步先选择EurekaService它优先选择在同一个区域内负载较少的server
第二步根据用户指定的策略,在从Server取到服务器注册列表中选择一个地址
同一个服务在多实例的时候对外暴露的服务名称要相同
Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他的所需请求的客户端结合使用,和eureka结合只是其中一个实例。
三、Ribbon核心组件IRule
RoundRobinRule:轮询
RandomRule:随机
AvailabilityFilteringRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务器,还有并发的连接数超过阈值的服务,然后对剩余的服务器列表按照轮询策略进行访问
WeightedResponseTimeRule:根据平均响应时间计算所有服务器的权重,响应时间越快服务权重越大被选中的概率越高。刚启动时如果统计信息不足,则使用RoundRobinRule策略,等统计信息足够,会切换回来
RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务
BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务器,然后选择一个并发量最小的服务器
ZoneAvoidanceRule:默认规则,复合判断Server所在区域的性能和server的可用性选择服务器
使用IRule切换负载均衡策略
添加Bean
@Bean
public IRule myRule(){
return new RoundRobinRule(); //new 的对象就是选择的负载均衡策略
}
四、Ribbon自定义策略
1.修改主启动类,添加注解
@SpringBootApplication
@EnableEurekaClient //本服务启动后悔自动注册进Eureka服务中
//在启动该微服务的时候就能去加载我们自定义的Ribbon配置类,从而使配置生效
//解释:针对MICROSERVICECLOUD-DEPT这个服务,使用configuration=MySelfRule.class的负载均衡策略
@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MySelfRule.class)
public class DeptConsumer80_App{
SpringApplication.run(DeptConsumer80_App.class,args);
}
2.编写自定义负载均衡策略
注:这个自定义配置类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,也就是说我们达不到特殊定制化的目的了
2.1新建一个包com.xxxx.myrule,创建类MySelfRule
@Configuration
public class MyselfRule(){
@Bean
public IRule myRule(){
return new RandomRule_ZY();
}
}
RandomRule_ZY类
public class RandomRule_ZY extends AbstractLoadBalancerRule(){
Random rand;
public RandomRule_ZY(){
rand = new Random();
}
public Server choose(ILoadBalancer lb ,Object key){
if(lb == null){
return null;
}
Server server = null;
while(server == null){
if(Thread.interrupted()){
return null;
}
List upList = lb.getReachableServers();
List allList = lb.getAllServers();
int serverCount = allList.size();
if(serverCount == 0){
return null;
}
int index = rand.nextInt(serverCount);
server = upList.get(index);
if(server == null){
Thread.yield();
continue;
}
if(server.isAlive()){
return (server);
}
server = null;
Thread.yield();
}
return server;
}
@Override
public Server Choose(Object key){
return choose(getLoadBalancer(),key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig){
}
}
五、Feign
Feign是一个声明式WebServer客户端。使用Feign能让编写WebService客户端更加简单,他的使用方法是定义一个接口,然后在上面加上注解,同时也支持JAX-RS标准的注解。Feign也支持可拔插式的编码器和解码器。SpringCloud对Feign进行了封装,使其支持了SpringMVC标准注解,和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。
Feign可以实现通过接口+注解,获得调用服务,可以依旧使用面向接口的编程方式
1.建立新的工程,修改pom文件
org.springframeword.cloud
spring-cloud-starter-feign
2.创建接口
@FeignClient(value = "MICROSERVICECLOUD-DEPT")
public interface DeptClientService{
@RequestMapping(value = "/dept/get/{id}",method = RequsetMethod.GET)
public Dept get(@PathVariable("id")long id);
@RequestMapping(value = "/dept/list",method = RequsetMethod.GET)
public List list();
@RequestMapping(value = "/dept/add",method = RequsetMethod.POST)
public boolean add(Dept dept);
}
3.创建Controller
@RestController
public interface DeptController_Consumer{
@Autowired
private DeptClientService service;
@RequestMapping(value = "/dept/get/{id}")
public Dept get(@PathVariable("id")long id){
return service.get(id);
}
@RequestMapping(value = "/dept/list")
public List list(){
return service.list();
}
@RequestMapping(value = "/dept/add")
public boolean add(Dept dept){
return service.add(dept);
}
}
4.修改主启动类
@SpringBootApplication
@EnableEurekaClient
//注明扫描范围
@EnableFeignClients(basePackages = {com.xxx.springcloud})
@ComponentScan("com.xxx.springcloud")
public class DeptConsumer80_App{
SpringApplication.run(DeptConsumer80_App.class,args);
}
Feign集成了Ribbon
利用Ribbon维护了MicroServiceCloud-Dept的服务列表信息,并通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用