SpringCloud-学习之-Ribbon负载均衡

什么是Ribbon

Ribbon是Netflix发布的负载均衡器,它有助于控制HTTP和TCP的客户端的行为。为Ribbon配置服务提供者地址后,Ribbon就可基于某种负载均衡算法,自动地帮助服务消费者去请求。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。当然,我们也可为Ribbon实现自定义的负载均衡算法。在Spring Cloud中,当Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。

先来试试简单的RestTemplate

工程就是一个Eureka Server,两个Eureka Client,client1调用client2的接口

先在client1里面:

1
2
3
4
5
6
7
8
9
@GetMapping("/msg")
public String getMsg(){
return "this is provide msg";
}

@PostMapping("/param")
public String getMsgAndParam(String param){
return "this is provide msg,param is " + param;
}

很随便的两个接口~

接着在client2里面使用restTemplate去调用这两个接口返回给客户端

当然,客户端先配置一下简单的restTemplate(new 一个也行,不过为了后面复杂点的restTemplate我就先做了这个)

1
2
3
4
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}

下面来调用看看~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Autowired
RestTemplate restTemplatel;


@GetMapping("/msg")
public String getMsg(){
return restTemplatel.getForEntity("http://127.0.0.1:8080/msg",String.class).getBody();
}

@PostMapping("/param")
public String getMsgAndParam(String param){
MultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
params.add("param",param);
return restTemplatel.postForEntity("http://127.0.0.1:8080/param",params,String.class).getBody();
}

这里稍微注意一下,使用postForEntity参数的话,不能用HashMap,要用MultiValueMap,不然client1接收不到参数

关于restTemplate的使用,可以看看萌萌哒群主写的博客MrBird

这么写有么有发现url写死了!这怎么行!得改一改~

加了注解的RestTemplate

在刚刚的基础上,小小的修改下代码~

首先是restTemplate的配置类

1
2
3
4
5
@LoadBalanced
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}

对的就加了个@LoadBalanced注解

然后就是client2的controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Autowired
RestTemplate restTemplatel;

@GetMapping("/msg")
public String getMsg(){
return restTemplatel.getForEntity("http://provide/msg",String.class).getBody();
}

@PostMapping("/param")
public String getMsgAndParam(String param){
MultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
params.add("param",param);
return restTemplatel.postForEntity("http://provide/param",params,String.class).getBody();
}

因为加了@LoadBalanced注解,所以使用名字就能找到服务了,这样的话服务提供者想部署到哪都行啦,只要他注册到Eureka,并且名字不变就行了~是不是比上面写死IP好多了。

Ribbon负载均衡策略

上面说了那么多好像都跟Ribbon没啥关系- -,现在就看看Ribbon是怎么实现负载均衡了。

按照百度说了,我找到了他的源码,有个叫BaseLoadBalancer的类,里面声明了一个变量

private static final IRule DEFAULT_RULE = new RoundRobinRule();

嗯,没错!这个就是他的负载均衡策略,看类名就知道了嘛,轮流来~测试了下,果然是轮流来😎

怎么测的?开两个服务然后一个返回1一个返回2不就好了~

最后修改一下他的负载均衡策略

1
2
3
PROVIDE:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

改成随机的,在试试~