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<Object> 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<ServiceInstance> 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
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
启动类增加注解@EnableFeignClients
增加feign接口
@Component
@FeignClient(value = "cloud-payment-service")
public interface OpenFeignService {
@GetMapping("/payment/loadBalanced")
public CommonResult<Object> getLoadBalanced();
}
增加controller
@RestController
@Slf4j
public class OrderController implements OpenFeignService {
@Resource
OpenFeignService openFeignService;
@Override
@GetMapping("/consumer/payment/loadBalanced")
public CommonResult<Object> 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#getLoadBalanced] 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"}
2020-08-25 17:55:26.683 DEBUG 56624 --- [p-nio-80-exec-2] c.f.springcloud.feign.OpenFeignService : [OpenFeignService#getLoadBalanced] <--- END HTTP (51-byte body)
公众号:发哥讲
这是一个稍偏基础和偏技术的公众号,甚至其中包括一些可能阅读量很低的包含代码的技术文,不知道你是不是喜欢,期待你的关注。
代码分享
微信公众号 点击关于我,加入QQ群,即可获取到代码以及高级进阶视频和电子书!!
如果你觉得文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈~
● 扫码关注我们
据说看到好文章不推荐的人,服务器容易宕机!
本文版权归 发哥讲 和 博客园 共有,原创文章,未经允许不得转载,否则保留追究法律责任的权利。
SpringCloud 服务负载均衡和调用 Ribbon、OpenFeign的更多相关文章
- SpringCloud服务负载均衡实现原理01
- SpringCloud服务负载均衡实现原理02
- SpringCloud系列五:Ribbon 负载均衡(Ribbon 基本使用、Ribbon 负载均衡、自定义 Ribbon 配置、禁用 Eureka 实现 Ribbon 调用)
1.概念:Ribbon 负载均衡 2.具体内容 现在所有的服务已经通过了 Eureka 进行了注册,那么使用 Eureka 注册的目的是希望所有的服务都统一归属到 Eureka 之中进 行处理,但是现 ...
- 玩转Spring Cloud之服务注册发现(eureka)及负载均衡消费(ribbon、feign)
如果说用Spring Boot+Spring MVC是开发单体应用(或单体服务)的利器,那么Spring Boot+Spring MVC+Spring Cloud将是开发分布式应用(快速构建微服务)的 ...
- 四. SpringCloud负载均衡与调用
1. Ribbon概述 1.1 Ribbon是什么 SpringCloud Ribbon是基于Netflix Ribbon实现的一套客户端,是负载均衡的工具. Ribbon是Netflix发布的开源项 ...
- 微服务负载均衡 —— ribbon
负载均衡是系统高可用.缓解网络流量和处理能力扩容的重要手段,广义的负载均衡指的是服务端负载均衡,如硬件负载均衡(F5)和软件负载均衡(Nginx).负载均衡设备会维护一份可用的服务器的信息,当客户端请 ...
- 基于Docker + Consul + Nginx + Consul-Template的服务负载均衡实现(转)
转:https://www.jianshu.com/p/fa41434d444a 前言 上一篇文章使用 Consul 和 Registrator 在 docker 的容器环境中搭建了服务注册和发现集群 ...
- 【微服务】之四:轻松搞定SpringCloud微服务-负载均衡Ribbon
对于任何一个高可用高负载的系统来说,负载均衡是一个必不可少的名称.在大型分布式计算体系中,某个服务在单例的情况下,很难应对各种突发情况.因此,负载均衡是为了让系统在性能出现瓶颈或者其中一些出现状态下可 ...
- SpringCloud(三):服务消费以及负载均衡(RestTemplate+Ribbon)
一.什么是Ribbon: Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法. 将Netflix的中间层服务连接在一起.Ribbon客户端组件提供一系列完善的配置项如连 ...
随机推荐
- 【FZYZOJ】无向图的联通图个数 题解(组合数学)
题目大意:求无向图的连通图个数.由于个数可能很大,只需要求出结果$mod1000000009$的值.$n\leq 1000$ ------------------------- 对于一个含有$n$个结 ...
- ios签名app稳定不掉签技术详细教程详解
iOS签名是专门针对ios的APP内测的数字签名,是苹果面向开发者提出的一箱机制. 因为现在苹果APP下载渠道只有App Store,还可以加上一个内测用的testflight,也就是说,除了这两个官 ...
- OAuth2.0-1
分布式授权解决方案: 其中授权服务一般放在网关服务上,资源服务指的是,挂在网关下得各个微服务 网关授权客户端>客户端拿到token>客户端拿到token到网关验证,获取token明文> ...
- 07-NABCD项目分析
时 间:2020.3.31 参加人员:向瑜.赵常恒.刘志霄 讨论记录内容: NABCD模型 ·N(need)-向瑜 你的创意解决了用户的什么需求? 1. 随时随地记录个人收支的明细,清楚明白的知 ...
- 修改 jar 包 或 war 包内容
修改 jar 包 或 war 包内容 有一个 java web 项目,是 .jar 或 .war 文件,我想替换其中的部分样式(.css)或功能(.class). 步骤就是解压,替换,重新打包. 以 ...
- HRNet
- 高级搜索树-红黑树(RBTree)解析
目录 红黑树的定义 节点与树的定义 旋转操作 插入操作 情况1:p的兄弟u为黑色 情况2: p的兄弟u为红色 插入操作性能分析 代码实现 删除操作 情况1:x的接替者succ为红色 情况2:x的接替者 ...
- C#LeetCode刷题之#521-最长特殊序列 Ⅰ(Longest Uncommon Subsequence I)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3949 访问. 给定两个字符串,你需要从这两个字符串中找出最长的特 ...
- JVM垃圾回收(GC)
JVM垃圾回收(GC) 1. 判断对象是否可以被回收 引用计数法:每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收.此方法简单,但无法解决对象相互循环引用的问 ...
- JavaScript 数组中根据某个属性值的中文进行排序
普通排序 const arr = [] arr.sort((x, y) => x.prop - y.prop) 中文属性值排序 const arr = [] arr.sort((x, y) =& ...