一、什么是Ribbon
springcloud Ribbon 是基于Netflix Ribbon实现的一套客户端负载均衡的工具,主要功能是提供客户端的软件负载均衡算法。springcloud 的负载均衡(Load Balace 简称LB)算法可以自定义。这就类似于我们平时逛超市结账一样,消费者(客户端)肯定会去选择排队人数最少的结账队列去结账,而这就被称为客户端的负载均衡。
负载均衡大致可分为两大类:集中式负载均衡、进程内负载均衡。而本文中的Ribbon就属于进程内的LB。
Ribbon与Eurea整合后,客户端能够直接通过微服务名称调用服务,而不用在关心地址和端口。
二、Ribbon默认的七种负载均衡算法
- RoundRobinRule:简单轮询负载均衡,采用的是计数器count,i++的方式,循环访问下一个server。
- RandomRule:随机负载均衡,随机选择一个server。
- RetryRule:重试功能负载均衡。
- AvailabilityFilteringRule:过滤失败连接式负载均衡。
- WeightedResponeTimeRule:加权响应时间式负载均衡,每次访问后给出权值,响应时间越短,权值越大,反之越小。
- BestAvailableRule:选择一个最小的并发负载均衡。
- ZoneAvoidanceRule:区域感知轮询负载均衡。
三、springcloud中eureka与ribbon的整合
1、在客户端(消费者)微服务的pom文件中引入依赖
<!-- Ribbon相关 -->
<dependency>
<groupId>org.springframework.cloud</groupId><!-- 表示是eureka的客户端,或者叫提供端 -->
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
2、修改application.yml,追加eureka的服务注册地址
server:
port: 80
#providerUrl: 'http://localhost:8001'
providerUrl: 'http://microservicecloud-dept' #可以根据微服务名称访问微服务,不再需要ip地址和端口号,提高安全性
#与eureka服务端配置的地址一致,表示将要入驻到的地址,可以配置多个
eureka:
client:
register-with-eureka: false #并不将自己注册到微服务注册中心
service-url:
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
3、在java配置类中,将RestTemplate上加注解:@LoadBalanced,表示开启自动负载均衡规则。
package com.atguigu.springcloud.cfgbeans;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import com.netflix.loadbalancer.RetryRule;
import com.netflix.loadbalancer.RoundRobinRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* Created with IntelliJ IDEA.
* Description:
* User:
* Date: 2019-04-08
* Time: 21:34
*/
@Configuration
public class ConfigBean {
@Bean
@LoadBalanced //开启自动负载均衡,即可以通过微服务名称进行调用微服务,不需要使用ip+端口号进行调用了。
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
/**
* springcloud的Riboon已经配置了七种负载均衡的算法,它们之间可以相互切换。
* 这七种负载均衡算法都是 IRule 接口的实现类
* @return
*/
@Bean
public IRule getIRule() {
return new RoundRobinRule();//简单轮询负载均衡,若没有配置该Bean,则Ribbon默认采取该种方式的负载均衡
// return new RandomRule();//随机负载均衡
// return new RetryRule();//重试轮询负载均衡
}
}
springcloud有其中默认的负载均衡算法,它们之间可以相互切换。如上代码所示,只需要在Java Bean配置类中注入接口 IRule的实现类即可。
当需要某种负载均衡时,就 return new 某一个就行了。若没有配置该bean,则默认采用RoundRobinRule()轮询负载均衡的方式。这七个已配置好的负载均衡算法都是 IRule 接口的实现类。
4.自定义Ribbon的负载均衡策略
需要在主启动类上添加 @EnableEurekaClient 以及 @RibbonClien。
package com.atguigu.springcloud;
import com.atguigu.mySeltRibbonRule.MySelfRule;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
/**
* Created with IntelliJ IDEA.
* Description:
* User:
* Date: 2019-04-08
* Time: 22:18
*/
@SpringBootApplication
@EnableEurekaClient
//在消费端(客户端)的启动类上添加@RibbonClient注解,即可在启动的时候去加载自定义的Ribbon配置类,从而使配置生效
//name--表示针对于某一个微服务,填的是微服务的名称
//configuration--表示的自定义的配置文件
@RibbonClient(name = "microservicecloud-dept",configuration = MySelfRule.class)
public class DeptConsumer_80 {
public static void main(String[] args) {
SpringApplication.run(DeptConsumer_80.class,args);
}
}
需要注意的配置细节--官方文档明确提出的警告:
这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及其子包下。否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的效果和目的了。
即:这个配置类不能放在含有主启动类的包下,因为@SpringBootApplication是一个复合型注解,包含了@ComponentScan注解。
此时应该新建一个包,与主启动类所在包同级的一个包。
MySelfRule类:
package com.atguigu.mySeltRibbonRule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Author:
* @Despriction: 自定义Ribbon负载均衡配置类
* @Package: com.atguigu.mySeltRibbonRule
* @Date:Created in 2019/4/28 15:38
* @Modify By:
*/
@Configuration
public class MySelfRule {
@Bean
public IRule getIRule() {
// return new RoundRobinRule();//简单轮询负载均衡,若没有配置该Bean,则Ribbon默认采取该种方式的负载均衡
return new RandomRule();//随机负载均衡
// return new RetryRule();//重试轮询负载均衡
}
}
注:若需要返回一个我们自定义的负载均衡算法,即 return new MySelfRibbonRule();
- 在MySelfRule类同一个包下新建一个MySelfRibbonRule类。
- MySelfRibbonRule 继承 AbstractLoadBalancerRule 抽象类,因为该类实现了 IRule 接口。
- 将随机轮询类 RandomRule里的方法复制进来,根据自己的逻辑需求在方法——
public Server choose(ILoadBalancer lb,Object key) {.......}进行修改。