在上周在的微供有数项目中(数据产品),需要对接企业微信中第三方应用,在使用Feign的去调用微服务的用户模块用微信的code获取access_token以及用户工厂信息时出现Feign重试超时报错的情况,通过此篇文章记录问题解决的过程。

  一.问题重现:

    1.SpringCloud部分依赖如下

    <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Dalston.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

    2.微信相关的接口文档:

    前端通过企业id,配置好回调域名之后,调用微信的Api去获取code

    见文档https://work.weixin.qq.com/api/doc/90000/90135/91022

    注意:

      code只能用一次,见文档,因此获取到的access_token需要缓存起来,项目中是缓存到redis中的,用于后续的消息推送等等功能

      

    3.请求流程图

      

    

  二.原因分析

    1.整个请求的链路中,阶段2是feign请求的位置,但是yml配置文件中并没有配置feign,因此可以断定feign使用的默认的配置,问题发生时,查看feign的文档发现,feign重试默认超时时间是1s,

    因此现在重新配置feign的超时时间,现有feign的配置如下

feign:
client:
config:
organization:
connectTimeout: 5000
readTimeout: 5000

    其实organization表示的就是feign所调用的服务名称

    connectTimeout表示建立请求连接的连接的时间(这里面包括获取请求eureka中保存的服务列表-推测)

    readTimeout表示连接建立以后请求调用的时间

    2.在上述配置中,通过查看organization和data服务的请求日志,发现请求都能顺利的建立,但是当阶段三去请求微信的接口一旦延迟,则会触发feign的重试进行第二次调用;

    由于阶段三请求微信的接口并不是没有调用,而是由于网络或者其他原因导致的微信没有响应,但是code又已经被消费了,当阶段二携带同样的code去调用微信的接口,这时就会出现

    code已经被消费

    3.此时有另外一个问题就是,项目中的服务都是单实例部署,springcloud组件中feign和ribbon都有重试的功能,

    Spring Cloud中Feign整合了Ribbon,但Feign和Ribbon都有重试的功能,Spring Cloud为了统一两者的行为,在C版本以后,将Feign的重试策略默认设置为 feign.Retryer#NEVER_RETRY(即永不重试)

    因此Feign的调用本质还是通过ribbon去实现

  三,相关配置测试

    经过测试后,发现feign和ribbon的配置都能实现超时熔断
    版本号:SpringCloud  Greenwich.SR1
    配置一:
    只配置feign相关,即feign覆盖了ribbon默认的超时时间配置,但是注意,该配置会触发ribbon的重试,

feign:
client:
config:
eureka-client:
connectTimeout: 1000
readTimeout: 1000

    配置二:

    只配置ri'bbon

    注意 这里有个坑MaxAutoRetriesNextServer这个参数如果不配置为0,即使在单实例部署的情况下,仍然会发生重试1次,因此如果不想发生重试,则需要手动配置

    MaxAutoRetriesNextServer=0和MaxAutoRetries=0

ribbon:
ReadTimeout: 4000
ConnectionTimeout: 4000
OkToRetryOnAllOperations: true
MaxAutoRetriesNextServer: 0 # 当前实例全部失败后可以换1个实例再重试,
MaxAutoRetries: 1 # 在当前实例只重试2次

    配置三:

    feign和ribbon都不配置,注意,经过测试后发现这里使用的是ribbon默认的超时配置,配置如下:

    MaxAutoRetriesNextServer=1   

    MaxAutoRetries=0

public LoadBalancerContext(ILoadBalancer lb) {
this.clientName = "default";
this.maxAutoRetriesNextServer = 1;
this.maxAutoRetries = 0;
this.defaultRetryHandler = new DefaultLoadBalancerRetryHandler();
this.okToRetryOnAllOperations = DefaultClientConfigImpl.DEFAULT_OK_TO_RETRY_ON_ALL_OPERATIONS;
this.lb = lb;
}

    版本号:SpringCloud   Dalston.SR1 与 Greenwich.SR1的测试结论一致  

    注意:  Dalston.SR1  ribbon组件默认的超时时间

    public static final int DEFAULT_READ_TIMEOUT = 5000;

public static final int DEFAULT_CONNECT_TIMEOUT = 2000;

    Greenwich.SR1 ribbon组件默认的超时间

    public static final int DEFAULT_CONNECT_TIMEOUT = 1000;
public static final int DEFAULT_READ_TIMEOUT = 1000;

      

    

【Feign/Ribbon】记录一次生产上的SpringCloudFeign的重试问题的更多相关文章

  1. Feign Ribbon Hystrix 三者关系 | 史上最全, 深度解析

    史上最全: Feign Ribbon Hystrix 三者关系 | 深度解析 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 前言 疯狂创客圈(笔者尼恩创建的 ...

  2. 【OOM】记录一次生产上的OutOfMemory解决过程

    一.项目架构 SpringCloud  Dalston.SR1 + SpringBoot 1.5.9 + Mysql +Redis + RabbitMQ 所有的业务模块的应用服务都部署在同一个服务器, ...

  3. springcloud微服务实战:Eureka+Zuul+Feign/Ribbon+Hystrix Turbine+SpringConfig+sleuth+zipkin

    相信现在已经有很多小伙伴已经或者准备使用springcloud微服务了,接下来为大家搭建一个微服务框架,后期可以自己进行扩展.会提供一个小案例: 服务提供者和服务消费者 ,消费者会调用提供者的服务,新 ...

  4. 记录CentOS 7.4 上安装MySQL&MariaDB&Redis&Mongodb

    记录CentOS 7.4 上安装MySQL&MariaDB&Redis&Mongodb 前段时间我个人Google服务器意外不能用,并且我犯了一件很低级的错误,直接在gcp讲服 ...

  5. 生产上数据库大量的latch free 导致的CPU资源耗尽的问题的解决

    中午的时候,我们生产上的某个数据库,cpu一直居高不下 通过例如以下的sql语句,我们查看当时数据库的等待,争用的情况: select s.SID, s.SERIAL#, 'kill -9 ' || ...

  6. SpringCloud+Eureka+Feign+Ribbon的简化搭建流程,加入熔断,网关和Redis缓存[2]

    目录 前提:本篇是基于 SpringCloud+Eureka+Feign+Ribbon的简化搭建流程和CRUD练习[1] 的修改与拓展 1.修改consumer的CenterFeign.java,把返 ...

  7. SpringCloud的服务消费者 (二):(rest+feign/ribbon)声明式访问注册的微服务

    采用Ribbon或Feign方式访问注册到EurekaServer中的微服务.1.Ribbon实现了客户端负载均衡,Feign底层调用Ribbon2.注册在EurekaServer中的微服务api,不 ...

  8. Linux(2)---记录一次线上服务 CPU 100%的排查过程

    Linux(2)---记录一次线上服务 CPU 100%的排查过程 当时产生CPU飙升接近100%的原因是因为项目中的websocket时时断开又重连导致CPU飙升接近100% .如何排查的呢 是通过 ...

  9. 记录一次线上bug

    记录一次线上bug,总的来说就是弱网和重复点击.特殊值校验的问题. 测试场景一:        在3g网络或者使页面加载速度需要两秒左右的时候,输入学号,提交学生的缴费项目,提交完一个 学生的缴费后, ...

随机推荐

  1. (三)String、StringBuilder、StringBuffer在字符串操作中的性能差异浅析

    参考资料:https://www.iteye.com/blog/hank4ever-581463 <Core Java Volume I-Fundamentals>原书第十版 <Ja ...

  2. 人脸检测数据源制作与基于caffe构架的ALEXNET神经网络训练

    本篇文章主要记录的是人脸检测数据源制作与ALEXNET网络训练实现检测到人脸(基于caffe). 1.数据获取 数据获取: ① benchmark是一个行业的基准(数据库.论文.源码.结果),例如WI ...

  3. .NET MVC & Web API Cors让AJAX 实现跨域

    什么是Cors? CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing).它允许浏览器向跨源服务器,发出XMLHttpReq ...

  4. 树莓派 3/4 安装 FreeBSD

    已盼春来归 已盼春来归 今日去 愿为春来归 盼归春天来了 FreeBSD 的春天在哪里? 树莓派是什么,相信凡是关注了我们的人都不会不知道,但是介于非专业人员需要在此做简要介绍.我们的安卓手机,大部分 ...

  5. LNMP配置——Nginx配置 ——域名重定向

    一.配置 #vi /usr/local/nginx/conf/vhost/test.com.conf 写入: server { listen 80; server_name test.com test ...

  6. 记录Java注解在JavaWeb中的一个应用实例

    概述 在学习注解的时候,学了个懵懵懂懂.学了JavaWeb之后,在做Demo项目的过程中,借助注解和反射实现了对页面按钮的权限控制,对于注解才算咂摸出了点味儿来. 需求 以"角色列表&quo ...

  7. 【LeetCode】2020-03 每日一题

    121. 买卖股票的最佳时机(简单) [分类]:模拟.思维 [题解]:可以用O(n)的复杂度完成,只需要在遍历的时候记录到当前位置为止买入股票的最小价格minn,再维护一个当前卖出股票价(a-minn ...

  8. fork、exec 和 exit 对 IPC 对象的影响

    GitHub: https://github.com/storagezhang Emai: debugzhang@163.com 华为云社区: https://bbs.huaweicloud.com/ ...

  9. ACNet:用于图像超分的非对称卷积网络

    编辑:Happy 首发:AIWalker Paper:https://arxiv.org/abs/2103.13634 Code:https://github.com/hellloxiaotian/A ...

  10. mvel 配合正则表达式实现文本替换

    mvel 依赖 <dependency> <groupId>org.mvel</groupId> <artifactId>mvel2</artif ...