简介
Ribbon是实现基于客户端实现负载均衡的技术,负载均衡简单地说就是:在多个服务器中运行着同一个服务,但是如果不加约束,那客户端根本不知道该去访问哪一台服务器的服务或者长时间都在访问同一台服务器,导致负载过重,而其他服务器却没有任何流量,而负载均衡就是通过一定的策略,让客户端对各个服务器“雨露均沾”,让各个服务器共同承受用户的请求。
Ribbon的使用
前提:能够使用Eureka实现服务的注册。
Ribbon是在客户端实现的负载均衡,所以一切实现操作都是在服务调用方进行的,在服务调用项目中添加Ribbon以及Eureka的依赖如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
要拿到人家的服务,肯定得知道人家在哪,所以注册中心地址肯定是要配的,在yml配置文件中配置:
eureka:
client:
register-with-eureka: false
service-url:
defaultZone: http://eureka7003:7003/eureka/,http://eureka7002:7002/eureka/,http://eureka7001:7001/eureka/
在启动类中加上@EnableEurekaClient
注解
调用服务使用的是RestTemplate,将它在配置类中配置的时候,在对应的配置方法中加上@LoadBalanced
注解
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
采用:http:// + 服务名
服务名是在服务提供方配置的,如下:
spring:
application:
name: springCloud-provider-dept
在Eureka的服务中也可以查看:
示例代码如下:
@RestController
public class DeptController {
@Autowired
RestTemplate restTemplate;
private static final String url="http://SPRINGCLOUD-PROVIDER-DEPT";
@RequestMapping("/getDepts")
public List<dept> getDepts(){
return restTemplate.getForObject(url+"/getDepts",List.class);
}
}
为了区分不同的服务器,需要在所有服务提供者处配置服务id(自定义,提供者之间服务id不相同即可):
eureka:
instance:
instance-id: springcloud-provider-dept8001 #修改Eureka上的默认描述信息
测试
-
先启动Eureka集群,再运行服务提供者项目(两个及以上,为了看到效果,最好将他们的数据也做区分),最后运行消费者。
-
访问消费者项目对应的端口,页面如下:
-
不停地刷新页面,可以看到页面会在不同的服务提供者之间获取数据,即客户端随机调用服务器。
负载均衡算法自定义实现
Ribbon默认的负载均衡算法有很多,常见的有:
- RoundRobinRule:轮询
- RandomRule:随机
- WeightedResponseTimeRule:根据响应时间来分配权重,权重越大,负载越大
- RetryRule:通过轮询的方式获得一个实例,与轮询不同的是,轮询得到一个失效实例后会一直等,等不到就报错了,而此算法则会选择下一个实例
- BestAvailableRule:选择并发度最低的实例
- AvailabilityFilteringRule :会过滤掉一些被标记的实例,因为这些实例可能不可用了,同时还会过滤高并发的实例。
自定义负载均衡算法的步骤:
- 创建一个MyRule,注意不可以与springboot启动类在同一个包下,点开IRule接口,根据它的实现类结合自己的需求来模仿一个算法,比如实现这样一个算法:每个实例访问五次,然后访问下一个实例。可以这样做:复制随机算法的代码,本来index是通过随机数获得的,现在做如下修改:
// int index = this.chooseRandomInt(serverCount);
// server = (Server)upList.get(index);
if(total<5){
total++;
server=upList.get(index);
}
else {
total=0;
index++;
if (index==upList.size()){
index=0;
}
server=upList.get(index);
}
- 将这个类交给spring托管,会自动覆盖掉默认的轮询算法:
@Configuration
public class MyRuleConfiguration {
@Bean
public IRule getRule(){
return new MyRule();
}
}
- 在springboot的启动类中加上如下注解(参数根据实际情况修改):
@RibbonClient(name = "SPRINGCLOUD-PROVIDER-DEPT",configuration = MyRule.class)
- ④运行程序,刷新页面可以看到效果,每刷新五次,页面就会改变数据。