Java之Springcloud Feign組件詳解
一、Feign是什麼?
OpenFeign是Spring Cloud提供的一個聲明式的偽Hltp客戶端,它使得調用遠程服務就像調用本地服務一樣簡單,隻需要創建一個接口並添加一個註解即可,Nacos很好的兼容瞭OpenFeign,OpenFeign默認集成瞭Ribbon,
所以在Nacos下使用OpenFeign默認就實現瞭負載均衡的效果。
二、使用步驟
1.消費方導入依賴
···c
org.springframework.cloud
spring-cloud-starter-openfeign
···
2.服務消費方的主程序啟動類添加註解,開啟@EnableFeignClients
@SpringBootApplication @MapperScan("com.csqf.mapper") @Import({ Swagger2Config.class, ControllerExceptionAdvice.class, }) @EnableFeignClients public class springcloud_share_6002 { public static void main(String[] args) { SpringApplication.run(springcloud_share_6002.class,args); } @Bean @LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); } }
3.服務消費方 創建遠程調用接口
@Service @FeignClient("user-6001") public interface UserFeignService { @GetMapping("/api/user/{id}") public R getUserNameById(@PathVariable("id") Integer id); }
代碼如下(示例):
4.更改代碼後測試
@RestController @RequestMapping("/api/share") public class ShareContoller { @Autowired private ShareServiceImpl shareService; // @Autowired // private RestTemplate restTemplate; // @Autowired // private DiscoveryClient discoveryClient; @Autowired private UserFeignService userFeignService; @GetMapping("/{id}") public R getShareById(@PathVariable("id") Integer id) { Share share = shareService.getShareById(id); R r = userFeignService.getUserNameById(share.getUserId()); String s = r.getData().toString(); ShareDto shareDto = new ShareDto(); BeanUtils.copyProperties(share,shareDto); shareDto.setUserName(s); return new R(ResponseEnum.SUCCESS,shareDto); } }
補充
1.重試機制
1:如果所有的重試完成 還是失敗 要拋出 feign.RetryableException 異常 2: 重試 會產生接口的冪等性問題: 1:查詢的接口 天生是冪等的 2: 增刪改的處理 非冪等的
配置 | 說明 |
---|---|
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds | 斷路器的超時時間需要大於ribbon的超時時間,不然不會觸發重試。 |
hello-service.ribbon.ConnectTimeout | 請求連接的超時時間 |
hello-service.ribbon.ReadTimeout | 請求處理的超時時間 |
hello-service.ribbon.OkToRetryOnAllOperations | 是否對所有操作請求都進行重試 |
hello-service.ribbon.MaxAutoRetriesNextServer | 重試負載均衡其他的實例最大重試次數,不包括首次server |
2 遠程調用的時候出現異常的處理(ControllerExceptionAdvice)
@ExceptionHandler(RetryableException.class) @ResponseBody public R doException(RetryableException ex){ ex.printStackTrace(); // System.out.println("拋出未知異常"); return new R(ResponseEnum.FEIGN_RETRY,null); }
3.Feign的傳遞參數方式註意事項
如果你傳遞的參數,比較復雜時,默認會采用POST的請求方式。
- 傳遞單個參數時,推薦使用@PathVariable,如果傳遞的單個參數比較多,這裡也可以采用@RequestParam,不要省略value屬性
- 傳遞對象信息時,統一采用json的方式,添加@RequestBody。Client接口必須采用@RequestMapping
spring cloud項目使用feign的時候都會發現一個問題,就是get方式無法解析對象參數。其實feign是支持對象傳遞的,但是得是Map形式,而且不能為空,與spring在機制上不兼容,因此無法使用。
spring cloud在2.1.x版本中提供瞭@SpringQueryMap註解,可以傳遞對象參數,框架自動解析。
調用方feign接口隻能是 | 被調用方接口 |
---|---|
public R f1(User user) 或 public R f1(@RequestBoby User user) | 參數 @RequstBoby 對象 |
public R f1(@SpringQueryMap User user) | 參數 對象 |
總結
FEIGN 集成ribbon 和 resttemplate,簡化 服務之間的調用
Feign是通過內置的Ribbon進行負載均衡,並通過HTTP去訪問被調用方,所以Feign的重試,其實就是Ribbon的重試。另外,我們在實際工作中使用Feign,用到Hystrix,在這裡就順便說一下Hystrix的原理。舉例說明下,假如在沒有Hystrix的情況下,用戶一個下單操作需要調用訂單、支付、物流三個服務,如果其中物流Service因為種種問題不能提供服務,即便另外兩個服務都好好的,整個下單操作也會因為物流Service而阻塞住,導致下單服務崩潰。而Hystrix為每個依賴的服務配置獨立的線程池並進行隔離,假設下單服務有90個線程,沒有Hystrix,則因為物流Service不能提供服務,不停地重試直到90個線程全卡死。而有瞭Hystrix,三個依賴的服務,每個30個線程,即便物流的30個全部阻塞瞭,也不影響另外兩個服務的線程。
到此這篇關於Java之Springcloud Feign組件詳解的文章就介紹到這瞭,更多相關Java之Springcloud Feign內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- SpringCloud微服務基礎簡介
- 基於FeignClient調用超時的處理方案
- 關於SpringCloud的微服務以及組件詳解
- 淺談SpringCloud之Ribbon詳解
- Sentinel 整合SpringCloud的詳細教程