摘要: 今天在生产环境发生了数据库进程卡死的现象,除了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这个参数慎用。如果对网络请求性能要求较高,可以在适当位置重写源码。
转自:https://blog.csdn.net/tianyaleixiaowu/article/details/79128879
相关推荐
【Spring Cloud Feign服务使用详解】 在分布式系统中,服务间的通信是至关重要的,Spring Cloud Feign就是一种声明式的服务调用工具,它使得服务之间的调用变得简单且直观。Feign是Netflix开源的一个接口绑定工具,...
"Spring Cloud Feign 深度学习与应用详解" Spring Cloud Feign 是一个声明式的 Web Service 客户端,它的目的就是让 Web Service 调用更加简单。Feign 提供了 HTTP 请求的模板,通过编写简单的接口和插入注解,就...
SpringCloud重试机制配置详解 在微服务架构中,重试机制是非常重要的组件之一,它可以帮助我们处理远程调用过程中的异常和超时问题。在SpringCloud中,我们可以通过不同的方式来配置重试机制,今天我们就来详细地...
- **容错机制**:讲解在微服务架构中常见的容错机制,如重试机制、断路器模式等。 #### 5. 常见问题与解决思路 - **性能优化**:针对微服务架构中可能出现的性能瓶颈提出优化建议。 - **安全性考虑**:讨论如何在...
- **重试机制**:当服务调用失败时,可配置重试次数。 - **灵活配置**:支持多种配置方式,如通过 YAML 文件、属性文件等。 ##### 3. **Feign** Feign 是一个声明式的 HTTP 客户端,它简化了 HTTP 请求的编码。...
### SpringCloud核心知识点详解 #### 一、SpringCloud概述 **SpringCloud** 是一套完整的微服务解决方案,基于 **Spring Boot** 实现,旨在为开发者提供一种简单的方式来构建分布式系统中的服务,包括服务发现、...
3.3 Feign配置:配置Feign的相关参数,如超时时间、重试策略等,以及自定义的解码器和编码器。 总结,SpringCloud通过Eureka实现服务注册与发现,使得服务之间可以动态地找到彼此,而Feign则简化了服务间的通信,...
《SpringCloud微服务基础框架详解》 在当前的IT行业中,微服务架构已经成为了大型分布式系统设计的重要选择,而SpringCloud作为Java领域的微服务治理框架,更是受到了广泛的欢迎。本项目"基础框架代码_springcloud_...
### Spring Cloud 微服务架构详解 #### 一、微服务入门 ##### 1.1 单体架构与分布式架构 在传统的软件开发中,应用程序往往采用单体架构设计,即所有的业务逻辑都封装在一个单一的应用程序中。这种模式下,虽然...
3. **Ribbon**:客户端负载均衡,提供一系列完整的配置项如连接超时、重试等。简单的说就是,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法。 4. **Feign**:Feign是一个声明式的Web ...
### Spring Cloud 微服务知识点详解 #### Spring Cloud 概述 Spring Cloud 是一套基于 Spring Boot 实现的微服务云应用开发框架。它继承了 Spring Boot 快速开发、自动化配置等特性,并在此基础上添加了一些针对...
### SpringCloud实战知识点详解 #### 一、SpringCloud与微服务架构 - **SpringCloud**:SpringCloud 是一套用于构建微服务架构的工具集,它提供了开箱即用的微服务解决方案,使得开发者能够轻松地构建分布式系统中...
当服务调用失败次数超过预设值时,Hystrix会触发熔断机制,直接返回一个预设的回退响应(Fallback),而不是继续重试失败的服务,从而防止级联故障的发生。Hystrix还允许开发者配置回退逻辑,以返回静态数据、其他...
### SpringCloud最新面试题知识点详解 #### 1. SpringBoot执行器的作用 - **定义**:SpringBoot执行器提供了一套RESTful Web服务接口,用于访问正在运行的应用程序的当前状态。 - **功能**: - **应用状态检查**...
- `retry_join`参数: 指定其他节点尝试加入集群时的重试机制。 3. **数据同步**: - Consul集群中的所有Server节点会通过Raft一致性算法来保持数据的一致性。 4. **故障恢复**: - 当集群中某节点发生故障时,...
这里的"webservice"标签表明项目涉及到了Web服务,可能是通过SpringBoot的Web服务客户端库,例如Spring-WS或Spring-Cloud-Feign等。 【内容详解】 1. **SpringBoot基础**:首先,你需要了解SpringBoot的基本概念和...