使用 feign 上传文件报错:timed-out and no fallback available
有业务的同事反馈,图片上传之后,加载不出来。登录系统后台查看相关记录,图片附件确实未显示。在新标签打开图片链接,图片只显示出来上面一小截,然后就没有然后了。多次刷新也不好使。这个问题之前出现过,之前是调高图片服务器的一个访问配置缓存大小:
location / {
client_body_buffer_size 256k;
...
proxy_buffer_size 256k;
proxy_buffers 4 256k;
...
}
运维做了代理缓存限制,调高一点就可以让更大的图片通过。但是在调整到 1024k 之后,图片还是有访问不到的情况。这时候就不能盲目地调高配置了,因为明显是上传图片过大了。这边就反馈让她做图片压缩处理之后再上传,并确认图片不涉密,所以推荐了一个在线的压缩工具:tinypng.com。
过了两天,她又反馈压缩后的图片上传不了,截图说明报错信息:
运行时异常:Read timed out executing GET xxx/uploadImage
因为刚接触这个 feign 服务,对于这种调用错误所知甚少。就想确认是否是图片本身的问题,还是接口的问题(其实只要报错了,就不应该纠结,肯定是要去调试找问题的)。
先是在测试站上传正常的图片,发现没有问题。然后跟她要了压缩后的图片上传,确实报错了:
运行时异常:xxxFeign#xxx timed-out and no fallback available.
从上传使用的时间来看,1s 左右就返回了,怎么会 time-out 超时呢?百度这个报错信息,得到了一篇解读:springcloud异常:timed-out and no fallback available,failed and no fallback available的问题解决 - CSDN
这个错误基本是出现在 Hystrix 熔断器,熔断器的作用是判断该服务能不能通,如果通了就不管了,调用在指定时间内超时时,就会通过熔断器进行错误返回。
其中提到了三个配置项:feign
、hystrix
、ribbon
。 其中 feign
是在使用的,其主要是替换 restTemplate
做远程调用,其 interface 接口形式的定义,可以比较方便定义使用。hystrix
文中提到是熔断器,Ribbon 是一个基于HTTP 和 TCP的客户端负载均衡工具(百度)。
测试站配置文件里带的是 feign.hystrix.enabled=true
。测试将其改成 false,并重新部署,测试报错:运行时异常:Read timed out executing GET xxx/uploadImage
。与正式站后台报错一致,都是 Read timed out
。查看正式站服务器配置,确实是关闭了 feign.hystrix.enabled=false
。
尝试修改增加 ribbon
配置:
ribbon.ReadTimeout=60000
ribbon.ConnectTimeout=60000
此时不再报错,图片也成功上传。看时间用了 6.65s,这惊到我了,正常图片(1.7M)上传也只用了 1.6s。她的图片压缩过后只有几百K,怎么会这么长时间呢?跟她要到源文件(都是几M的),然后找了另外一个压缩工具 Caesium Image Compressor,限制说明里有一条 图片永远不会离开您的设备
,从控制台看确实没有上传二进制文件到其他服务器的请求。所以大概率是前端版本的压缩,且压缩率不低(3.48 MB -> 780 kB (-78%))。测试新压缩后的图片上传(去掉 riboon 配置),报错 Read timed out
。所以确认是图片存在问题,导致文件上传服务处理缓慢,进而导致系统这边的超时报错。
但文中也提到了,如果关闭 feign
熔断器并不能解决根本问题。然后就想再试试 feign
熔断器开启状态下如何设置超时时间参数,使其不再报错。
一开始 feign
+ hystrix
组合,超时一开始设置成 5000 报错,设置成 15000 还是报错:运行时异常:xxxFeign#xxx failed and no fallback available.
。也测试过 feign
+ ribbon
依然报错。
最后直接把提到的几个参数都设置了重新部署:
feign:
hystrix:
enabled: true
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 15000
ribbon:
ReadTimeout: 60000
ConnectTimeout: 60000
成功了!另外百度到的一篇 微服务 feign远程调用yml配置,并解决显示服务不可用 timed-out and no fallback 里面整体配置:
# pzy最新升级版 feign配置远程调用超时时间
# 细节请看csdn博客
feign:
hystrix:
enabled: true
client:
config:
default:
connectTimeout: 40000
readTimeout: 40000
#pzy最新升级版 hystrix的超时时间
hystrix:
command:
default:
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 15000
circuitBreaker:
requestVolumeThreshold: 200
sleepWindowInMilliseconds: 5000
errorThresholdPercentage: 50
threadpool:
default:
coreSize: 200
maxQueueSize: 200
queueSizeRejectionThreshold: 160
# pzy最新升级版 feign配置远程调用超时时间
ribbon:
ReadTimeout: 12000
ConnectTimeout: 3000
MaxAutoRetries: 1
MaxAutoRetriesNextServer: 1
OkToRetryOnAllOperations: false
主要还是针对 feign
、hystrix
、ribbon
进行配置,只是多了很多的配置项,测试也是可以的。如果上面的那个简版配置测试还报错,可以试试下面这个。