Eureka的微服務之間呼叫

wp136470發表於2019-12-25

前言

上篇《SpringCloud搭建Eureka》,搭建完了之後,我們還未進行使用,現在讓我們繼續,這篇的內容便為如何進行各個微服務之間的呼叫。

問題:我們如何進行呼叫?

Eureka服務呼叫底層基於Http進行通訊,它提供了RestTemplate使用;假設我們現在有兩個EurekaClient,一個是提供者,一個是消費者。我們現在需要消費者消費提供者的API,如何做到呢?

建立提供者的微服務,這個過程就不明說了,因為之前已經搭建過了。

現在我們有一個ProviderController類,API我們可以隨便寫著進行測試。

@RestController
@RequestMapping("api")
public class ProviderController {

    @PostMapping("getPrice")
    public String getPrice(@RequestBody String name) {
        return name + "訪問price,price為100.";
    }

}

提供一個api/getPrice的API。

建立消費者的微服務,同理;

需要注意的是,首先,這兩個都是屬於EurekaClient,註冊中心只有一個,上篇已經搭建好的EurekaServer。第二個,啟動不同的微服務請設定不同的埠名,否則,啟動報錯;

兩個Client就已經搭建好了,接下來我們使用RestTemplate。消費者因為需要消費提供者的API,所以,便於簡單,我們直接再消費者的啟動類增加RestTemplate。

@SpringBootApplication
@EnableEurekaClient
public class DemoApplication {

    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

這裡的配置,其實我是有疑問的,為什麼一定需要加@LoadBalanced,這個註解意思便是負載均衡,所以我們需要引入Ribbon的依賴包;

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

我的疑問後面再說。接下來消費提供者的API,使用RestTemplate。

@RestController
@RequestMapping("consume")
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @PostMapping("api")
    public String getPrice() {
        return restTemplate.postForEntity("http://eurekaClientTest1/api/getPrice", "eurekaClientTest2", String.class).getBody();
    }
}

配置好了之後,將三個服務都啟動。請先把Server的服務啟動。

這個時候,我們可以訪問Server的連線檢視是否有服務註冊過來。

你可以設定IP,也可以使用ApplicationName,上篇也提過;

這個時候我使用的時postman去訪問我們消費者的API去消費提供者的API。

就這樣,兩個服務之間的呼叫很簡單的實現了。

總結一下:

1,使用RestTemplate的時候,如果我們使用的是IP+埠,RestTemplate會根據真實的地址呼叫。我們無需增加註解@LoadBalanced。

2,使用RestTemplate的時候,如果我們使用的是虛擬地址,比如服務名稱,那麼我們需要將服務名稱解析到真實的地址才能呼叫正常,這個時候增加Ribbon,增加註解@LoadBalanced,會幫我們將服務名稱解析。

然後我跑了下程式碼,首先我們先不增加@LoadBalanced,啟動之後呼叫,

這是我們URL;ok,呼叫doExecute方法:

注意紅框,這個是建立一個request的請求,我們繼續往裡看的話,發現RequestFactory()預設生成的為SimpleBufferingClientHttpRequest。再往下走,呼叫executeInternal方法,這個時候我們發現接下來呼叫的是

SimpleBufferingClientHttpRequest這個類中executeInternal方法

這個類簡單來看就是建立連線,而我們的URL是服務名稱,這裡便識別不了。那我們既然都是Client了,也註冊了,按道理來說就應該會識別服務名稱。

接下來,我們增加@LoadBalanced重新跑,這個時候我們發現

我們發現,咦,這裡竟然是使用到RequestFactory()生成的便為InterceptingClientHttpRequestFactory,這個就已經和之前的不一樣了,繼續往下走,看看這個類是做了什麼操作呢?

萬萬沒想到,最後竟然追蹤到了Ribbon中的類RibbonLoadBalancerClient;

我們可以看到,這裡就已經將提供者的真實URL找到了。具體的後續再說,這樣我們就可以通過真實的URL去呼叫了。

接下來,我們需要認識一下Ribbon。

相關文章