1.Feign
使用了Ribbon的負載均衡功能,大大簡化了遠程調用時的代碼:
String baseUrl = "http://user-service/user/";
User user = this.restTemplate.getForObject(baseUrl + id, User.class)
你可能以後需要編寫類似的大量重複代碼,格式基本相同,無非參數不一樣。有沒有更優雅的方式,來對這些代碼再次優化呢?
這就是我們接下來要學的Feign的功能了。
1.1.簡介
有道詞典的英文解釋:
爲什麼叫僞裝?
Feign可以把Rest的請求進行隱藏,僞裝成類似SpringMVC的Controller一樣。你不用再自己拼接url,拼接參數等等操作,一切都交給Feign去做。
項目主頁:https://github.com/OpenFeign/feign
1.2.快速入門
1.2.1.導入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1.2.2.Feign的客戶端
@FeignClient("user-service")
public interface UserFeignClient {
@GetMapping("/user/{id}")
User queryUserById(@PathVariable("id") Long id);
}
- 首先這是一個接口,Feign會通過動態代理,幫我們生成實現類。這點跟mybatis的mapper很像
@FeignClient
,聲明這是一個Feign客戶端,類似@Mapper
註解。同時通過value
屬性指定服務名稱- 接口中的定義方法,完全採用SpringMVC的註解,Feign會根據註解幫我們生成URL,並訪問獲取結果
改造原來的調用邏輯,不再調用UserDao:
@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.2.3.開啓Feign功能
我們在啓動類上,添加註解,開啓Feign功能
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableFeignClients // 開啓Feign功能
public class UserConsumerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}
- 你會發現RestTemplate的註冊被我刪除了。Feign中已經自動集成了Ribbon負載均衡,因此我們不需要自己定義RestTemplate了
1.2.4.啓動測試:
訪問接口:
正常獲取到了結果。
1.3.負載均衡
Feign中本身已經集成了Ribbon依賴和自動配置:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-6g9qR0OZ-1576480757201)(assets/1525672070679.png)]
因此我們不需要額外引入依賴,也不需要再註冊RestTemplate
對象。
另外,我們可以像上節課中講的那樣去配置Ribbon,可以通過ribbon.xx
來進行全局配置。也可以通過服務名.ribbon.xx
來對指定服務配置:
user-service:
ribbon:
ConnectTimeout: 250 # 連接超時時間(ms)
ReadTimeout: 1000 # 通信超時時間(ms)
OkToRetryOnAllOperations: true # 是否對所有操作重試
MaxAutoRetriesNextServer: 1 # 同一服務不同實例的重試次數
MaxAutoRetries: 1 # 同一實例的重試次數
1.4.Hystix支持
Feign默認也有對Hystix的集成:
只不過,默認情況下是關閉的。我們需要通過下面的參數來開啓:
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)重啓測試:
我們關閉user-service服務,然後在頁面訪問:
1.5.請求壓縮(瞭解)
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 # 設置觸發壓縮的大小下限
注:上面的數據類型、壓縮大小下限均爲默認值。
1.6.日誌級別(瞭解)
前面講過,通過logging.level.xx=debug
來設置日誌級別。然而這個對Fegin客戶端而言不會產生效果。因爲@FeignClient
註解修改的客戶端在被代理時,都會創建一個新的Fegin.Logger實例。我們需要額外指定這個日誌的級別纔可以。
1)設置com.he包下的日誌級別都爲debug
logging:
level:
com.he: debug
2)編寫配置類,定義日誌級別
@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
這裏指定的Level級別是FULL,Feign支持4種級別:
- NONE:不記錄任何日誌信息,這是默認值。
- BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間
- HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭信息
- 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);
}
4)重啓項目,即可看到每次訪問的日誌: