Spring Cloud Feign 優雅的服務調用
- 2020 年 3 月 7 日
- 筆記
Fegin 是由NetFlix開發的聲明式、模板化HTTP客戶端,可用於SpringCloud 的服務調用。提供了一套更優雅、便捷的HTTP調用API,並且SpringCloud整合了Fegin、Eureka和Ribbon。使其使用更加簡便。替換了之前使用RestTemplate進行硬編碼方式的服務調用。
Feign組件入門
導入依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
開啟服務
在啟動類上添加 @EnableFeignClients 開啟
@SpringBootApplication @EnableFeignClients public class ServiceConsumerApplication {}
寫服務介面
- 在項目中創建一個文件夾用來管理Fegin的所有介面
- 可以按照服務提供者的名字進行二級分類
- 創建一個介面。這裡我根據服務提供者的名稱創建了一個 UserServiceFeignClient 的介面
- 介面上添加註解 @FeignClient("SERVICE-PROVIDER"),註解的默認值填寫服務提供者的名字
- 複製提供者的Controller方法,注意不要遺漏類名上的地址
package cn.keats.service_consumer.feign; import cn.keats.service_consumer.entity.User; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import java.util.List; /** * @Author: keats_coder * @Date: 2020/3/7 * @Version 1.0 */ @FeignClient("SERVICE-PROVIDER") public interface UserServiceFeignClient { @GetMapping("/api/v1/user/{age}") User getUser(@PathVariable("age") Integer age); /** * 用戶列表 * @return */ @GetMapping("/api/v1/users") List<User> getUsers(); }
調用
在需要調用服務的地方使用 @AutoWired 注入該介面。調用其對應的方法
@Autowired private UserServiceFeignClient userServiceFeignClient; /** * 基於 Feign 的優雅的介面調用方式 */ @GetMapping("teacher/user/{age}") public User getAllUser(@PathVariable Integer age){ return userServiceFeignClient.getUser(age); }
Feign負載均衡
Feign中已經集成了Ribbon的負載均衡功能,默認情況下使用輪詢的規則,若想要自定義可以參考:Ribbon進行服務調用/負載均衡以及請求重試配置
Feign的配置
新版本的Feign支援配置文件配置,常用的配置有日誌級別的配置。開發環境下可以配置成最細膩級別的日誌方便檢查問題
# feign的配置 feign: client: config: SERVICE-PROVIDER: loggerLevel: FULL # NONE(默認選項), BASIC, HEADERS, FULL; 內容依次豐富、性能影響依次增大 logging: level: cn.keats.service_consumer.feign.UserServiceFeignClient: debug
Feign的執行原理
- 在Spring容器啟動時,掃描到 @EnableFeignClients 註解。而該註解又導入了 FeignClientsRegistrar.class 這個類。該類定義了掃描所有添加 @FeignClient 註解的介面
- FeignClientsRegistrar 實現了 Spring ImportBeanDefinitionRegistrar 類,用來導入自定義Bean。其中該方法主要用來導入Bean.
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) { this.registerDefaultConfiguration(metadata, registry); // 註冊配置 this.registerFeignClients(metadata, registry);// 註冊Feign客戶端 }
- 之後通過 registerFeignClient 方法,以動態代理的形式生成介面的實現。讓我們得以調用