在接触 Spring Cloud 这套框架之前,笔者使用的一直是Dubbo。在转型到Spring Cloud 后,发现了一个很郁闷的问题。Spring Cloud 中的 Openfeign,相比于 Dubbo 对单个方法和单个接口(Interface)设置RPC超时时间,支持的不是特别理想。我查阅了一些资料和博客发现,现有的 Feign 只支持RPC超时设置的方式主要有以下几种

第一种配置默认的连接超时和读取超时,该配置全局生效。

feign.client.config.default.connectTimeout=2000
feign.client.config.default.readTimeout=5000

第二种是设置服务级别的连接超时和读取超时,该配置对这个服务的全部接口生效。

# 单个服务 连接超时时间
feign.client.config.{这里填写服务名称}.connectTimeout = 5000
# 单个服务 读超时时间
feign.client.config.{这里填写服务名称}.readTimeout = 10000

以上两种的粒度都非常粗,所以使用起来并不是很理想。下面要介绍的方案避免了这个粗粒度的问题。

第三种是借助于Hystrix实现方法级别的超时时间设置:

#首先是开启 Hystrix
feign.hystrix.enabled = true # 全局设置超时
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 30000 #服务级别设置超时
hystrix.command.{这里填写服务名称}.execution.isolation.thread.timeoutInMilliseconds: 30000

要对以下接口进行设置:

public interface MemberService {
@RequestMapping("/getUsers")
List<User> getUsers(String name);
}
# 方法级别设置超时
hystrix.command.MemberService#getUser(String).execution.isolation.thread.timeoutInMilliseconds = 3000

分析一下一下几种方法的优劣:

首先以上几种方法都是可以使用的没有问题,只是用起来不是特别爽快,相比于Dubbo总感觉缺点东西。第一种和第二种粒度太大,如果只是有一个方法需要很长的时间,如果只是为了这个方法,而将这个服务下所有的方法都设置成同样长的超时时间,显然是不太合适的。而第三种方法又要开启Hystrix,说句老实话,Hystrix现在新的项目使用的越来越少,就像笔者现在使用的是Sentinel。而且Hystrix的超时设置比较奇特用并不是我们所理解的Rpc 连接超时和读取超时,而是执行超时时间。如果有兴趣的同学可以自己去了解一下,因为篇幅有限这里就不展开讲了。

各位看官看到这里是不是要开始吐槽了,讲了大半天了,讲的都是大家知道的,一点干货都没有,说好的强化插件呢???

各位大大不要着急,下面就要开始介绍Feign的强化插件,集成了连接超时,读取超时和重试。分为服务提供方的注解形式和服务消费方的配置形式。该插件的的作用在于补全openfeign客户端在使用的默认代理和 Sentinel 代理 的过程中无法自定义单个接口或者单个方法级别的超时时间与重试的插件。

本插件的优先级为:

服务消费者method配置 > 服务提供者method > 服务消费者interface级配置 > 服务提供者interface级配置 > 服务消费者全局配置
注意:是否允许重试以服务提供者注解标识为最高优先级,只有服务提供方注解显示的表明可以重试,才能执行重试。如果注解没有,默认不可重试。

服务提供方 maven 引用:

            <dependency>
<groupId>org.example</groupId>
<artifactId>openfeign-strengthen-plugin-annotation</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

java 代码书写方式(服务提供方使用注解形式):

 /**
* 注解放在 interface 上,则该 interface 下所有的方法 共享该配置
*/
@RpcInfo(connectTimeout = 2,connectTimeoutUnit = TimeUnit.SECONDS, readTimeout = 1, readTimeoutUnit = TimeUnit.SECONDS, followRedirects = false)
public interface MemberService { /**
* 注解放在 method 上
* 则该 method RPC调用 时使用该配置。
* 方法上的配置优先级大于 interface 级别,
* 同时存在时,以 method 上的为准
* connectTimeout 连接超时时间
* connectTimeoutUnit 连接超时时间的单位 默认为毫秒
* readTimeout 读取超时时间
* readTimeoutUnit 读取超时时间单位 默认为毫秒
* followRedirects 是否重定向 默认为否
* maxAutoRetriesNextServer 切换实例的重试次数 默认为 0 次 禁止重试
* maxAutoRetries 对当前实例的重试次数 默认为 0 次 禁止重试
* isAllowedRetry 是否允许重试 默认为 false 不允许
*/
@RequestMapping("/getUsers")
@RpcInfo(connectTimeout = 2,connectTimeoutUnit = TimeUnit.SECONDS,
readTimeout = 1, readTimeoutUnit = TimeUnit.SECONDS, followRedirects = false,
maxAutoRetriesNextServer = 1, maxAutoRetries = 1, isAllowedRetry = true)
List<User> getUsers(String name); @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@RpcInfo(connectTimeout = 5,connectTimeoutUnit = TimeUnit.SECONDS, readTimeout = 2, readTimeoutUnit = TimeUnit.SECONDS)
String handleFileUpload(@RequestPart(value = "file") MultipartFile file);
}

服务消费者引入 maven 依赖:

        <dependency>
<groupId>org.example</groupId>
<artifactId>openfeign-strengthen-plugin-start</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>

服务消费者方使用 application.yml 配置的形式使用,并且服务消费者超时时间配置优先级高于服务提供方配置

  feign:
client:
rpcConfig:
#单个方法维度的配置
#接口名称 + # + 方法名称 + (参数类型, 参数类型...)
#包名 + 接口名称 + # + 方法名称 + (参数类型, 参数类型...) com.huihuang.service.MemberService#getUsers(String)
MemberService#getUsers(String):
connectTimeout: 1 #连接超时
connectTimeoutUnit: SECONDS #超时时间单位
readTimeout: 1 #读取超时
readTimeoutUnit: SECONDS
followRedirects: false #是否允许重定向
maxAutoRetries: 2 # 对当前实例的重试次数
maxAutoRetriesNextServer: 1 # 切换实例的重试次数
#按接口维度配置 优先级低于 单个方法维度的配置
#接口名称
#包名 + 接口名称 com.huihuang.service.MemberService
MemberService:
connectTimeout: 1 #连接超时
connectTimeoutUnit: SECONDS #超时时间单位
readTimeout: 1 #读取超时
readTimeoutUnit: SECONDS
followRedirects: false #是否允许重定向
maxAutoRetries: 2 # 对当前实例的重试次数
maxAutoRetriesNextServer: 1 # 切换实例的重试次数
#全局维度配置 优先级低于 单个方法维度 和 接口维度 的配置
default:
connectTimeout: 1 #连接超时
connectTimeoutUnit: SECONDS #超时时间单位
readTimeout: 1 #读取超时
readTimeoutUnit: SECONDS
followRedirects: false #是否允许重定向
maxAutoRetries: 2 # 对当前实例的重试次数
maxAutoRetriesNextServer: 1 # 切换实例的重试次数

GitHub地址:https://github.com/RaidenXin/openfeign-strengthen-plugin

这是我自己遇到的问题,希望能给各位看官大大一点点帮助。如果有什么意见和建议欢迎和我联系,可以直接评论或者在我的微信公众号后台留言发给我,笔者现在在公司的职位是基础架构架构师,如果有其他的Java方面或者基础架构方面的问题也可以一起交流一下。非常感谢大家的观看。

下面是我的公众号:

微服务改造之Openfeign的强化插件的更多相关文章

  1. 罗辑思维首席架构师:Go微服务改造实践

    转自:http://www.infoq.com/cn/news/2018/05/luojisiwei 方圆 曾先后在 Cisco,新浪微博从事基础架构研发工作.十多年一直专注于后端技术的研发,在消息通 ...

  2. Viper 微服务框架 编写一个hello world 插件-02

    1.Viper是什么? Viper 是.NET平台下的Anno微服务框架的一个示例项目.入门简单.安全.稳定.高可用.全平台可监控.底层通讯可以随意切换thrift grpc. 自带服务发现.调用链追 ...

  3. 一个项目的SpringCloud微服务改造过程

    SSO是公司一个已经存在了若干年的项目,后端采用SpringMVC.MyBatis,数据库使用MySQL,前端展示使用Freemark.今年,我们对该项目进行了一次革命性的改进,改造成SpringCl ...

  4. 微服务Kong(四)——添加插件

    在本节中,您将学习到,如何配置使用KONG的插件来管理您的API.KONG的核心原则之一就是通过插件来实现API的扩展.插件可以使您更为简单的扩展和管理您的API. 在以下的步骤中,您将通过配置key ...

  5. spring boot微服务改造冲突

    1.报错: 13:57:49.959 [main] ERROR org.springframework.boot.SpringApplication - Application startup fai ...

  6. 全)Java从单体到微服务打造房产销售平台 2018年慕课网 高清视频+源码

    第1章 课程介绍本章从整体上介绍课程有什么收获,以及课程如何安排,其中包括微服务的两个不同学习阶段--单体开发阶段(基于SpringBoot)和微服务改造阶段(基于SpringCloud),知识点梳理 ...

  7. 微服务架构-选择Spring Cloud,放弃Dubbo

    Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经走了一年多. 在使用 Spring Cloud 之前,我们对微服务实践是没有太多的体会和经验的.从 ...

  8. 放弃Dubbo,选择最流行的Spring Cloud微服务架构实践与经验总结

    http://developer.51cto.com/art/201710/554633.htm Spring Cloud 在国内中小型公司能用起来吗?从 2016 年初一直到现在,我们在这条路上已经 ...

  9. Spring Cloud 微服务的那点事

    什么是微服务 微服务的概念源于2014年3月Martin Fowler所写的一篇文章“Microservices”. 微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间互相协调 ...

随机推荐

  1. Java到底怎么学?

    你现在是不是想学Java,但很迷茫不知该从何下手,那么请认真看完这篇文章,希望对你有所帮助! 作为零基础刚刚接触Java的朋友们来说,我的建议还是先看视频,虽然有很多人说看视频学习慢,建议直接买优秀的 ...

  2. Java基础语法(语法、位运算、JavaDoc等)

    一.注释.标识符.关键字 1.注释(comments) 平时我们编写代码,在代码量比较少的时候,我们还可以看懂自己编写的代码,但是当项目结构一旦复杂起来,我们就需要用到注释了! 注释并不会被程序执行, ...

  3. 初学Python-day13 文件处理1

    IO操作 一.os模块 作用:包含了操作系统的基本功能,提供了非常丰富的用来处理文件和目录的函数或方法. 1.属性 函数名 函数说明 name 获取操作系统的类型 uname 获取操作系统的信息(li ...

  4. 【Java虚拟机6】Java内存模型(Java篇)

    什么是Java内存模型 <Java虚拟机规范>中曾试图定义一种"Java内存模型"(Java Memory Model,JMM)来屏蔽各种硬件和操作系统的内存访问差异, ...

  5. mybatis学习笔记(1)基本环境

    1.pom引入 <dependencies> <dependency> <groupId>org.mybatis</groupId> <artif ...

  6. 第六次Alpha Scrum Meeting

    本次会议为Alpha阶段第六次Scrum Meeting会议 会议概要 会议时间:2021年5月2日 会议地点:线上会议 会议时长:20min 会议内容简介:本次会议主要由每个人展示自己目前完成的工作 ...

  7. Noip模拟11 2021.7.11

    T1 math 其实看看题面,看看给的那机组数据即可看出规律了(然而当时并没有,只是发现模数的循环节,存了个vector,接下来就暴力了) 有个柿子: 其实就是裴蜀定理. 然后想一想的话就是 那么只要 ...

  8. numpy中的nan和常用方法

    1.数组的拼接 import numpy as np t1 = np.array([[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11]]) t2 = np.array([ ...

  9. 中文NER的那些事儿4. 数据增强在NER的尝试

    这一章我们不聊模型来聊聊数据,解决实际问题时90%的时间其实都是在和数据作斗争,于是无标注,弱标注,少标注,半标注对应的各类解决方案可谓是百花齐放.在第二章我们也尝试通过多目标对抗学习的方式引入额外的 ...

  10. Linux 文本三剑客之 grep

    Linux 系统中一切皆文件. 文件是个文本.可以读.可以写,如果是二进制文件,还能执行. 在使用Linux的时候,大都是要和各式各样文件打交道.熟悉文本的读取.编辑.筛选就是linux系统管理员的必 ...