1. 程式人生 > >SpringCloud從入門到進階(七)——踩坑實戰之Zuul服務呼叫失敗與檔案上傳問題

SpringCloud從入門到進階(七)——踩坑實戰之Zuul服務呼叫失敗與檔案上傳問題

內容

  上一節搭建了具有服務熔斷、負載均衡的微服務架構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問題:

1542179340123

  中文檔名亂碼問題:

1542192066226[6]

解讀官方文件

  上述錯誤在直接呼叫微服務的時候是沒有的。是在引入路由Zuul轉發請求之後引入了這些潛在的問題。帶著問題,我們在官方文件中找一找,看看有沒有相1542192066226關的說明。

  官方文件的Zuul這一章中的"Uploading Files through Zuul"一節講到,“如果使用Zuul進行檔案的上傳,只允許很小的檔案上傳成功。如果想上傳大檔案,一種可選的方式為在請求的url中路徑前加上"/zuul",這樣可以繞過Zuul的攔截”。那麼我們使用http://172.26.125.20:7081/zuul/v1/routea/test/upload介面再次測試上傳大檔案和中文名稱檔案。

大檔案

1542199216570

中文名稱檔案

1542199161954

  由此可見,在請求的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的配置儘可能簡單。