当前位置:网站首页>Ribbon负载均衡服务调用
Ribbon负载均衡服务调用
2022-06-26 05:26:00 【RB_VER】
概述
spring cloud ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单地说,ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。ribbon客户端组件提供一系列完善的配置项如连接超时、重试等。简单地说,就是在配置文件中列出load balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。
负载均衡就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。常见的负载均衡软件有Nginx、LVS等。
Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由Nginx实现转发请求。即负载均衡是由服务端实现的。(集中式LB)
Ribbon是本地负载均衡,在调用微服务接口时,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程过程调用技术。(进程内LB)
集中式LB:即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如Nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方。
进程内LB:将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
Ribbon负载均衡和Rest调用
Ribbon其实就是一个负载均衡的客户端组件,它可以和其他所需请求的客户端结合使用。

Ribbon工作时分两步:
第一步先选择Eureka Server,它优先选择在同一个区域内负责较少的server。
第二步再根据用户指定的策略,在从server获取到的服务注册列表中选择一个地址。
spring-cloud-starter-netflix-eureka-client自带了spring-cloud-starter-ribbon引用。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Ribbon默认自带的负载规则
IRule接口:根据特定算法中从服务列表中选取一个要访问的服务。
实现IRule接口的自带常用规则:
- com.netflix.loadbalancer.RoundRobinRule:轮询。(默认)
- com.netflix.loadbalancer.RandomRule:随机。
- com.netflix.loadbalancer.RetryRule:先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务。
- WeightedResponseTimeRule:对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择。
- BestAvailableRule:会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务。
- AvailabilityFilteringRule:先过滤故障实例,再选择并发较小的实例。
- ZoneAvoidanceRule:默认规则,复合判断server所在区域的性能和server的可用性选择服务器。
负载规则替换
自定义配置类不能放在@ComponentScan所扫描的当前包以及子包下,否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。
cloud-consumer-order80模块目录结构:
MySelfRule
package com.qrxqrx.myrule;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MySelfRule {
@Bean
public IRule myRule() {
return new RandomRule();
}
}
OrderMain80
package com.qrxqrx.springcloud;
import com.qrxqrx.myrule.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;
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name = "CLOUD-PAYMENT-SERVICE",configuration = MySelfRule.class)
public class OrderMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderMain80.class,args);
}
}
Ribbon默认负载均衡算法原理
rest接口第几次请求数 % 服务器集群总数量 = 实际调用服务器位置下标
每次服务重启后rest接口计数从1开始。
RoundRobinRule源码分析
RandomRule的choose方法:
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
log.warn("no load balancer");
return null;
} else {
Server server = null;
int count = 0;
while(true) {
if (server == null && count++ < 10) {
List<Server> reachableServers = lb.getReachableServers();
List<Server> allServers = lb.getAllServers();
int upCount = reachableServers.size();
int serverCount = allServers.size();
if (upCount != 0 && serverCount != 0) {
int nextServerIndex = this.incrementAndGetModulo(serverCount);
server = (Server)allServers.get(nextServerIndex);
if (server == null) {
Thread.yield();
} else {
if (server.isAlive() && server.isReadyToServe()) {
return server;
}
server = null;
}
continue;
}
log.warn("No up servers available from load balancer: " + lb);
return null;
}
if (count >= 10) {
log.warn("No available alive servers after 10 tries from load balancer: " + lb);
}
return server;
}
}
}
Ribbon手写轮询算法
在cloud-provider-payment8001和cloud-provider-payment8002中修改controller
@GetMapping(value = "/payment/lb")
public String getPaymentLB() {
return serverPort;
}
修改cloud-consumer-order80模块,注释掉配置类的@LoadBalanced
@Configuration
public class ApplicationContextConfig {
@Bean
//@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
实现LoadBalancer
package com.qrxqrx.springcloud.lb;
import org.springframework.cloud.client.ServiceInstance;
import java.util.List;
public interface LoadBalancer {
ServiceInstance instances(List<ServiceInstance> serviceInstances);
}
实现
package com.qrxqrx.springcloud.lb;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Component
public class MyLB implements LoadBalancer {
private AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public ServiceInstance instances(List<ServiceInstance> serviceInstances) {
int index = getAndIncrement() % serviceInstances.size();
return serviceInstances.get(index);
}
public final int getAndIncrement() {
int current;
int next;
do {
current = this.atomicInteger.get();
next = current >= 2147483647 ? 0 : current + 1;
} while(this.atomicInteger.compareAndSet(current,next));
System.out.println("第"+next+"次访问");
return next;
}
}
修改OrderController
@GetMapping(value = "/consumer/payment/lb")
public String getPaymentLB() {
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
if (instances == null || instances.size() <= 0) {
return null;
}
ServiceInstance serviceInstance = loadBalancer.instances(instances);
URI uri = serviceInstance.getUri();
return restTemplate.getForObject(uri+"/payment/lb",String.class);
}
边栏推荐
- Owasp-top10 in 2021
- Excellent learning ability is your only sustainable competitive advantage
- Use jedis to monitor redis stream to realize message queue function
- Two step processing of string regular matching to get JSON list
- apktool 工具使用文档
- How does P2P technology reduce the bandwidth of live video by 75%?
- Thoughts triggered by the fact that app applications are installed on mobile phones and do not display icons
- Official image acceleration
- cartographer_ fast_ correlative_ scan_ matcher_ 2D branch and bound rough matching
- Security problems in wireless networks and modern solutions
猜你喜欢

Uni app ceiling fixed style

Henkel database custom operator '~~‘

AutowiredAnnotationBeanPostProcessor什么时候被实例化的?
![C# 39. Conversion between string type and byte[] type (actual measurement)](/img/33/046aef4e0c1d7c0c0d60c28e707546.png)
C# 39. Conversion between string type and byte[] type (actual measurement)
The wechat team disclosed that the wechat interface is stuck with a super bug "15..." The context of

cartographer_local_trajectory_builder_2d

Beidou navigation technology and industrial application of "chasing dreams in space and feeling for Beidou"

The parameter field of the callback address of the payment interface is "notify_url", and an error occurs after encoding and decoding the signed special character URL (,,,,,)

Install the tp6.0 framework under windows, picture and text. Thinkphp6.0 installation tutorial

Ad tutorial series | 4 - creating an integration library file
随机推荐
[unity3d] collider assembly
MySQL source code reading (II) login connection debugging
The wechat team disclosed that the wechat interface is stuck with a super bug "15..." The context of
红队得分方法统计
How to rewrite a pseudo static URL created by zenpart
Apktool tool usage document
Beidou navigation technology and industrial application of "chasing dreams in space and feeling for Beidou"
出色的学习能力,才是你唯一可持续的竞争优势
10 set
Command line interface of alluxio
PHP one sentence Trojan horse
vscode config
C# 39. Conversion between string type and byte[] type (actual measurement)
RESNET in tensorflow_ Train actual combat
使用Jedis監聽Redis Stream 實現消息隊列功能
Security problems in wireless networks and modern solutions
Could not get unknown property ‘*‘ for SigningConfig container of type org. gradle. api. internal
Redis discovery bloom filter
电机专用MCU芯片LCM32F037系列内容介绍
小小面试题之GET和POST的区别