SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的方法

网友投稿 404 2022-11-23


SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的方法

1、Ribbon

Spring Cloud Ribbon是基于Netflix Ribbon实现的—套客户端―负载均衡的工具。

简单的说,Ribbon是Netlix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。

目前Ribbon和Eureka进入到维护模式。停更不停用

负载均衡:

LB负载均衡(Load Balance)是什么?

简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)。1

常见的负载均衡有软件Nginx,LVS,硬件F5等。

Ribbon本地负载均衡客户端VS Nginx服务端负载均衡区别

Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求。即负载均衡是由服务端实现的。

Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到VM本地,从而在本地实现RPC远

程服务调用技术。

1、集中式LB

即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如nginx)由该设施负责把访问请求通过某种策咯转发至服务的提供方;

2、进程内LB

将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

负载均衡 +RestTemplate 配合使用

架构

总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例.

Ribbon在工作时分成两步

第一步先选择EurekaServer ,它优先选择在同一个区域内负载较少的server.

第二步再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。

其中Ribbon提供了多种策略:比如轮询、随机和根据响应时间加权。

pom 依赖

spring-cloud-starter-netflix-eureka-client

自身 就集成了 ribbon 。

RestTemplate说明:

Ribbon负载均衡规则

继承结构

自带7种:

如何使用?负载均衡策略替换。

官方文档明确给出了警告:

这个自定义配置类不能放在@ComponentScan所扫描的当前包下以及子包下,

否则我们自定义的这个配置类就会被所有的Ribbon客户端所共享,达不到特殊化定制的目的了。

增加rule配置类

包路径: com.fage.rules

@Configuration

public class MyRibbonRule {

@Bean

public IRule randomRule() {

return new RandomRule();

}

}

boot启动类增加注解

@RibbonClient(name = "cloud-payment-service", configuration = {MyRibbonRule.class})

负载均衡轮询算法原理

负载均衡算法: rest接口第几次请求数%服务器集群总数量=实际调用服务器位置下标,每次服务重启动后rest接口计数从1开始。

List instances = discoveryClient.getlnstances(CLOUD-PAYMENT-SERVICE");

如:List [o] instances = 127.0.0.1:8002

List [1] instances = 127.0.0.1:8001

8001+8002组合成为集群,它们共计2台机器,集群总数为2,按照轮询算法原理:

当总请求数为1时:1%2=1对应下标位置为1,则获得服务地址为127.0.0.1:8001

当总请求数位2时: 2%2=O对应下标位置为0,则获得服务地址为127.0.0.1:8002

当总请求数位3时:3%2=1对应下标位置为1,则获得服务地址为127.0.0.1:8001

当总请求数位4时:4%2=0对应下标位置为0,则获得服务地址为127.0.0.1:8002

如此类推......

源码:

从0开始取余获取提供者服务。

内部使用cas+自旋锁。

手写一个负载均衡算法,实现轮询

1、服务提供者增加接口

@GetMapping("/payment/loadBalanced")

public CommonResult getLoadBalanced() {

return new CommonResult<>(200, "调用成功", port);

}

2、服务消费者改造

将 @LoadBalanced 注解去掉

增加MyLoadBalanced接口,只有一个方法ServiceInstance instance(List serviceInstances);用于得到当前算法后要使用的实例对象。

实现类MyLib源码如下:

@Component

@Slf4j

public class MyLib implements MyLoadBalanced {

private final AtomicInteger nextServerCyclicCounter = new AtomicInteger(0);

public final int getAndIncrement() {

// 方案 1 cas

// int current;

// int next;

// do {

// current = this.nextServerCyclicCounter.get();

// next = current >= 2147483647 ? 0 : current + 1;

// } while (!this.nextServerCyclicCounter.compareAndSet(current, next));

// log.info("**********第几次访问,次数next:" + next);

// return next;

// 方案 2 JUC 提供的 自增方法

log.info("**********第几次访问,次数next:" + nextServerCyclicCounter.getAndIncrement());

return nextServerCyclicCounter.get();

}

/**

* 负载均衡算法:rest接口第几次请求书 % 服务器集群总数量 = 实际调用服务器位置下标,每次服务重启动后rest接口计数从1开始

*

* @param serviceInstances 集群中的 服务 实例

* @return 集群中的一个实例

*/

@Override

public ServiceInstance instance(List serviceInstances) {

return serviceInstances.get(getAndIncrement() % serviceInstances.size());

}

}

3、改造消费者调用方法

@GetMapping(value = "/consumer/payment/loadBalanced")

public CommonResult getLoadBalanced() {

ServiceInstance instance = myLoadBalanced.instance(discoveryClient.getInstances(PAYMENT_URL.split("//")[1]));

return restTemplate.getForObject(instance.getUri()+"/payment/loadBalanced", CommonResult.class);

}

2、OpenFeign

只需要一个接口并在接口上添加注解即可。

feign不再更新,直接学习openFeign。都是用于负载均衡。

Feign是一个声明式WebService客户端。使用Feign能让编写Web Service客户端更加简单。

它的使用方法是定义一个服务接口然后在上面添加注解。Feign也支持可拔括式的编码罴和解码器。Spring Cloud对Feign进行了封装,使其支持了Spring MVC标准注解和HttpMessageConverters。Feign和ribbon组合使用以支持负载均衡。

Feign能干什么

Feign旨在使编写java Http客户端变得更容易。

前面在使用Ribbon+RestTemplate时,利用RestTemplate对http请求的封装处理,形成了一套模版化的调用方法。但是在实际开发

中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装

这些依赖服务的调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。在Feign的实现下

,我们只需创建一个接口并使用注解的方式来配置它(以前是Dao接口上面标注Mapper注解,现在是一个微服务接口上面标注一个

Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring cloud Ribbon时,自动封装服务调用客户端的开发量。

Feign集成了Ribbon

利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过feign只需要定义

服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用

Feign和openFeign的区别

搭建openFeign模块 cloud-consumer-openfeign-order80

org.springframework.cloud

spring-cloud-starter-openfeign

启动类增加注解@EnableFeignClients

增加feign接口

@Component

@FeignClient(value = "cloud-payment-service")

public interface OpenFeignService {

@GetMapping("/payment/loadBalanced")

public CommonResult getLoadBalanced();

}

增加controller

@RestController

@Slf4j

public class OrderController implements OpenFeignService {

@Resource

OpenFeignService openFeignService;

@Override

@GetMapping("/consumer/payment/loadBalanced")

public CommonResult getLoadBalanced() {

return openFeignService.getLoadBalanced();

}

}

注册中心使用eureka。跟之前一样。

OpenFeign超时控制

OpenFeign默认等待时间为1ms。

设置超时时间

###设置 超时时间 方式 1

# 设置 feign客户端超时时间 ( openFeign 默认支持 ribbon )

ribbon:

# 指的是建立连接所用的时间,适用于网络状况正常的情况下,俩端连接所用的时间 单位是秒

ReadTimeout: 6000

# 指的是建立连接后从服务器读取到可用资源的时间

ConnectTimeout: 5000

###设置 超时时间 方式 2

#feign:

# client:

# config:

# default:

# connectTimeout: 5000

# readTimeout: 6000

# loggerLevel: full

OpenFeign日志增强

Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。

说白了就是对Feign接口的调用情况进行监控和输出

日志级别:

NONE:默认的,不显示任何日志;

BASIC:仅记录请求方法、URL、响应状态码及执行时间;

HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;

FULL:除HEADERS中定义的信息之外,还有请求和响应的正文及元数据。

配置日志bean:

@Bean

Logger.Level feignLoggerLevel() {

return Logger.Level.FULL;

}

yml开启日志

# 设置 feign客户端超时时间 ( openFeign 默认支持 ribbon )

ribbon:

# 指的是简历连接所用的时间,适用于网络状况正常的情况下,俩端连接所用的时间 单位是秒

ReadTimeout: 8000

# 指的是建立连接后从服务器读取到可用资源的时间

ConnectTimeout: 6000

# 开启 feign 日志打印

logging:

level:

## feign 日志 以什么级别 监控那个接口

com.fage.springcloud.feign.OpenFeignService: debug

结果:

2020-08-25 17:55:26.667 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] ---> GET http://cloud-payment-service/payment/loadBalanced HTTP/1.1

2020-08-25 17:55:26.667 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] ---> END HTTP (0-byte body)

2020-08-25 17:55:26.682 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] <--- HTTP/1.1 200 (14ms)

2020-08-25 17:55:26.682 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] connection: keep-alive

2020-08-25 17:55:26.682 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalJMzRzNtanced] content-type: application/json

2020-08-25 17:55:26.682 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] date: Tue, 25 Aug 2020 09:55:26 GMT

2020-08-25 17:55:26.682 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] keep-alive: timeout=60

2020-08-25 17:55:26.682 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] transfer-encoding: chunked

2020-08-25 17:55:26.682 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] 

2020-08-25 17:55:26.683 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService   : [OpenFeignService#getLoadBalanced] {"code":200,"message":"调用成功","data":"8001"}


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java实现字符串反转案例
下一篇:SpringBoot系列教程之dubbo和Zookeeper集成方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~