第5章 微服務之間如何交互


在第3章講解Eureka時,我們提到了Eureka會保存各個服務的元數據,元數據中包含了各個服務的地址等信息。那么服務之間到底是怎樣通過這些信息進行交互的呢?

Spring Cloud服務間的調用默認支持兩種方式:Ribbon和Feign,具體來說就是使用RestTemplate和FeignClient來調用。不管使用什么方式,本質上都是通過REST接口調用服務的HTTP接口,參數和結果默認都是通過jackson序列化和反序列化的。

前面我們已經創建了customer微服務,這里我們再新建一個order微服務。使用兩個服務來進行服務間調用的學習。

order微服務的端口號設置為8002。order微服務的pom.xml引入了如下包:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

其中spring-cloud-starter-netflix-ribbon 引入了Ribbon支持。

為了使用Ribbon訪問customer服務的接口,我們在order的啟動類中加入了如下代碼,加載RestTemplate。

@Bean
@LoadBalanced
public RestTemplate restTemplate(){
    return new RestTemplate();
}

注意:這里使用的注解@Loadbalanced是用來開啟Ribbon負載均衡的。如果沒有添加此注解,那么得到的restTemplate就不具備Ribbon的負載均衡功能,也不會識別微服務的實例名,只能當作傳統的http訪問工具類來使用。

編寫測試controller。

@RestController
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/users/{userId}")
    public String getUserInfo(@PathVariable Long userId) {
        System.out.printf("這里要使用Ribbon來遠程調用customer服務獲取用戶信息");
        String userInfoStr = restTemplate.getForObject("http://customer/users/" +
                userId, String.class);
        return userInfoStr;
    }

}

通過這樣,就可以訪問customer服務中的接口,customer中的接口代碼如下:

@GetMapping("/users/{userId}")
public String getUserInfoByUserId(@PathVariable Long userId){
    return "userInfo with userId = " + userId;
}

在瀏覽器中訪問http://localhost:8002/users/1001,可以得到如5.1的結果。

27ec2c0cc65c44b7698ef39807d56c2e.png
圖5.1 Ribbon方式

 

通過上面的例子,我們通過RestTemplate在order和customer之間進行了服務間的http請求,內部請求過程中使用了http://customer/users/這個地址,並沒有涉及到域名端口之類的東西。這里的customer就是我們之前提到的實例名。也就是這個服務在整個系統中的唯一名稱。

5.1 Ribbon

Ribbon是Netflix發布的負載均衡器,它有助於控制HTTP和TCP的客戶端的行為。為Ribbon配置服務提供者地址后,Ribbon就可基於某種負載均衡算法,自動地幫助服務消費者去請求。Ribbon默認為我們提供了很多負載均衡算法,例如輪詢、隨機等。當然,我們也可為Ribbon實現自定義的負載均衡算法。

在Spring Cloud中,Ribbon可自動從Eureka Server獲取服務提供者地址列表,並基於負載均衡算法,請求其中一個服務提供者實例。在本章剛開始,我們新建的order服務使用RestTemplate調用customer接口的實例就是使用了帶有Ribbon功能的RestTemplate。

RestTemplate提供了若干方便我們使用的工具方法,通過這些方法可以很方便地實現網絡訪問/服務間調用。

接下來我們介紹幾個常見的方法。

  • delete():在特定的URL上對資源執行HTTP DELETE操作。
  • getForEntity():發送一個HTTP

    GET請求,返回的ResponseEntity包含了響應體所映射成的對象。
    
  • getForObject():發送一個HTTP GET請求,返回的請求體將映射為一個自定義對象。
  • postForEntity():POST

    數據到一個URL,返回包含一個對象的ResponseEntity,這個對象是從響應體中映射得到的。
    
  • postForObject():POST 數據到一個URL,返回根據響應體匹配形成的對象。
  • headForHeaders():發送HTTP HEAD請求,返回包含特定資源URL的HTTP頭。
  • optionsForAllow():發送HTTP OPTIONS請求,返回對特定URL的Allow頭信息。
  • postForLocation():POST 數據到一個URL,返回新創建資源的URL。
  • put():PUT 資源到特定的URL。
  • execute():在URL上執行特定的HTTP方法,返回一個從響應體映射得到的對象。
  • exchange():在URL上執行特定的HTTP方法,返回包含對象的ResponseEntity,這個對象是從響應體中。

5.2 Feign

Feign 是一個聲明web服務客戶端,它使編寫web服務客戶端更容易,使用Feign
創建一個接口並對它進行注解,它具有可插拔的注解支持包括Feign注解與JAX-RS注解,Feign還支持可插拔的編碼器與解碼器,Spring
Cloud 增加了對 Spring MVC的注解,Spring Web 默認使用了HttpMessageConverters,
Spring Cloud 集成 Ribbon 和 Eureka 提供的負載均衡的HTTP客戶端 Feign。

為order服務添加feign支持。

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

為啟動類添加注解@EnableFeignClients,開啟Feign掃描。

新建service接口類,代碼如下:

@FeignClient("customer")
public interface UserService {

    @GetMapping("/users/{userId}")
    String getUserInfoByUserId(@PathVariable Long userId);

}

在UserController中添加接口方法。

@GetMapping("/feign/users/{userId}")
public String getUserInfoWithFeign(@PathVariable Long userId){

    System.out.printf("這里要使用Feign來遠程調用customer服務獲取用戶信息");
    String userInfoStr = userService.getUserInfoByUserId(userId);
    return userInfoStr;

}

啟動order服務,瀏覽器訪問http://localhost:8002/feign/users/100112。得到如圖5.2的結果。

6e3f4c20d3e2479bd0275bbf300fda51.png
圖5.2 feign方式

 

5.3 小結

本章主要了解了如何使用Ribbon和Feign通過Eureka的實例來進行服務間的接口調用。到本文為止,我們已經可以構建一些簡單的微服務,並可以讓它們注冊到同一個注冊中心,連接到同一個配置中心,並且可以在不需要url的情況下進行服務間交互。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM