Spring Cloud升级之路 - Hoxton - 8. 修改实例级别的熔断为实例+方法级别
实例级别的熔断带来的困扰
如之前系列(Spring Cloud升级之路 - Hoxton - 4. 使用Resilience4j实现实例级别的隔离与熔断)所述,我们实现了实例级别的熔断。但是在生产中发现,并不是所有情况下都表现良好。首先如果发布了新接口,但是不小心回滚了,调用新接口就会报错,从而导致整个实例都不能访问。还有就是某些实例某个接口出现了问题,但是其他接口是好的,熔断掉整个实例有点浪费。于是乎,我们将实例级别的熔断改成 实例 + 方法级别。
对于 OpenFeign 修改
首先,我们只针对断路器进行修改,线程隔离还是实例级别的,如果也抽象为实例+方法级别的,线程数与线程池的数量就太多了。
每个 Feign 调用都是有 url 的,我们是不是可以通过 url 获取不同的断路器呢?这样做是可以的,的确实现了实例 + 方法级别的熔断。但是有一个问题,对于有 PathVaraiable
的 FeignClient,相当于每个参数都会新建一个断路器,这并不是我们想要的,例如:
package com.github.hashjang.hoxton.service.consumer.feign;
//省略import
@FeignClient(value = "service-provider")
public interface ServiceProviderTestReadTimeoutFeignCleint {@RequestMapping(value = "/test-read-time-out/{userId}", method = RequestMethod.GET)String testTimeoutGet(@PathVariable String userId);
}
这样的话,对于每一个 userId 都会生成一个不同的断路器,这样断路器实际上可能没起到该有的作用。
所以,还是用实际 Feign 接口的类全限定方法名称作为唯一标识。
LoadBalancerConfig.java:
@Override
public Response execute(Request request, Request.Options options) throws IOException {String serviceName = request.requestTemplate().feignTarget().name();String serviceInstanceId = getServiceInstanceId(request);String serviceInstanceMethodId = getServiceInstanceMethodId(request);ThreadPoolBulkhead threadPoolBulkhead;CircuitBreaker circuitBreaker;try {//每个实例一个线程池threadPoolBulkhead = threadPoolBulkheadRegistry.bulkhead(serviceInstanceId, serviceName);} catch (ConfigurationNotFoundException e) {threadPoolBulkhead = threadPoolBulkheadRegistry.bulkhead(serviceInstanceId);}try {//每个服务实例具体方法一个resilience4j熔断记录器,在服务实例具体方法维度做熔断,所有这个服务的实例具体方法共享这个服务的resilience4j熔断配置circuitBreaker = circuitBreakerRegistry.circuitBreaker(serviceInstanceMethodId, serviceName);} catch (ConfigurationNotFoundException e) {circuitBreaker = circuitBreakerRegistry.circuitBreaker(serviceInstanceMethodId);}//省略之后代码
}private String getServiceInstanceId(Request request) throws MalformedURLException {String serviceName = request.requestTemplate().feignTarget().name();URL url = new URL(request.url());return serviceName + ":" + url.getHost() + ":" + url.getPort();
}private String getServiceInstanceMethodId(Request request) throws MalformedURLException {String serviceName = request.requestTemplate().feignTarget().name();URL url = new URL(request.url());//通过微服务名称 + 实例 + 方法的方式,获取唯一idString methodName = request.requestTemplate().methodMetadata().method().toGenericString();return serviceName + ":" + url.getHost() + ":" + url.getPort() + ":" + methodName;
}
对于 Spring Cloud Gateway 修改
对于 Spring Cloud Gateway,仅仅是在断路器上面加上 url, 同样的,会有上面说的,如果 url 中带有某个参数的 PathVariable,会生成很多独立的断路器的问题,这个目前还没有什么办法好解决。
并且,网关对于 404 并不认为是错误,只对IO异常以及超时会有错误。这种情况下,对于实例熔断,也并不是不能接受,虽然还会有某个接口超时导致实例熔断的风险,但是将超时时间设置足够长,以后后续的微服务进行异常处理熔断,也是可以接受的。
综合评估之后,网关还是继续保持实例级别的熔断。
Spring Cloud升级之路 - Hoxton - 8. 修改实例级别的熔断为实例+方法级别相关推荐
- Spring Cloud升级之路 - Hoxton - 10. 网关重试带Body的请求Body丢失的问题
带 Body 的重试 Body 丢失 之前我们的配置里面,只对 Get 请求针对 500 响应码重试,但是针对像 Post 这样的请求,只对那种根本还没到发送 Body 的阶段的异常(例如连接异常)这 ...
- Spring Cloud 升级之路 - 2020.0.x - 1. 背景知识、需求描述与公共依赖
1. 背景知识.需求描述与公共依赖 1.1. 背景知识 & 需求描述 Spring Cloud 官方文档说了,它是一个完整的微服务体系,用户可以通过使用 Spring Cloud 快速搭建一个 ...
- Spring Cloud 升级最新 Finchley 版本,踩了所有的坑
转载自 Spring Cloud 升级最新 Finchley 版本,踩了所有的坑 Spring Boot 2.x 已经发布了很久,现在 Spring Cloud 也发布了 基于 Spring Bo ...
- springcloud完整项目_.net core+Spring Cloud学习之路 一
文章开头唠叨两句. 2019年了,而自己参加工作也两年有余了,用一个词来概括这两年多的生活,就是:"碌碌无为". 也不能说一点收获都没有,但是很少.2019来了,我立志要打破现状, ...
- .net core+Spring Cloud学习之路 一
文章开头唠叨两句. 2019年了,而自己参加工作也两年有余了,用一个词来概括这两年多的生活,就是:"碌碌无为". 也不能说一点收获都没有,但是很少.2019来了,我立志要打破现状, ...
- docker 安装nacos_「Java Spring Cloud 实战之路」 使用nacos配置网关
0. 前言 在上一节中,我们创建了一个项目架构,后续的项目都会在那个架构上做补充. 1. Nacos 1.1 简介 Nacos可以用来发现.配置和管理微服务.提供了一组简单易用的特性集,可以快速实现动 ...
- Spring Cloud微服务之模块依赖修改(六)
父工程parent的pom模块下,模块管理变成了如下,看起来不舒服,应该是一级目录下有二级,二级目录下有三级这样的层次感,看着才舒服. 移除模块一下子模块中的模块.不改也是可以的,只是个人习惯问题. ...
- Spring Cloud入门-Gateway服务网关(Hoxton版本)
文章目录 Spring Cloud入门系列汇总 摘要 Gateway 简介 相关概念 创建 api-gateway模块 在pom.xml中添加相关依赖 两种不同的配置路由方式 使用yml配置 使用Ja ...
- Spring Cloud入门-Admin服务监控中心(Hoxton版本)
文章目录 Spring Cloud入门系列汇总 摘要 Spring Boot Admin 简介 创建admin-server模块 创建admin-client模块 监控信息演示 结合注册中心使用 修改 ...
最新文章
- Centos7:update-initramfs -u:command not found
- excel分类_Excel数据处理学习(七)使用分类汇总
- 栈的应用就进匹配_笔记
- php fopen 错误,php fopen函数失败怎么办
- mysql 存储过程与存储函数
- Java web项目报错 Java compiler level does not match the version of the installed Java project facet.
- 数据结构—链表-单链表基本操作实现
- Oracle日期范围
- PLOS_ONE_Genome-Wide Analysis of Long Noncoding RNA (lncRNA) Expression in Hepatoblastoma Tissues
- xshell官网最新 中文,xshell
- python继承的3个特点_面向对象三大特征之继承
- confusing uv
- 基于麒麟座开发板2.0的MQTT实现例程
- 手机APP应注册这些类别的商标
- Kotlin快速学习之路(完整版)
- 何为固定IP和动态IP?快解析搞定固定IP端口映射!
- 拉姆.查兰《执行》笔记
- html监听多选框事件,复选框事件监听使用求助
- 教你路由器端口映射设置方法
- Material Design 2日期组件显示汉化 ,materia时间组件国际化,md2 时间组件汉化
热门文章
- swi-prolog安装及使用(基于)
- 我的网站http://www.xhu.cn/xhu/520/
- 学计算机和电子信息工程那个更好找工作,电子信息工程专业毕业月薪一般是多少 好不好找工作...
- loT技术(BT/WFI/ZIGBEE/MESH)
- 【译文】工作六年后,我对软件开发的认知转变
- 初级考试可以使用计算机吗,计算机初级考试的内容都有哪些
- 新库上线 | CnOpenData·IFR工业机器人数据
- 程序员必修内功,收集了上千本各类编程书籍【免费获取】
- 内存泄漏试试AScan
- MixMarvel行业分享专栏 韩国区块链市场观察:行业巨头布局区块链游戏领域