上一節咱們使用了Ribbon(基於Http/Tcp
)進行微服務的調用,Ribbon的調用比較簡單,經過Ribbon組件對請求的服務進行攔截,經過Eureka Server
獲取到服務實例的IP:Port
,而後再去調用API。本節課咱們使用更簡單的方式來實現,使用聲明式的Web
服務客戶端Feign
,咱們只須要使用Feign來聲明接口,利用註解
來進行配置就能夠使用了,是否是很簡單?實際工做中,咱們也只會用到Feign來進行服務之間的調用(大多數)。接下來,咱們來實例操做一把。java
爲了代碼的重用性,咱們來建立一個新的project mscx-ad-feign-sdk
做爲Feign的服務調用工具。web
mscx-ad-feign-sdk
<?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>
@EnableFeignClients
,添加在具體的微服務中,使用咱們自定義的FeignClient)/** * ISponsorFeignClient for service using * * @author <a href="mailto:magicianisaac@gmail.com">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; } }
咱們上面的實例中有一個問題,若是說咱們的廣告提供服務出現了問題,那麼咱們經過使用FeignClient 調用的APIsponsorFeignClient.getUsers(username);
就會報錯,若是長時間報錯,會引發大規模的服務錯誤問題,也就有是咱們常說的服務雪崩效應,咱們要怎樣避免一個服務出錯而拖垮整個系統的問題呢?這裏咱們須要引入一個組件Hystrix
來處理服務錯誤。spring
從上圖咱們能夠看到,咱們引入Feign依賴的時候,它自己已經依賴了Hystrix,根據Maven依賴的傳遞性,咱們能夠知道咱們本身的服務已經包含了Hystrix的依賴支持,咱們能夠直接使用了~apache
@EnableHystrix // 開啓hystrix 斷路器
feign: hystrix: enabled: true
@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)app
@FeignClient(value = "mscx-ad-sponsor", fallback = SponsorClientHystrix.class) public interface ISponsorFeignClient { ...
在SponsorClientHystrix
中,咱們要特別注意2點maven
@Component
註解,以即可以加入Spring 容器中ISponsorFeignClient
Feign的客戶端接口經過上面的實現,咱們的服務在調用過程當中,若是發生錯誤,就會進行服務降級,調用到出錯應該調用的默認處理類中的方法,也就實現了咱們想要作的短路處理來保護咱們的當前服務。ide