SpringCloud微服務基礎4:Feign
Spring Cloud Feign是一套基於Netflix Feign實現的宣告式服務呼叫客戶端。它使得編寫Web服務客戶端變得更加簡單。我們只需要通過建立介面並用註解來配置它既可完成對Web服務介面的繫結。它具備可插拔的註解支援,包括Feign註解、JAX-RS註解。它也支援可插拔的編碼器和解碼器。Spring Cloud Feign還擴充套件了對Spring MVC註解的支援,同時還整合了Ribbon和Eureka來提供均衡負載的HTTP客戶端實現。
Feign可以把Rest的請求進行隱藏,偽裝成類似SpringMVC的Controller一樣。你不用再自己拼接url,拼接引數等等操作,一切都交給Feign去做。
【注意】Feign中已經自動集成了Ribbon負載均衡;同時Feign預設也有對Hystix的整合(預設是關閉Hystix)。
1.工程搭建
1.1、消費者工程引入Feign依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1.2、Feign的客戶端@FeignClient
在消費者新增一個介面,該介面可以理解為在消費者中的DAO層,內容如下:
@FeignClient("user-service")
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
(1)首先這是一個介面,Feign會通過動態代理,幫我們生成實現類。這點跟mybatis的mapper很像;
(2)@FeignClient,宣告這是一個Feign客戶端,類似@Mapper註解。同時通過value屬性指定服務名稱;
(3)介面中的定義方法,完全採用SpringMVC的註解,Feign會根據註解幫我們生成URL,並訪問獲取結果;
修改消費者的service層程式碼如下:
@Service
public class UserService {
@Autowired
private UserFeignClient userFeignClient;
public List<User> queryUserByIds(List<Long> ids) {
List<User> users = new ArrayList<>();
ids.forEach(id -> {
// 我們測試多次查詢,
users.add(this.userFeignClient.queryUserById(id));
});
return users;
}
}
1.3、消費者啟動類開啟Feign@EnableFeignClients
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients // 開啟Feign功能
public class UserConsumerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}
發現RestTemplate的註冊被我刪除了。Feign中已經自動集成了Ribbon負載均衡,因此我們不需要自己定義RestTemplate了。
2.Feign中Hystix支援
Feign預設也有對Hystix的整合;只不過,預設情況下是關閉的。我們需要修改application.yml的引數來開啟:
feign:
hystrix:
enabled: true # 開啟Feign的熔斷功能
但是,Feign中的Fallback配置不像Ribbon中那樣簡單了;需要我們對消費者進行改造。操作步驟如下:
(1)第一步:首先,我們要定義一個類,實現剛才編寫的UserFeignClient,作為fallback的處理類;程式碼如下:
@Component
public class UserFeignClientFallback implements UserFeignClient {
@Override
public User queryUserById(Long id) {
User user = new User();
user.setId(id);
user.setName("使用者查詢出現異常!");
return user;
}
}
(2)第二步:然後在UserFeignClient中,指定剛才編寫的實現類;程式碼如下:
@FeignClient(value = "user-service", fallback = UserFeignClientFallback.class)
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
3.Feign中請求壓縮及日誌級別
3.1、feign請求壓縮
Spring Cloud Feign 支援對請求和響應進行GZIP壓縮,以減少通訊過程中的效能損耗。通過下面的引數即可開啟請求與響應的壓縮功能:
feign:
compression:
request:
enabled: true # 開啟請求壓縮
response:
enabled: true # 開啟響應壓縮
同時,我們也可以對請求的資料型別,以及觸發壓縮的大小下限進行設定:
feign:
compression:
request:
enabled: true # 開啟請求壓縮
mime-types: text/html,application/xml,application/json # 設定壓縮的資料型別
min-request-size: 2048 # 設定觸發壓縮的大小下限
3.2、feign日誌級別
我們可以通過logging.level.xx=debug來設定日誌級別。然而這個對Fegin客戶端而言不會產生效果。因為@FeignClient註解修改的客戶端在被代理時,都會建立一個新的Fegin.Logger例項。我們需要額外指定這個日誌的級別才可以。
1)設定cn.jun包下的日誌級別都為debug ;
logging:
level:
cn.jun: debug
2)編寫配置類,定義日誌級別
Feign支援4種級別:
(1)NONE:不記錄任何日誌資訊,這是預設值。
(2)BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間
(3)HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭資訊
(4)FULL:記錄所有請求和響應的明細,包括頭資訊、請求體、元資料。
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
3)在FeignClient中指定配置類:
@FeignClient(value = "user-service", fallback = UserFeignClientFallback.class, configuration = FeignConfig.class)
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}