服務註冊與發現 | 上手實踐Spring Cloud Eureka 和 Feign(三)

語言: CN / TW / HK

theme: scrolls-light

這是我參與11月更文挑戰的第10天,活動詳情檢視:2021最後一次更文挑戰

承接上一篇文章《上手實踐Spring Cloud Eureka 和 Feign(二)》,上篇文章成功啟動了註冊中心,服務提供方,這篇文章基於Feign發現並消費服務。

三、Feign

這一章節我們從三個方面遞進的講Feign,第一如果沒有Feign,我們將如何呼叫註冊中心的服務;第二Feign是什麼,能為我們帶來哪些便利?第三,如何上手使用Feign。

3.1 如果沒有Feign

為什麼是Feign呢,如果不使用Feign我們該如何呼叫註冊到Eureka上的服務呢?

如果不使用Feign,為了保證正常的服務發現和呼叫,我們必須要做到以下核心幾步: - 第一步,使用Ribbon進行負載均衡 - 第二步,獲取服務的例項,並且獲取根URL,再拼湊方法的URL - 第三步,最後使用 REST 模板或者其它方式來使用指定的服務

對於第一步,使用Ribbon獲取服務例項,大致的程式碼如下。 ```java @Autowired private LoadBalancerClient loadBalancer;

pulic void method(){ ServiceInstance serviceInstance=loadBalancer.choose("producer"); } ``` 對於第二步,大致的程式碼如下:

java pulic void method(){ String baseUrl=serviceInstance.getUri().toString(); baseUrl=baseUrl+"/targetURL"; }

最後對於第三步,執行訪問,並獲取結果,大致的程式碼如下。 java pulic void method(){ RestTemplate restTemplate = new RestTemplate(); ResponseEntity<String> response=null; try{ response=restTemplate.exchange(baseUrl, HttpMethod.GET, getHeaders(),String.class); }catch (Exception ex) { System.out.println(ex); } System.out.println(response.getBody()); } 在整個呼叫過程中,是很複雜的,我們還需要處理一些空異常等等,我們使用Feign可以做到簡化以上的步驟。

image.png

3.2 Feign介紹

Feign旨在簡化HTTP API客戶端,它是一個宣告式Web Service客戶端。Fegin是一個java呼叫HTTP的客戶端binder,其靈感來自於Retrofit、JAXRS-2.0和WebSocket。

使用Feign能讓編寫Web Service客戶端更加簡單, 它的使用方法是定義一個介面,然後在上面添加註解,同時也支援JAX-RS標準的註解,並且Feign也支援可拔插式的編碼器和解碼器。

那麼Feign是如何工作的呢?簡單地說,Feign基於將註解轉換成請求模板的方式工作,引數會簡單直接的應用到模板上。具體原理不做過深的闡述。

像上面提供的未使用Feign的例子,使用Feign後其呼叫鏈圖如下。

image.png

正如Eureka,Spring Cloud也提供了方便使用的OpenFeign Starter,我們將看到如何使用 Netflix Feign 使服務發現和呼叫變得更加容易和整潔。

3.3 上手實踐

在這裡,我們就使用上篇文章介紹提供的服務註冊中心,和服務提供方。
首先新建一個模組,引入相關依賴。 maven <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> 注意,我們因為要去發現Eureka的提供的服務,所以還是要引入Eureka Client的依賴。
接下來提供與服務方呼叫一模一樣的介面GreetingClient。 ```java @FeignClient("spring-cloud-eureka-client") public interface GreetingClient {

@GetMapping("/greeting")
String greeting();

} `` 所以這裡就有一個問題,服務提供方和消費要宣告同樣一套介面,按照最佳工程實踐,建議把這部分介面抽象出來作為單獨Modeling`,然後對應的服務提供方和消費方引入這個包。

接下來是,寫啟動類和Web服務,為了方便,把兩者都寫到啟動類Launcher吧。 ```java @SpringBootApplication @EnableFeignClients @RestController public class Launcher {

@Autowired
private GreetingClient greetingClient;

public static void main(String[] args) {
    SpringApplication.run(Launcher.class,args);
}

@GetMapping("/get-greeting")
public String greeting(){
    return greetingClient.greeting();
}

} `application.yml`配置資訊如下。yml spring: application: name: spring-cloud-eureka-feign-client server: port: 8080 eureka: client: serviceUrl: defaultZone: ${EUREKA_URI:http://localhost:8761/eureka} ``` 然後啟動這個消費服務,觀察Eureka的管理頁面,可以看到這個消費方也註冊到Eureka註冊中心了。

screenshot-127-0-0-1-8761-1636963294276.png

然後訪問http://{yourhost}:8080/get-greeting,即得到hello...的回覆,代表呼叫鏈通暢。

在這個例子中,並沒有引入負載均衡,如果想要做到,引入Ribbon的依賴後,在程式碼呼叫服務的地方,正常去呼叫遠端服務即可。

``` @Autowired private RemoteCallService loadBalancer;

#服務方法中這樣使用去呼叫遠端方法去獲取資料
data tmp = loadBalancer.getData();

```

四、總結

相較而言,這一整篇文章還是比較簡單,上手實踐一點都不難,因為整個系列都是以入門教程為主,讓讀者認識到這些分散式元件為什麼要提供,我們能用它們分別做什麼。服務註冊中心還有很多,比如Zuul、ZK等等,接下來的教程會一一講到,敬請期待!


少年,沒看夠?點選石頭的主頁,隨便點點看看,說不定有驚喜呢?歡迎支援點贊/關注/評論,有你們的支援是我更文最大的動力,多謝啦!