天天看點

restTemplate服務調用踩坑

restTemplate 調用服務的不同的方式需要的服務執行個體是不一樣的。

restTemplate 調用服務有以下幾種方式:請求位址直接調用、服務名調用

請求位址直接調用

restTemplate執行個體如果使用@Autowire方式注入,url中直接寫明調用接口具體的IP位址(域名)及端口号

服務名調用

服務名調用也可以分為兩種方式:一種是自行擷取注冊中心的服務清單,根據服務名找到對應的服務執行個體進行調用;第二種方法就是使用@LoadBalanced注解,系統自動根據hostName來擷取對應的服務執行個體,LoadBalancerInterceptor.intercept如下

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
        URI originalUri = request.getURI();
        String serviceName = originalUri.getHost();
        Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
        return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
    }
           

踩坑過程

項目使用了spring boot 2.2.5,spring cloud Finchley.SR2

該項目主要用于調用外部公司的接口,為本公司的其他的系統提供統一的調用外部公司接口的位址。調用外部公司接口時使用請求位址直接調用。項目中我直接使用@Autowire方式注入restTemplate執行個體,此時調用外部公司接口可以正常調用,回調本公司其他服務的接口時通過服務名調用,調用接口失敗,調用時沒有将服務名轉為對應的IP及端口号。

restTemplate執行個體上增加@LoadBalanced注解後,本公司接口調用成功,外部公司接口調用失敗(接口調用時,IP位址也被認為是服務名,到服務清單中去尋找對應的服務執行個體,找不到對應的執行個體報錯了)最終在啟動類裡注入了兩個restTemplate執行個體

錯誤排查的過程中,還遇到了另外一個小問題,版本降低到E版本之後增加了@LoadBalanced注解之後還是無法通過服務名進行調用,發現啟動類上沒有加@EnableDIscoveryClient注解,增加該注解之後通過服務名調用接口成功。網上查詢發現E版本之後無需在啟動類上增加服務發現的相關注解,E版本是否需要加該注解,大家可以自行驗證一下。

菜鳥踩坑中,高手們請自動忽略