本文由淺人深,帶你了解如何在項目中整合OpenFeign與Sentinel,分析Sentinel源碼,并打造自己的Sentinel腳手架。
Sentinel是阿里巴巴開源的一款微服務流量控制組件。是面向分布式、多語言異構化服務架構的流量治理組件,主要以流量為切入點,從流量路由、流量控制、流量整形、熔斷降級、系統自適應過載保護、熱點流量防護等多個維度來幫助開發者保障微服務的穩定性。
我們先看一下,沒有整合Sentinel,OpenFeign調用異常時,是怎樣的情況。假定存在兩個服務,order和user,然后再order服務中,通過feign調用user中的接口。
公共組件中定義接口:
@FeignClient(name = "xdty-user")public interface UserApi { @GetMapping("/getUserInfo") ResponseResult getUserInfo();}
user服務中實現接口:
public class UserController implements UserApi { @Override public ResponseResult getUserInfo() { int i = 1/0; //模擬異常 return new ResponseResult("200","user info"); }}
order服務中調用user服務中的接口:
@RestControllerpublic class OrderController implements OrderApi { @Autowired private UserApi userApi; @Override public ResponseResult getOrderInfo() { return userApi.getUserInfo(); }}
利用postman訪問order服務。
返回接口:
可以看到,這樣的返回值,是非常不友好的,對于項目而言,不管接口成功與否,都應有統一的返回,如:code,message。
引入依賴:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>
啟用OpenFeign整合Sentinel的自動配置。熔斷是在consumer端實現的,所以在consumer端的application.yaml配置文件中添加如下配置。
feign: sentinel: enabled: true
定義一個容錯的處理類,當調用遠程接口失敗或超時時,會調用對應接口的容錯邏輯。
public class UserApiFallback implements UserApi { @Override public ResponseResult getUserInfo() { return new ResponseResult("503","用戶服務異常"); }}@Componentpublic class UserApiFallbackFactory implements FallbackFactory<UserApi> { @Override public UserApi create(Throwable cause) { return new UserApiFallback(); }}
@FeignClient 注解上增加 fallbackFactory屬性。
@FeignClient(name = "xdty-user",fallbackFactory = UserApiFallbackFactory.class)public interface UserApi { @GetMapping("/getUserInfo") ResponseResult getUserInfo();}
再次調用接口。
可以發現,服務異常后,會進行降級處理,返回統一定義的異常。
上述代碼,增加了異常處理邏輯,但存在一個問題,就是每次都要為其設置fallbackFactory參數。導致項目中會多出很多冗余代碼。那我們能不能有一個自己定制化的默認Fallback去處理這些相同的事情呢?
要想解決這個問題,需要先了解sentinel中fallback的機制。前面提到,要使用sentinel需要配置文件中指定feign.sentinel.enabled=true。看到SentinelFeignAutoConfiguration的代碼實現,我想大家也就明天這樣配置的原因了。
@ConditionalOnProperty 中 feign.sentinel.enabled 起了決定性作用,這也就是為什么我們需要在配置文件中指定 feign.sentinel.enabled=true。
接下來看 SentinelFeign.builder 里面的實現:
build方法中重新實現了super.invocationHandlerFactory方法,也就是動態代理工廠,構建的是InvocationHandler對象。
build中會獲取Feign Client中的信息,比如fallback,fallbackFactory等,然后創建一個SentinelInvocationHandler,SentinelInvocationHandler繼承了InvocationHandler。
SentinelInvocationHandler中的invoke方法里面進行熔斷限流的處理。
從這段代碼我就可以看出,在沒有配置fallback時,并沒有向SentinelInvocationHandler構造方法中傳入FallbackFactory。這樣的話我們就有了思路:
接下來,我們沿著sentinel的思路,編寫一個屬于自己的小小腳手架,實現統一的兜底方法。
定義全局的fallback處理器。
定義一個全局的FallbackFactory。
重新實現spring-cloud-starter-alibaba-sentinel下的SentinelFeign。
注入我們的SentinelFeign Bean。
注:這里使用AutoConfigureBefore注解,要想該注解生效,必須把自定義的配置類變成自動配置類。
這樣,以后只要定義基本屬性@FeignClient,不需要再配置fallBackFactory,就可以完成統一的兜底方法了。
本文鏈接:http://www.tebozhan.com/showinfo-26-33376-0.htmlOpenFeign整合Sentinel,由淺入深,搭建屬于自己的腳手架
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 六個開發者必知必會的Git命令