1,Ribbon是做什么地?
Spring Cloud Rebbon 是基于netflix Ribbon 实现的一套客户端负载均衡的工具
主要功能是提供客户端软件负载均衡算法和服务调用的,Ribbon客户端组件提供一系列完成的配置项,就是在配置文件中列出Load Balancer后面的所有机器,Ribbon会自动地帮助你基于某种规则(比如轮询算法,随机连接)去连接机器,我们很容易使用Ribbon实现自定义地负载均衡算法
2, LB
简单地说就是将用户地请求平摊分配到多个服务,从而达到系统地HA,常见地负载均衡有 Nginx,LVS,硬件F5等
3,Ribbon本地负载均衡客户端 VS Nginx服务端负载均衡区别?
Nginx: 客户端所有地请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现
Ribbon:在调用微服务接口地时候会在注册中心获取注册信息地服务列表之后缓存到JVM本地,从而实现RPC远程服务调用技术
集中式LB:在服务地消费方和调用方使用独立的LB设施,由该设施负责把访问请求通过某种策略转发至服务提供方;
进程内LB: 将LB逻辑集成到消费方,消费方从服务地注册中心获取由那些地址可用,然后再从这些地址选择何时地服务器。
Ribbon就是属于进程内LB,他只是一个类库,集成于消费方进程,消费方通过它来获取服务提供方的地址。
4, Ribbon只是一个软负载均衡的客户端组件,它可以和其他所需请求的客户端结合使用,和eureka结合只是其中一个实例
负载均衡+RestTemplate
5,pom
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
另外高版本Spring CLoud 的eureka内部集成了Ribbon
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
6,RestTemplate
@Bean
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment){
//返回对象为响应体中转换成的对象可以理解为Json
return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment, CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") Long id){
//返回的是对对象
return restTemplate.getForObject(PAYMENT_URL+"/payment/get/"+id,CommonResult.class);
}
7,Ribbon核心组件 IRule
8,自定义的配置类不能放在@ComponentScan(@SringBootApplication)所扫描的包下及子包下,否则我们自定义的这个被之类会被所有的ribbon客户端所共享,不能达到特殊定制化的目的
9,Ribbon 负载均衡算法的原理
负载均衡算法:rest接口第几次请求%服务器集群的总数量=实际调用服务器位置的下标,每次服务启动后rest接口计数从1开始。
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
核心代码
CAS自旋锁机制
private int incrementAndGetModulo(int modulo) {
for (;;) {
int current = nextServerCyclicCounter.get();
int next = (current + 1) % modulo;
if (nextServerCyclicCounter.compareAndSet(current, next))
return next;
}
}