2016-08-14 25 views
1

下面的指導頁非常好,它可以作爲彈簧啓動應用程序中功能區的基本情況。@LoadBalanced RestTemplate調用嵌套的上下文端點

https://spring.io/guides/gs/client-side-load-balancing/

的示例停止一旦端點映射成爲嵌套的工作 - 例如加入

@RequestMapping(值= 「/歡迎」)在類級

@RestController 
@SpringBootApplication 
@RequestMapping(value = "/welcome") //<------------- ADDED ---> 
public class SayHelloApplication { 

    private static Logger log = LoggerFactory.getLogger(SayHelloApplication.class); 

    @RequestMapping(value = "/greeting") 
    public String greet() { 

,然後改變從

String greeting = this.restTemplate.getForObject("http://say-hello/greeting", String.class); 
客戶機中的@LoadBalanced RestTemplate呼叫

String greeting = this.restTemplate.getForObject("http://say-hello/welcome/greeting", String.class); 

調用與附加堆棧跟蹤失敗,而直接訪問http://localhost:8090/welcome/greeting仍然正常工作。將功能區配置爲將均衡請求加載到長期和嵌套的URL端點(如domain.com/x/y/z/p/q)的適當方式是什麼?

堆棧跟蹤:

java.lang.IllegalStateException: No instances available for say-hello 
    at org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient.execute(RibbonLoadBalancerClient.java:79) ~[spring-cloud-netflix-core-1.1.4.RELEASE.jar:1.1.4.RELEASE] 
    at org.springframework.cloud.client.loadbalancer.LoadBalancerInterceptor.intercept(LoadBalancerInterceptor.java:46) ~[spring-cloud-commons-1.1.1.RELEASE.jar:1.1.1.RELEASE] 
    at org.springframework.http.client.InterceptingClientHttpRequest$InterceptingRequestExecution.execute(InterceptingClientHttpRequest.java:85) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.http.client.InterceptingClientHttpRequest.executeInternal(InterceptingClientHttpRequest.java:69) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:596) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at org.springframework.web.client.RestTemplate.getForObject(RestTemplate.java:264) ~[spring-web-4.2.6.RELEASE.jar:4.2.6.RELEASE] 
    at hello.UserApplication.hi(UserApplication.java:31) ~[classes/:na] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_45] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_45] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_45] 
    at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_45] 
+1

功能區僅處理主機名。你的錯誤表示功能區找不到任何say-hello的實例。你重試了嗎?它可能需要一點。 – spencergibb

+0

請務必檢查Eureka,看看是否有爲say-hello服務註冊的實例。 –

+0

根據庫的示例代碼和給定鏈接say-hello.ribbon.eureka.enabled = false。我只做了問題中指定的更改。它似乎只在給定的URL是http:// say-hello/context(該示例有效)時才處理主機名,而當它是http:// say-hello/context/sub-context /時跟蹤) – nmadzharov

回答

1

的問題是通過添加@RequestMapping的類,你也改變了/處理程序從根移動到/welcome/。爲了使負載平衡器能夠繼續工作,您必須更新在用戶應用的SayHelloConfiguration內使用的PingUrl。做它new PingUrl(false, "/welcome/")

0

我也在使用這個示例應用程序開始使用功能區,這是偉大的。

爲了明確這一點,我想花多一點的話對設計:

  1. 用戶應用,在「/完整/用戶」文件夾,是 「客戶端「應用程序,我們可以通過」curl http:// {host}:8888「訪問它;而說你好應用程序,在 「/ complete/say-hello」文件夾,是「服務提供商」。作爲 由示例指示,我們應該通過旋轉起來3個實例 (東道國):8090(東道國):9092(東道國):9999 - 我們可以檢查出 /完整/用戶/ src目錄/主/資源/應用。yml看看;
  2. 功能區,嵌入在「客戶端」用戶應用程序中,將通過默認的Ping策略維護一系列的負載平衡服務實例(這裏將是3,如果我們旋轉了上述實例),該策略會定期ping服務通過調用特定的URL實例。默認情況下是「/」,因爲我們可以在這裏看到代碼(同樣可以通過指定URI來配置): @Bean public IPing ribbonPing(IClientConfig config) { return new PingUrl(); } 現在,讓我們回到您的問題。

一旦你加入明確的@RequestMapping(value = "/welcome"),映射爲「/」,在

​​

將意味着在「/歡迎」,這是「/歡迎的根路徑改變了SayHelloApplication.java的URI的映射/「,而不是say-hello應用程序的」/「。

然後,我們沒有任何映射爲真正的「/」,例如,「http:// {host}:8090 /'。在這種情況下,Ping將逐一失敗,並且最終功能區會將所有服務實例標記爲不健康,因此最終會出現「No available available for say-hello」。