内容
上一节搭建了具有服务熔断、负载均衡的微服务架构1.0 ,但是在通过路由调用微服务时出现了一些直接调用微服务没有的问题,这也是笔者项目中遇到的真实问题。本文查阅了官方文档等资料,介绍该问题的解决方法。
版本
IDE:IDEA 2017.2.2 x64
JDK:1.8.0_171
manve:3.3.3
SpringBoot:1.5.9.RELEASE
SpringCloud:Dalston.SR1
说明
转载请说明出处:SpringCloud从入门到进阶(七)——踩坑实战之Zuul服务调用失败与文件上传问题
服务调用失败问题
在起初部署Zuul做路由时,出现过直接访问微服务正常,但是经过Zuul转发调用微服务时出现服务熔断的问题。经过排查Zuul的日志,发现Zuul已经从Eureka中获取到了微服务实例(application-serviceA)的地址(hostname:8881, hostname:8883, hostname:8882),地址信息是主机名的形式。
2018-10-23 19:09:01.809 INFO 9621 --- [http-nio-7082-exec-1] INFO c.n.loadbalancer.DynamicServerListLoadBalancer -
DynamicServerListLoadBalancer for client #微服务名application-serviceA application-serviceA initialized: DynamicServerListLoadBalancer: {NFLoadBalancer:name=application-serviceA,current list of #微服务的三个实例(主机名的形式) Servers=[hostname:8881, hostname:8883, hostname:8882],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;
Instance count:3; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
解决问题的两个方法
从日志中我们看到路由Zuul已经从Eureka中读取到了“主机名:端口号”形式的微服务实例的地址,那么为什么会Zuul还是无法访问微服务呢?经过排查,该问题是由于笔者没有在Zuul这台主机的hosts文件中配置微服务实例主机的DNS信息造成的。将所有微服务的主机名和内网IP地址的映射添加到路由接入服务器的hosts中即可解决该问题。另外,也可以修改微服务实例的配置文件(preferIpAddress ),使其以ip地址的方式注册到eureka中。
将微服务的IP注册到Eureka中,可以在Zuul的日志中看到如下信息:
2018-11-14 22:34:23.523 INFO [bootstrap,6968de15a96e1c3c,64e6af59a5d186a9,false] 30406 --- [nio-7082-exec-1] c.n.l.DynamicServerListLoadBalancer
: DynamicServerListLoadBalancer for #微服务名application-serviceA client application-serviceA initialized: DynamicServerListLoadBalancer:{NFLoadBalancer:name=application-serviceA,current list of #微服务的三个实例(ip地址的形式) Servers=[172.26.125.115:8882, 172.26.125.115:8883, 172.26.125.115:8881],Load balancer stats=Zone stats: {defaultzone=[Zone:defaultzone;
Instance count:3; Active connections count: 0; Circuit breaker tripped count: 0; Active connections per server: 0.0;]
文件上传问题回顾
在上一节的最后,我们通过路由Zuul调用微服务测试文件上传。在测试过程中,我们发现当上传文件大小超过1MB时,服务会报500错误。并且同时当上传文件名包含中文时,会出现中文乱码的问题。
文件大小超过1MB的500问题:
中文文件名乱码问题:
解读官方文档
上述错误在直接调用微服务的时候是没有的。是在引入路由Zuul转发请求之后引入了这些潜在的问题。带着问题,我们在官方文档中找一找,看看有没有相关的说明。
官方文档的Zuul这一章中的"Uploading Files through Zuul"一节讲到,“如果使用Zuul进行文件的上传,只允许很小的文件上传成功。如果想上传大文件,一种可选的方式为在请求的url中路径前加上"/zuul",这样可以绕过Zuul的拦截”。那么我们使用http://172.26.125.20:7081/zuul/v1/routea/test/upload接口再次测试上传大文件和中文名称文件。
大文件
中文名称文件
由此可见,在请求的url路径前加上"/zuul"的效果,等同于直接访问对应微服务。此外,官方文档中也说明,如果上传太大的文件时,可能请求时间过长,导致Zuul超时熔断服务。针对超时熔断的问题,可以增加如下参数调节Zuul超时的时间阈值:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:
ConnectTimeout: 3000
ReadTimeout: 60000
当然,除了官方文档中给的这些方法,我们也可以在zuul的项目中增加一些配置,解决相应的问题。
比如解决大文件上传的问题,可以增加如下配置限定上传文件体积的阈值:
spring:
http:
multipart:
#上传文件总的最大值为30MB
max-request-size: 30MB
#单个文件的最大值为10MB
max-file-size: 10MB
关于中文乱码问题,找了一些配置,但是都没有解决。对于此类型问题的解决尽量不要画蛇添足,建议按照官方文档进行处理,使Zuul的配置尽可能简单。