上一節我們使用了Ribbon(基於 )進行微服務的調用,Ribbon的調用比較簡單,通過Ribbon組件對請求的服務進行攔截,通過 獲取到服務實例的 ,然後再去調用API。本節課我們使用更簡單的方式來實現,使用聲明式的 服務客戶端 ,我們只需要使用Feign來聲明介面,利用 來進行配置就可以使用了, ...
上一節我們使用了Ribbon(基於Http/Tcp
)進行微服務的調用,Ribbon的調用比較簡單,通過Ribbon組件對請求的服務進行攔截,通過Eureka Server
獲取到服務實例的IP:Port
,然後再去調用API。本節課我們使用更簡單的方式來實現,使用聲明式的Web
服務客戶端Feign
,我們只需要使用Feign來聲明介面,利用註解
來進行配置就可以使用了,是不是很簡單?實際工作中,我們也只會用到Feign來進行服務之間的調用(大多數)。接下來,我們來實例操作一把。
為了代碼的重用性,我們來創建一個新的project mscx-ad-feign-sdk
作為Feign的服務調用工具。
- 創建項目
mscx-ad-feign-sdk
- 三部曲之Step 1(加依賴)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mscx-ad</artifactId>
<groupId>com.sxzhongf</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<name>mscx-ad-feign-sdk</name>
<description>只定義微服務Feign調用用到的請求對象和響應對象,而不涉及具體的實現類。</description>
<groupId>com.sxzhongf</groupId>
<artifactId>mscx-ad-feign-sdk</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 引入服務調用的組件 feign 依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.sxzhongf</groupId>
<artifactId>mscx-ad-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- 引入系統容錯hystrix 的依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.2.7.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 三部曲之Step 2(加註解
@EnableFeignClients
,添加在具體的微服務中,使用我們自定義的FeignClient)
/**
* ISponsorFeignClient for service using
*
* @author <a href="mailto:[email protected]">Isaac.Zhang | 若初</a>
*/
@FeignClient(value = "mscx-ad-sponsor", fallback = SponsorClientHystrix.class)
public interface ISponsorFeignClient {
@RequestMapping(value = "/ad-sponsor/plan/get", method = RequestMethod.POST)
CommonResponse<List<AdPlanVO>> getAdPlansUseFeign(@RequestBody AdPlanGetRequestVO requestVO);
@RequestMapping(value = "/ad-sponsor/user/get", method = RequestMethod.GET)
/**
* Feign 埋坑之 如果是Get請求,必須在所有參數前添加{@link RequestParam},不能使用{@link Param}
* 會被自動轉發為POST請求。
*/
CommonResponse getUsers(@RequestParam(value = "username") String username);
}
---
@RestController
@Slf4j
@RequestMapping(path = "/search-feign")
public class SearchFeignController {
/**
* 註入我們自定義的FeignClient
*/
private final ISponsorFeignClient sponsorFeignClient;
@Autowired
public SearchFeignController(ISponsorFeignClient sponsorFeignClient) {
this.sponsorFeignClient = sponsorFeignClient;
}
@GetMapping(path = "/user/get")
public CommonResponse getUsers(@Param(value = "username") String username) {
log.info("ad-search::getUsersFeign -> {}", JSON.toJSONString(username));
CommonResponse commonResponse = sponsorFeignClient.getUsers(username);
return commonResponse;
}
}
- 三部曲之Step 3(加配置,工具類庫不需要,添加在具體的微服務中)
我們上面的實例中有一個問題,如果說我們的廣告提供服務出現了問題,那麼我們通過使用FeignClient 調用的APIsponsorFeignClient.getUsers(username);
就會報錯,如果長時間報錯,會引起大規模的服務錯誤問題,也就有是我們常說的服務雪崩效應,我們要怎樣避免一個服務出錯而拖垮整個系統的問題呢?這裡我們需要引入一個組件Hystrix
來處理服務錯誤。
- 三部曲之Step1(加依賴)
從上圖我們可以看到,我們引入Feign依賴的時候,它本身已經依賴了Hystrix,根據Maven依賴的傳遞性,我們可以知道我們自己的服務已經包含了Hystrix的依賴支持,我們可以直接使用了~
- 三部曲之Step2(加註解)
@EnableHystrix // 開啟hystrix 斷路器
- 三部曲之Step3(改配置)
feign:
hystrix:
enabled: true
- 使用Hystrix來配置Feign實現調用容錯
@Component
public class SponsorClientHystrix implements ISponsorFeignClient {
@Override
public CommonResponse<List<AdPlanVO>> getAdPlansUseFeign(AdPlanGetRequestVO requestVO) {
return new CommonResponse<>(-1, "mscx-ad-sponsor feign & hystrix get plan error.");
}
@Override
public CommonResponse getUsers(String username) {
return new CommonResponse<>(-1, "mscx-ad-sponsor feign & hystrix get user error.");
}
}
在ISponsorFeignClient
類中,添加出錯處理類(fallback)
@FeignClient(value = "mscx-ad-sponsor", fallback = SponsorClientHystrix.class)
public interface ISponsorFeignClient {
...
在SponsorClientHystrix
中,我們要特別註意2點
- 該類必須添加
@Component
註解,以便可以加入Spring 容器中 - 該類需要實現
ISponsorFeignClient
Feign的客戶端介面
通過上面的實現,我們的服務在調用過程中,如果發生錯誤,就會進行服務降級,調用到出錯應該調用的預設處理類中的方法,也就實現了我們想要做的短路處理來保護我們的當前服務。