如何解决springcloud feign 首次调用100%失败的问题


Posted in Java/Android onJune 23, 2021

叙述

在高并发情况下发布应用时,经常会发现监控中有很多超时报错或者断路器打开,下图中可以看到监控情况,测试时也会偶现第一次feign调用出错,第二次就会恢复正常。

如何解决springcloud feign 首次调用100%失败的问题

分析

大家都知道,这里feign底层是集成的ribbon,这里ribbon也会有http连接池,这里的连接池是长连接,定时初始化一批并销毁旧连接,这里还包括一些上下文需要初始化,但是在容器初始化好时,ribbon底层的client是未初始化的,当第一次调用时,有一个初始化过程会导致超时,一般情况下会说需要调整超时时间,但是在电商高并发情况下,这里肯定时不现实的,响应请求都需要ms级别。

解决方案

ribbon饥饿加载

这里可以通过配置ribbon饥饿加载来减少出错次数,如下:

ribbon:
  # 饥饿加载
  eager-load:
    # 是否开启饥饿加载
    enabled: true
    # 饥饿加载的服务
    clients: demo-goods,demo-product

这里为什么说不能完全解决呢?因为在发布时流量切换的瞬间,流量太大,并不是仅仅ribbon需要初始化,hystrix、web容器线程池等都需要初始化或者扩容,这里也需要耗时,所以这里的饥饿加载仅仅只是做到了发布时减少错误数。

zuul饥饿加载

网关作为对外请求的入口,zuul内部使用Ribbon调用其他服务,Spring Cloud默认在第一次调用时懒加载Ribbon客户端。zuul同样需要维护一个相对的子应用环境的上下文,所以也需要启动时饥饿加载。

zuul:
  ribbon:
    eager-load:
      enabled: true

springcloud 中Feign调用常见问题

注: 本文基于Springcloud Edgware版本

一、Feign调用首次失败问题

1、Feign简介:

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解,Feign 整合了Ribbon。

2、原因分析:

Feign整合Hystrix组件后,Hystrix默认的超时时间是1秒,如果超过这个时间尚未响应,将会进入自定义的fallback代码,往往首次请求会比较慢(由于Ribbon是懒加载的,在首次请求时,才会开始初始化相关类),这个响应时间可能就大于1秒了,出现调用失败

3、解决方案

(1)增加Hystrix的超时时间,默认为1s

hystrix:
  command:
    default:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds:  10000

(2)配置饿加载(推荐使用)

ribbon:
  eager-load:
    clients:  project1,project2
    enabled:  true

(3)禁用Hystrix超时(不推荐使用)

hystrix:
  command:
    default:
      execution:
        timeout:
          enabled:  false

(4)为fegin全局禁用hystrix(此种方式较为极端,不建议使用)

feign:
 hystrix:
  enabled: false

二、Feign整合Hystrix之后日志显示问题

1、解决方案

Feign整合Hystrix之后,当调用失败会走fallback逻辑,造成日志不显示,往往我们需要看日志分析原因,进行故障排查。

(1)在application中配置,开区Feign对Hystrix的支持

feign:
  hystrix:
    enabled: true

(2)编写Feigin的客户端以及回滚类

在客户端FeignClient注解配置相对应的回滚类,fallbackFactory = LogFallbackFactory.class,name属性为注册中心其他服务的名称

/**
 * @description:fegin调用客户端
 *
 * @author: LUOYUAN
 * @date: 2019-08-07-10:33
 * @function:
 */
@FeignClient(name = "eureka-log",path = "/api/log",fallbackFactory = LogFallbackFactory.class)
public interface LogFeignClient {
    
    @RequestMapping(value = "list", method = RequestMethod.GET)
    public String logList();
}
/**
 * @description:feign调用失败逻辑
 * @author: LUOYUAN
 * @date: 2019-08-07-10:34
 * @function:
 */
@Slf4j
public class LogFallbackFactory implements FallbackFactory<LogFeignClient> {
    @Override
    public LogFeignClient create(Throwable throwable) {

        return new LogFeignClient() {
            @Override
            public String logList() {
                log.info("query log fallback reason was:",throwable);
                return null;
            }
        };
    }
}

调用失败会打印异常信息

query log fallback reason was:
feign.RetryableException: Connection refused: connect executing GET http://eureka-log/api/log/list
at feign.FeignException.errorExecuting(FeignException.java:132)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:113)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:109)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302)
at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298)

三、Feign调用时定义的fallback不生效

Springcloud Dalston之前得到版本,Feign默认已经开启了Hystrix熔断器,从Dalaton版本开始,默认关闭Hystrix支持,需手动开启,在application.yaml中添加如下配置

feign:
  hystrix:
    enabled: true

以上为个人经验,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Java/Android 相关文章推荐
解决Maven项目中 Invalid bound statement 无效的绑定问题
Jun 15 Java/Android
Java各种比较对象的方式的对比总结
Jun 20 Java/Android
gateway网关接口请求的校验方式
Jul 15 Java/Android
SpringRetry重试框架的具体使用
Jul 25 Java/Android
详解Java七大阻塞队列之SynchronousQueue
Sep 04 Java/Android
SpringBoot整合阿里云视频点播的过程详解
Dec 06 Java/Android
Java字符串逆序方法详情
Mar 21 Java/Android
Flutter集成高德地图并添加自定义Maker的实践
Apr 07 Java/Android
零基础学java之方法的定义与调用详解
Apr 10 Java/Android
Android开发之底部导航栏的快速实现
Apr 28 Java/Android
Java实现扫雷游戏详细代码讲解
May 25 Java/Android
tree shaking对打包体积优化及作用
Jul 07 Java/Android
分析设计模式之模板方法Java实现
基于Java的MathML转图片的方法(示例代码)
Jun 23 #Java/Android
springboot如何初始化执行sql语句
Java循环队列与非循环队列的区别总结
Jun 22 #Java/Android
springBoot基于webSocket实现扫码登录
Jun 22 #Java/Android
SpringBoot集成Redis,并自定义对象序列化操作
Java如何实现树的同构?
You might like
常用表单验证类,有了这个,一般的验证就都齐了。
2006/12/06 PHP
php中邮箱地址正则表达式实现与详解
2012/04/24 PHP
PHP header()函数使用详细(301、404等错误设置)
2013/04/17 PHP
PHP+FastCGI+Nginx配置PHP运行环境
2014/08/07 PHP
Laravel 4 初级教程之Pages、表单验证
2014/10/30 PHP
php生成短域名函数
2015/03/23 PHP
原生JS实现Ajax通过GET方式与PHP进行交互操作示例
2018/05/12 PHP
PHP容器类的两种实现方式示例
2019/07/24 PHP
使用composer安装使用thinkphp6.0框架问题【视频教程】
2019/10/01 PHP
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
2007/03/24 Javascript
wap浏览自动跳转到wap页面的js代码
2014/05/17 Javascript
详解如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
2017/06/01 jQuery
Three.js中网格对象MESH的属性与方法详解
2017/09/27 Javascript
使用Dropzone.js上传的示例代码
2017/10/10 Javascript
react-native 圆弧拖动进度条实现的示例代码
2018/04/12 Javascript
vue this.reload 方法 配置
2018/09/12 Javascript
使用Vue.js 和Chart.js制作绚丽多彩的图表
2019/06/15 Javascript
JavaScript实现多层颜色选项卡嵌套
2020/09/21 Javascript
python 将字符串转换成字典dict
2013/03/24 Python
python smtplib模块发送SSL/TLS安全邮件实例
2015/04/08 Python
详解Anconda环境下载python包的教程(图形界面+命令行+pycharm安装)
2019/11/11 Python
Python使用QQ邮箱发送邮件实例与QQ邮箱设置详解
2020/02/18 Python
Django Form设置文本框为readonly操作
2020/07/03 Python
职业技术学校毕业生推荐信
2013/12/03 职场文书
教师的实习自我鉴定
2013/12/17 职场文书
企业为何需要商业计划书
2013/12/26 职场文书
趣味活动策划方案
2014/02/08 职场文书
二手房购房意向书范本
2014/04/01 职场文书
禁止酒驾标语
2014/06/25 职场文书
幼儿园2015年度工作总结
2015/04/01 职场文书
志愿者服务活动总结报告
2015/05/06 职场文书
初中运动会前导词
2015/07/20 职场文书
2016年教师节感恩寄语
2015/12/04 职场文书
《云雀的心愿》教学反思
2016/02/23 职场文书
SpringBoot项目部署到阿里云服务器的实现步骤
2022/06/28 Java/Android
httpclient调用远程接口的方法
2022/08/14 Java/Android