feign异常feign.RetryableException & NoHttpResponseException
系统总是出现feign.RetryableException,需要找到原因并解决,虽然问题不大,但是一直有这个异常日志。
项目采用的是spring-cloud-starter-openfeign自动注入、apache httpclient做连接池。并没有对配置做相关优化,采用默认配置。
feign.RetryableException定位
通过异常栈定位到问题出在feign.SynchronousMethodHandler#invoke内调用executeAndDecode。执行请求出现异常后抛出。
1 | public Object invoke(Object[] argv) throws Throwable { |
默认情况下feign配置重试机制使用的是feign.Retryer.Default,默认重试5次。
在使用了SpringBoot自动配置后,在org.springframework.cloud.openfeign.FeignClientsConfiguration#feignRetryer可以看到默认使用的是feign.Retryer#NEVER_RETRY,里面是不做重试直接抛出异常。那就可以看到为什么请求失败会出现feign.RetryableException。
NoHttpResponseException 定位
在上面feign异常栈的后面可以看到NoHttpResponseException异常,通过异常栈可以看到代码org.apache.http.impl.conn.DefaultHttpResponseParser#parseHead处抛出的异常,是读取返回时出错抛出。
从stackoverflow Apache HttpClient Interim Error: NoHttpResponseException里面可以看到,根本原因是因为使用了过期连接导致。
解决办法:
- 官方建议定时清理过期连接。
- 设置自定义重试次数。
- 使用okhttp替换
apache httpclient。
使用
okhttp添加配置feign.httpclient.enabled=false,避免第三方依赖了feign-httpclient,如果确认没有依赖可以不需要
添加feign.okhttp.enabled=true启动okhttp