什么是Ribbon,ribbon有什么用,个人先总结一下(不正确请提出讨论):Ribbon是基于客户端的负载均衡器,为我们提供了多样的负载均衡的方案,比如轮询,最小的并发请求的server,随机server等;其默认的策略是ZoneAvoidanceRule,也就是复合判断server所在区域的性能和server的可用性选择server,使用ZoneAvoidancePredicate和AvailabilityPredicate来判断是否选择某个server,前一个判断判定一个zone的运行性能是否可用,剔除不可用的zone(的所有server),AvailabilityPredicate用于过滤掉连接数过多的Server。
在上面两篇博文中我们介绍了Eureka的使用和相关的博文教程。在上一篇博文中(https://blog.csdn.net/asd529735325/article/details/85044158),在我们服务调用方,我们就用到了Ribbon,我们使用Ribbon的RestTemplate,其整合了EurekaClient,Ribbon基于客户端的负载均衡器为我们提供了多样的负载均衡的功能,我们所需要做的就是在Spring中注册一个RestTemplate,并且添加@LoadBalanced
注解。(上一篇我们添加的是LoadBalanced,默认
ZoneAvoidanceRule策略)。
这里我们详细实验一下Ribbon如何实现的负载均衡。
在https://github.com/wades2/EurekaDemo2这个代码的基础上我们添加了一个Client端,也是作为server实例的。
为了区分是最终究竟访问的哪个EurekaClient,我们的Cotroller返回的和第一个有差异(但是实际开发中不可以!我们这里只是为了实验!!强调!!)。
我们按照之前注册到服务端一样把新的Client注册到Eurekaserver,以下是我个人的配置文件:
spring.application.name=Eureka-client
#eureka.client.allow-redirects=false
#修改启动端口
server.port=8085
eureka.client.serviceUrl.defaultZone=http://user:123456@localhost:8083/eureka,http://user:123456@localhost:8082/eureka
#eureka.client.register-with-eureka=true
eureka.instance.ip-address=true
注意:spring.application.name必须和EurekaClient的一致,因为restTemplate是通过spring.application.name+请求接口地址来实现请求的类似于httpClient的框架(可以理解成域名或IP+端口号就能实现请求,只是在Ribbon中换了个形式而已)。
package com.example.demo.controller;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("user")
public class UserController {
@Autowired
private EurekaClient eurekaClients;
// @Autowired
// private DiscoveryClient discoveryClient;
@GetMapping("getUser")
public String getUser() {
//todo 得到eureka server的服务实例
// InstanceInfo info=eurekaClients.getNextServerFromEureka("Eureka-client",false);
// return info.getHomePageUrl();
return "hello client2";
}
}
Controller除了返回的信息不一样,其他都一样。
然后启动访问http://localhost:8086/getUser/routine,我们可以看到,请求同样的url,返回的一次是hello client2,一次是hello one,我们可以知道,客户端的负载均衡已经完成了。
接下来我们来说说如何根据自己的需求配置负载均衡策略,我们刚在前文提到Ribbon默认的策略是ZoneAvoidanceRule,我们通过实验来试试其他策略:
在Eurakacaller中Controller下new一新的Class作为config,来配置我们的策略。
然后重构下Controller(因为之前是把Config直接写在Controller里面的):
package com.example.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
//@Configuration
public class Controller {
// @Bean
// @LoadBalanced
// public RestTemplate getRestTemplate() {
// return new RestTemplate();
// }
//
// @GetMapping("getUser/routine")
// public String routine() {
// RestTemplate restTemplate = getRestTemplate();
//
// String json = restTemplate.getForObject("http://Eureka-client/user/getUser", String.class);
// return json;
// }
@Autowired
private RestTemplate restTemplate;
@GetMapping("getUser/routine")
public String routine() {
// RestTemplate restTemplate = configBean.getRestTemplate();
String json = restTemplate.getForObject("http://Eureka-client/user/getUser", String.class);
return json;
}
// @GetMapping("getUser/routine2")
// public String routine2() {
// RestTemplate restTemplate = getRestTemplate();
// String json = restTemplate.getForObject("http://Eureka-client/user/getUser2", String.class);
// return json;
// }
}
然后配置下我们的Ribbon策略:
package com.example.demo.controller;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
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;
@Configuration
public class ConfigBean {
@Bean
@LoadBalanced // ribbon负载均衡
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@Bean
public IRule muRule() {
return new RoundRobinRule();//轮询
// return new RandomRule();// 随机
}
}
选择轮询还是随机看你,如果注销了muRule,则变为默认策略。
OK,有关Ribbon的配置就结束了,欢迎大家一起讨论评论。
这里推荐一个对Ribbon有深入研究大佬的博客地址,看了后会明白很多,Ribbon是如何通过restTemplate来发送http请求调用的:https://blog.csdn.net/puhaiyang/article/details/79682177