SpringCloud中的Ribbon负载均衡详细解读
作者:爱敲代码的小楚
负载均衡
当系统面临大量的用户访问,负载过高的时候,通常会增加服务器数量来进行横向扩展(集群),多个服务器的负载需要均衡,以免出现服务器负载不均衡,部分服务器负载较大,部分服务器负载较小的情况。通过负载均衡,使得集群中服务器的负载保持在稳定高效的状态,从而提高整个系统的处理能力。
软件负载均衡:nginx,lvs
硬件负载均衡:F5
第一层可以用DNS,配置多个A记录,让DNS做第一层分发。
第二层用比较流行的是反向代理,核心原理:代理根据一定规则,将http请求转发到服务器集群的单一服务器上。
软件负载均衡分为:服务端(集中式),客户端。
服务端负载均衡:在客户端和服务端中间使用代理,nginx。
客户端负载均衡:根据自己的情况做负载。Ribbon就是。
客户端负载均衡和服务端负载均衡最大的区别在于服务端地址列表的存储位置,以及负载算法在哪里。
客户端负载均衡
在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端地址列表,这些列表统统都是从服务注册中心获取的;
服务端负载均衡
在服务端负载均衡中,客户端节点只知道单一服务代理的地址,服务代理则知道所有服务端的地址。
介绍:
Ribbon是Netflix开发的客户端负载均衡器,为Ribbon配置服务提供者地址列表后,Ribbon就可以基于某种负载均衡策略算法,自动地帮助服务消费者去请求 提供者。Ribbon默认为我们提供了很多负载均衡算法,例如轮询、随机等。我们也可以实现自定义负载均衡算法。
Ribbon作为Spring Cloud的负载均衡机制的实现,
- Ribbon可以单独使用,作为一个独立的负载均衡组件。只是需要我们手动配置 服务地址列表。
- Ribbon与Eureka配合使用时,Ribbon可自动从Eureka Server获取服务提供者地址列表(DiscoveryClient),并基于负载均衡算法,请求其中一个服务提供者实例。
- Ribbon与OpenFeign和RestTemplate进行无缝对接,让二者具有负载均衡的能力。OpenFeign默认集成了ribbon。
Ribbon组成
- ribbon-core: 核心的通用性代码。api一些配置。
- ribbon-eureka:基于eureka封装的模块,能快速集成eureka。
- ribbon-examples:学习示例。
- ribbon-httpclient:基于apache httpClient封装的rest客户端,集成了负载均衡模块,可以直接在项目中使用。
- ribbon-loadbalancer:负载均衡模块。
- ribbon-transport:基于netty实现多协议的支持。比如http,tcp,udp等。
利用Eureka手写负载均衡
代码
@Autowired DiscoveryClient discoveryClient; AtomicInteger atomicInteger = new AtomicInteger(); @GetMapping("/client7") public Object client7() { List<ServiceInstance> instances = discoveryClient.getInstances("provider"); // 随机 int nextInt = new Random().nextInt(instances.size()); // 自定义轮训算法 int i = atomicInteger.getAndIncrement(); instances.get(i % instances.size()); // 权重。。 for (ServiceInstance serviceInstance : instances) { // int quanzhong = serviceInstance.getMetadata(); // 权重 1-9 } ServiceInstance instance = instances.get(nextInt); // ribbon 完成客户端的负载均衡,过滤掉down了的节点 // ServiceInstance instance = lb.choose("provider"); String url ="http://" + instance.getHost() +":"+ instance.getPort() + "/getHi"; String respStr = restTemplate.getForObject(url, String.class); return respStr; }
@LoadBalanced
实际使用方式
- 在eureka-client中使用Ribbon时, 不需要引入jar包,因为erueka-client已经包括ribbon的jar包了。点进去看看。
- 用@LoadBalance修饰RestTemplate可以实现负载均衡。
- 由于RestTemplate的Bean实例化方法restTemplate被@LoadBalanced修饰,所以当调用restTemplate的postForObject方法发送HTTP请求时,会使用Ribbon进行负载均衡。
//使用ribbon,添加@LoadBalance,使RestTemplate具备负载均衡能力。 @Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } @Autowired private RestTemplate restTemplate; //serviceName=虚拟主机名。默认情况下,虚拟主机名和服务名一致。 String url = "http://"+serviceName+"/send/alisms-template"; //调用 ResponseEntity<ResponseResult> resultEntity = restTemplate.postForEntity(url, smsSendRequest, ResponseResult.class); //测试根据serviceName获取服务提供者信息。此时不需要@LoadBalance,默认是轮训。 @Autowired private LoadBalancerClient loadBalancerClient; // 不能将choseServiceName和 restTemplate写在一起,因为后者中已经有前者了。 @GetMapping("/choseServiceName") public ResponseResult choseServiceName() { String serviceName = "service-sms"; ServiceInstance si = loadBalancerClient.choose(serviceName); System.out.println("sms节点信息:url:"+si.getHost()+",port:"+si.getPort()); return ResponseResult.success(""); }
切换负载均衡策略
注解方式
@Bean public IRule myRule(){ //return new RoundRobinRule(); //return new RandomRule(); return new RetryRule();
配置文件
针对服务定ribbon策略:
provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
给所有服务定ribbon策略:
ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
属性配置方式优先级高于Java代码。
Ribbon脱离注册中心
Ribbon可以和服务注册中心Eureka一起工作,从服务注册中心获取服务端的地址信息,也可以在配置文件中使用listOfServers字段来设置服务端地址。
ribbon.eureka.enabled=false ribbon.listOfServers=localhost:80,localhost:81
到此这篇关于SpringCloud中的Ribbon负载均衡详细解读的文章就介绍到这了,更多相关SpringCloud的Ribbon负载均衡内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!