摘要: 今天在生产环境发生了数据库进程卡死的现象,除了sql因为全量更新,没加索引的原因,最主要还是我们的接口的服务器端接口出现问题了。忽视了更新接口的幂等性,以及调用方feign client的重试,导致接口重复执行。万幸的是数据已经修复,花了几个小时跟踪feign和ribbon的源码,把其原理彻底搞明白了。

feign是netflix提供的服务间基于http的rpc调用框架,在spring cloud得到广泛应用。默认情况下,一个feign client是在hystrix断路器中执行,并利用ribbon进行软负载选择远程target service,所以可以想象出一个feign client的层次架构是包裹的层次,hystrix控制整个rpc从调用到方法返回,而ribbon控制从选址到socket返回,关于它们的超时设置,请参考我上一篇博客:SpringCloud重试机制配置

今天先不讨论hystrix,仅从feign在spring cloud中应用容易踩到坑和从源码debug的角度看执行过程。我们先来填坑,看看这个配置:

这是ribbon在github wiki上的给我们的默认配置,OKToRetryOnAllOperations的意义是无论是请求超时或者socket read timeout都进行重试,

这个OKToRetryOnAllOperations=true我建议改成false或者不设,为什么?我们直接上源码分析:

这是feign初始化它的ribbon重试控制器,它的逻辑是如果设置了OKToRetryOnAllOperations这个参数为true,第一个if的构造函数就设置为true,这就比较危险了,如果接口是post或者put请求,这是进行修改操作,如果服务器长时间不返回,客户端发生socket read timeout会进行重试,如果服务器接口没做幂等性,这个后果自己想想。继续看后面两个判断,得出的结论是:如果是Get请求设置为OKToRetryOnAllOperations=true不影响,因为只涉及到读操作,如果是其他http方法,默认只会在socket还没建立连接时进行重试,比如突然网络抖动或者一台服务实例挂了,这是没问题的,因为只保证了服务器端执行一次(还是建议涉及到修改的接口做好幂等性)。

关于超时再提一下两个配置ribbon.ConnectTimeout和ReadTimeout,根据自己服务调用情况,慎重进行设置,我的建议是ReadTimeout可以稍微设大点(同时注意hystrix线程池超时时间)。

下面我们分析下feign的执行过程和重试机制,下面这个图是我简易画的,这是总体概览

1、一个feign请求开始,通过动态代理的方式包裹了一层feign retryer逻辑,控制最外层的feign自身的重试机制:

2、continueOrPropagate是控制是否重试和跳出上层死循环的最终出口:

3、必要的ribbon设置,并调用真实执行逻辑

4、在AbstractLoadBalancerAwareClinet中执行,LoadBalancerCommand中控制ribbon选取server、重试、记录执行状态、封装错误返回,这都是利用RXJava的观察者模式来做的

  • 第一个catch控制ribbon请求的Exception

  • 第二个catch控制整个一轮ribbon重试(ribbon.MaxAutoRetries、ribbon.MaxAutoRetriesNextServer)下来,仍然异常。

  • 回到方法调用入口的catch,进行feign的retryer的逻辑,决定是整体再重试还是直接抛出异常跳出循环(默认是5次重试)

5、默认情况下,在feign.Client.Default的内部类里进行真实的http请求,默认是用Java的网络api(这块可以替换掉自己写,比如使用:netty)

总结下,注意我们的接口请求方式,设置合适的超时时间,OKToRetryOnAllOperations这个参数慎用。如果对网络请求性能要求较高,可以在适当位置重写源码。

SpringCloud Feign重试详解的更多相关文章

  1. SpringCloud Feign使用详解

    添加依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId> ...

  2. springcloud中Feign配置详解

    Spring Cloud中Feign配置详解 到目前为止,小伙伴们对Feign的使用已经掌握的差不多了,我们在前文也提到Feign是对Ribbon和Hystrix的整合,那么在Feign中,我们要如何 ...

  3. SpringCloud及其组件详解

    SpringCloud及其组件详解 1.Spring Cloud 1.1 Spring Cloud和Dubbo的区别图解 1.2 微服务的技术栈 2.Spring Cloud 概述 2.1 Sprin ...

  4. Spring Cloud Feign原理详解

    目录 1.什么是Feign? 2.Open Feign vs Spring Cloud Feign 2.1.OpenFeign 2.2.Spring Cloud Open Feign 3.Spring ...

  5. 原生Feign使用详解

    一,简介 Feign使得 Java HTTP 客户端编写更方便.Feign 灵感来源于Retrofit.JAXRS-2.0和WebSocket.Feign最初是为了降低统一绑定Denominator到 ...

  6. SpringCloud学习系列之二 ----- 服务消费者(Feign)和负载均衡(Ribbon)使用详解

    前言 本篇主要介绍的是SpringCloud中的服务消费者(Feign)和负载均衡(Ribbon)功能的实现以及使用Feign结合Ribbon实现负载均衡. SpringCloud Feign Fei ...

  7. SpringCloud Eureka参数配置项详解

    SpringCloud Eureka参数配置项详解(转) Eureka涉及到的参数配置项数量众多,它的很多功能都是通过参数配置来实现的,了解这些参数的含义有助于我们更好的应用Eureka的各种功能,下 ...

  8. SpringCloud 详解配置刷新的原理 使用jasypt自动加解密后 无法使用 springcloud 中的自动刷新/refresh功能

    之所以会查找这篇文章,是因为要解决这样一个问题: 当我使用了jasypt进行配置文件加解密后,如果再使用refresh 去刷新配置,则自动加解密会失效. 原因分析:刷新不是我之前想象的直接调用conf ...

  9. SpringCloud Feign 之 超时重试次数探究

    SpringCloud Feign 之 超时重试次数探究 上篇文章,我们对Feign的fallback有一个初步的体验,在这里我们回顾一下,Fallback主要是用来解决依赖的服务不可用或者调用服务失 ...

随机推荐

  1. .NET环境下,通过LINQ操作SQLite数据库

    //对应数据库中的某个表 [Table(Name = "main.Student")]    public class Student    {        [Column(Na ...

  2. ipython matplotlib

    matplotlib实际上是一套面向对象的绘图库,它所绘制的图表中的每个绘图元素,例如线条Line2D.文字Text.刻度等在内存中都有一个对象与之对应.为了方便快速绘图matplotlib通过pyp ...

  3. js 复制到剪贴板 兼容还得自己想办法

    clipboard.js https://github.com/zenorocha/clipboard.js/ 主要问题还是ie8, 可以使用ie 特有的方法 if (window.clipboard ...

  4. 操作 使用XML的方法

    XmlHelper是一个工具类 public static class XMLHelper { /// <summary> /// XML的编码方式,默认是UTF-8 /// </s ...

  5. BZOJ 1037 生日聚会(神DP)

    这题的DP很难想,定义dp[i][j][a][b]表示用了i个男生,j个女生,任一连续的后缀区间内,男生比女生最多多a人,女生比男生最多多b人. 转移就是显然了. # include <cstd ...

  6. html页面导入文件 使用include后多出一空白行的解决

    用include引入的footer和header文件都在上面多出一空白行,是Unicode签名(bom)引起的. “标题/编码”,把 包括unicode签名(bom) 的勾取消就好了.

  7. (三)Redis列表List操作

    List全部命令如下: lset key index value # 将列表key下标为index的元素的值设置为value,当 index 参数超出范围,或对一个空列表(key不存在)进行lset时 ...

  8. bzoj3489: A simple rmq problem (主席树)

    //========================== 蒟蒻Macaulish:http://www.cnblogs.com/Macaulish/  转载要声明! //=============== ...

  9. BZOJ1499:[NOI2005]瑰丽华尔兹——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1499 舞厅是一个N行M列的矩阵,矩阵中的某些方格上堆放了一些家具,其他的则是空地.钢琴可以在空地上滑 ...

  10. phalcon安装

    参考网站:https://docs.phalconphp.com/zh/latest/reference/tools.html (中文版)cento6.5环境安装:cd ~mkdir phalconc ...