摘要: 今天在生产环境发生了数据库进程卡死的现象,除了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. Python 时间推进器-->在当前时间的基础上推前n天 | CST时间转化标准日期格式

    由于公司任务紧迫,好久没有在园子里写自己的心得了,今天偷个闲发表点简单的代码块,在开源的时代贡献微薄力量.话不多说,直接上代码块: ]) m = ]) d = ]) the_date = dateti ...

  2. DBGrid相关技术整理

    DBGrid相关技术整理: 注:对于DBGrid相关属性.方法的学习融入到技术整理过程中 一,多选 设置属性: Options->dgMultiSelect = True; ->dgRow ...

  3. Activiti5工作流笔记四

    排他网关(ExclusiveGateWay) 流程图 部署流程定义+启动流程实例 查询我的个人任务 完成我的个人任务 并行网关(parallelGateWay) 流程图 部署流程定义+启动流程实例 查 ...

  4. 【bzoj4401】块的计数 结论题

    题目描述 给出一棵n个点的树,求有多少个si使得整棵树可以分为n/si个连通块. 输入 第一行一个正整数N,表示这棵树的结点总数,接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相 ...

  5. IO模式

    二 IO模式 刚才说了,对于一次IO访问(以read举例),数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间.所以说,当一个read操作发生时,它会经历两 ...

  6. javascript标准对象与包装对象

    javascript标准对象与包装对象 标准对象 在JavaScript的世界里,一切都是对象. 但是某些对象还是和其他对象不太一样.为了区分对象的类型,我们用typeof操作符获取对象的类型,它总是 ...

  7. [洛谷P4717]【模板】快速沃尔什变换

    题目大意:给定多项式$A$和$B$,求$C$满足: $$C_n=\sum\limits_{x\oplus y=n}A_xB_y$$ 其中$\oplus$为位运算($or,and,xor​$) 题解:$ ...

  8. [洛谷P5068][Ynoi2015]我回来了

    题目大意:给你一张$n(n\leqslant10^3)$个点$m(m\leqslant10^5)$个点的无向无权图,多组询问,每次询问给你一些二元组$(x_i,y_i)$,求有多少个$u$于至少一个二 ...

  9. POJ1422:Air Raid——题解

    http://poj.org/problem?id=1422 题目大意:n个点m条有向边,每条边只能走一次,往点上放人让他们走遍所有边,问至少要多少人. —————————————————————— ...

  10. BZOJ2226 & SPOJ5971:LCMSum——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2226 题目大意:给定一个n,求lcm(1,n)+lcm(2,n)+……+lcm(n,n). ———— ...