SpringCloudAlibaba微服務(wù)調(diào)用組件OpenFeign的方法
JAVA 項(xiàng)目中如何實(shí)現(xiàn)接口調(diào)用?
1)Httpclient
HttpClient 是 Apache Jakarta Common 下的子項(xiàng)目,用來(lái)提供高效的、最新的、功能豐富的支持 Http 協(xié)議的客戶端編程工具包,并且它支持 HTTP 協(xié)議最新版本和建議。HttpClient 相比傳統(tǒng) JDK 自帶的 URLConnection,提升了易用性和靈活性,使客戶端發(fā)送 HTTP 請(qǐng)求變得容易,提高了開(kāi)發(fā)的效率。
2)Okhttp
一個(gè)處理網(wǎng)絡(luò)請(qǐng)求的開(kāi)源項(xiàng)目,是安卓端最火的輕量級(jí)框架,由 Square 公司貢獻(xiàn),用于替代 HttpUrlConnection 和 Apache HttpClient。OkHttp 擁有簡(jiǎn)潔的 API、高效的性能,并支持多種協(xié)議(HTTP/2 和 SPDY)。
3)HttpURLConnection
HttpURLConnection 是 Java 的標(biāo)準(zhǔn)類(lèi),它繼承自 URLConnection,可用于向指定網(wǎng)站發(fā)送 GET 請(qǐng)求、POST 請(qǐng)求。HttpURLConnection 使用比較復(fù)雜,不像 HttpClient 那樣容易使用。
4)RestTemplate WebClient
RestTemplate 是 Spring 提供的用于訪問(wèn) Rest 服務(wù)的客戶端,RestTemplate 提供了多種便捷訪問(wèn)遠(yuǎn)程 HTTP 服務(wù)的方法,能夠大大提高客戶端的編寫(xiě)效率。
上面介紹的是最常見(jiàn)的幾種調(diào)用接口的方法,我們下面要介紹的方法比上面的更簡(jiǎn)單、方便,它就是 Feign。
一 Feign介紹
Feign是Netflix開(kāi)發(fā)的聲明式、模板化的HTTP客戶端,其靈感來(lái)自Retrofit、JAXRS-2.0以及WebSocket。Feign可幫助我們更加便捷、優(yōu)雅地調(diào)用HTTP API。
Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等。
Spring Cloud Openfeign對(duì)Feign進(jìn)行了增強(qiáng),使其支持Spring MVC注解,另外還整合了Ribbon和Nacos,從而使得Feign的使用更加方便。
優(yōu)勢(shì)
Feign可以做到使用 HTTP 請(qǐng)求遠(yuǎn)程服務(wù)時(shí)就像調(diào)用本地方法一樣的體驗(yàn),開(kāi)發(fā)者完全感知不到這是遠(yuǎn)程方法,更感知不到這是個(gè) HTTP 請(qǐng)求。它像 Dubbo 一樣,consumer 直接調(diào)用接口方法調(diào)用 provider,而不需要通過(guò)常規(guī)的 Http Client 構(gòu)造請(qǐng)求再解析返回?cái)?shù)據(jù)。它解決了讓開(kāi)發(fā)者調(diào)用遠(yuǎn)程接口就跟調(diào)用本地方法一樣,無(wú)需關(guān)注與遠(yuǎn)程的交互細(xì)節(jié),更無(wú)需關(guān)注分布式環(huán)境開(kāi)發(fā)。
二 Spring Cloud Alibaba快速整合OpenFeign
引入依賴
<!‐‐ openfeign 遠(yuǎn)程調(diào)用 ‐‐> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring‐cloud‐starter‐openfeign</artifactId> </dependency>
編寫(xiě)調(diào)用接口+@FeignClient
注解
@FeignClient(value = "mall‐order",path = "/order") public interface OrderFeignService { @RequestMapping("/findOrderByUserId/{userId}") public R findOrderByUserId(@PathVariable("userId") Integer userId); } /* * 添加feign接口和方法 * name 指定調(diào)用rest接口所對(duì)應(yīng)的服務(wù)名 * path 指定調(diào)用rest接口所在的StockController指定的@RequestMapping * */ @FeignClient(name="stock-service",path ="/stock",configuration = FeignConfig.class) public interface StockFeignService { // 聲明需要調(diào)用的rest接口對(duì)應(yīng)的方法,沒(méi)有實(shí)現(xiàn)類(lèi):動(dòng)態(tài)代理 @RequestMapping("/reduct") String reduct(); }
調(diào)用端在啟動(dòng)類(lèi)上添加@EnableFeignClients
注解
@EnableFeignClients
發(fā)起調(diào)用,像調(diào)用本地方式一樣調(diào)用遠(yuǎn)程服務(wù)
@RestController @RequestMapping("/user") public class UserController { @Autowired OrderFeignService orderFeignService; @RequestMapping(value = "/findOrderByUserId/{id}") public R findOrderByUserId(@PathVariable("id") Integer id) { //feign調(diào)用 R result = orderFeignService.findOrderByUserId(id); return result; } }
三 Spring Cloud Feign的自定義配置及使用
Feign 提供了很多的擴(kuò)展機(jī)制,讓用戶可以更加靈活的使用
3.1 日志配置
有時(shí)候我們遇到 Bug,比如接口調(diào)用失敗、參數(shù)沒(méi)收到等問(wèn)題,或者想看看調(diào)用性能,就需要配置 Feign 的日志了,以此讓 Feign 把請(qǐng)求信息輸出來(lái)
第一種:全局配置,定義一個(gè)配置類(lèi),指定日志級(jí)別,全局生效
import feign.Contract; import feign.Logger; import feign.Request; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //服務(wù)調(diào)用方進(jìn)行配置 // 注意: 此處配置@Configuration注解就會(huì)全局生效,如果想指定對(duì)應(yīng)微服務(wù)生效,就不能配置(也就是相當(dāng)于局部配置了) @Configuration public class FeignConfig { /** * 日志級(jí)別 * * @return */ @Bean public Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
注意使用的包:
通過(guò)源碼可以看到日志等級(jí)有 4 種,分別是:
- NONE【性能最佳,適用于生產(chǎn)】:不記錄任何日志(默認(rèn)值)。
- BASIC【適用于生產(chǎn)環(huán)境追蹤問(wèn)題】:僅記錄請(qǐng)求方法、URL、響應(yīng)狀態(tài)代碼以及執(zhí)行時(shí)間。
- HEADERS:記錄BASIC級(jí)別的基礎(chǔ)上,記錄請(qǐng)求和響應(yīng)的header。
- FULL【比較適用于開(kāi)發(fā)及測(cè)試環(huán)境定位問(wèn)題】:記錄請(qǐng)求和響應(yīng)的header、body和元數(shù)據(jù)。
第二種:局部配置,讓調(diào)用的微服務(wù)生效,在@FeignClient
注解中指定使用的配置類(lèi)
局部配置有兩種:配置類(lèi)和配置文件
使用局部配置-配置類(lèi)的話,還是要先新建上邊的配置類(lèi),只不過(guò)上邊的配置類(lèi)不能加@Configuration
注解了。
注意下邊,一定要使用@PathVariable("userId")
指定參數(shù),否則報(bào)錯(cuò)
在yml配置文件中執(zhí)行 Client 的日志級(jí)別才能正常輸出日志,格式是"logging.level.feign接口包路徑=debug"
logging: level: com.maltose.mall.feigndemo.feign: debug
測(cè)試:BASIC級(jí)別日志
補(bǔ)充:局部配置可以在yml中配置
對(duì)應(yīng)屬性配置類(lèi):
org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration
# feign日志局部配置 feign: client: config: product-service: #服務(wù)名 loggerLevel: BASIC contract: feign.Contract.Default #設(shè)置為默認(rèn)的契約 (還原成原生注解) # 連接超時(shí)時(shí)間,默認(rèn)2s connectTimeout: 5000 # 請(qǐng)求處理超時(shí)時(shí)間,默認(rèn)5s readTimeout: 10000 requestInterceptors[0]: com.tulingxueyuan.order.intercptor.feign.CustomFeignInterceptor
3.2 契約配置
Spring Cloud 在 Feign 的基礎(chǔ)上做了擴(kuò)展,使用 Spring MVC 的注解來(lái)完成Feign的功能。原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的注解方式來(lái)定義客戶端也是可以的,通過(guò)配置契約來(lái)改變這個(gè)配置,Spring Cloud 中默認(rèn)的是SpringMvcContract
Spring Cloud 早期版本就是用的原生Fegin. 隨著netflix的停更,替換成了Open feign。即舊Spring Cloud項(xiàng)目升級(jí)的話,就得了解契約配置了。
修改契約配置,支持Feign原生的注解
在上邊的FeignConfig.java類(lèi)里添加:
/** * 修改契約配置,支持Feign原生的注解 * @return */ @Bean public Contract feignContract() { return new Contract.Default(); }
注意:修改契約配置后,OrderFeignService 不再支持springmvc的注解,需要使用Feign原生的注解
OrderFeignService 中配置使用Feign原生的注解
@FeignClient(value = "mall‐order",path = "/order") public interface OrderFeignService { //必須指定請(qǐng)求方式 @RequestLine("GET /findOrderByUserId/{userId}")//對(duì)應(yīng)之前springmvc里的RequestMapping注解 public R findOrderByUserId(@Param("userId") Integer userId);//Param對(duì)應(yīng)PathVariable注解 }
補(bǔ)充,也可以通過(guò)yml配置契約
feign: client: config: mall‐order: #對(duì)應(yīng)微服務(wù) loggerLevel: FULL contract: feign.Contract.Default #指定Feign原生注解契約配置
3.3 自定義攔截器實(shí)現(xiàn)認(rèn)證邏輯
public class FeignAuthRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { // 業(yè)務(wù)邏輯 如:記錄日志 String access_token = UUID.randomUUID().toString(); template.header("Authorization",access_token); } } @Configuration // 全局配置 public class FeignConfig { @Bean public Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } /** * 自定義攔截器 * @return */ @Bean public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){ return new FeignAuthRequestInterceptor(); } }
測(cè)試
補(bǔ)充:可以在yml中配置
feign: client: config: mall‐order: #對(duì)應(yīng)微服務(wù) requestInterceptors[0]: #配置攔截器 com.tuling.mall.feigndemo.interceptor.FeignAuthRequestInterceptor
mall-order端可以通過(guò)@RequestHeader
獲取請(qǐng)求參數(shù)
建議在filter,interceptor中處理
3.4 超時(shí)時(shí)間配置
通過(guò) Options 可以配置連接超時(shí)時(shí)間和讀取超時(shí)時(shí)間,Options 的第一個(gè)參數(shù)是連接的超時(shí)時(shí)間(ms),默認(rèn)值是 2s;第二個(gè)是請(qǐng)求處理的超時(shí)時(shí)間(ms),默認(rèn)值是 5s。
全局配置
@Configuration public class FeignConfig { @Bean public Request.Options options() { return new Request.Options(5000, 10000); } }
yml中配置
feign: client: config: mall‐order: #對(duì)應(yīng)微服務(wù) # 連接超時(shí)時(shí)間,默認(rèn)2s connectTimeout: 5000 # 請(qǐng)求處理超時(shí)時(shí)間,默認(rèn)5s readTimeout: 10000
補(bǔ)充說(shuō)明: Feign的底層用的是Ribbon,但超時(shí)時(shí)間以Feign配置為準(zhǔn)
3.5 客戶端組件配置
Feign 中默認(rèn)使用 JDK 原生的 URLConnection 發(fā)送 HTTP 請(qǐng)求,我們可以集成別的組件來(lái)替換掉 URLConnection,比如 Apache HttpClient,OkHttp
Feign發(fā)起調(diào)用真正執(zhí)行邏輯:feign.Client#execute
(擴(kuò)展點(diǎn))
3.5.1 配置Apache HttpClient
引入依賴
<!‐‐ Apache HttpClient ‐‐> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.7</version> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign‐httpclient</artifactId> <version>10.1.0</version> </dependency>
然后修改yml配置,將 Feign 的 Apache HttpClient啟用 :
feign: #feign 使用 Apache HttpClient 可以忽略,默認(rèn)開(kāi)啟 httpclient: enabled: true
關(guān)于配置可參考源碼: org.springframework.cloud.openfeign.FeignAutoConfiguration
測(cè)試:調(diào)用會(huì)進(jìn)入feign.httpclient.ApacheHttpClient#execute
3.5.2 配置 OkHttp
引入依賴
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign‐okhttp</artifactId> </dependency>
然后修改yml配置,將 Feign 的 HttpClient 禁用,啟用 OkHttp,配置如下
feign: #feign 使用 okhttp httpclient: enabled: false okhttp: enabled: true
關(guān)于配置可參考源碼: org.springframework.cloud.openfeign.FeignAutoConfiguration
測(cè)試:調(diào)用會(huì)進(jìn)入feign.okhttp.OkHttpClient#execute
3.6 GZIP 壓縮配置
開(kāi)啟壓縮可以有效節(jié)約網(wǎng)絡(luò)資源,提升接口性能,我們可以配置 GZIP 來(lái)壓縮數(shù)據(jù)
feign: # 配置 GZIP 來(lái)壓縮數(shù)據(jù) compression: request: enabled: true # 配置壓縮的類(lèi)型 mime‐types: text/xml,application/xml,application/json # 最小壓縮值 min‐request‐size: 2048 response: enabled: true
注意:只有當(dāng) Feign 的 Http Client 不是 okhttp3 的時(shí)候,壓縮才會(huì)生效,配置源碼在FeignAcceptGzipEncodingAutoConfiguration
核心代碼就是 @ConditionalOnMissingBean(type="okhttp3.OkHttpClient")
,表示 Spring BeanFactory 中不包含指定的 bean 時(shí)條件匹配,也就是沒(méi)有啟用 okhttp3 時(shí)才會(huì)進(jìn)行壓縮配置。
到此這篇關(guān)于SpringCloudAlibaba微服務(wù)調(diào)用組件OpenFeign的文章就介紹到這了,更多相關(guān)SpringCloudAlibaba OpenFeign內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Maven基礎(chǔ)之如何修改本地倉(cāng)庫(kù)的默認(rèn)路徑
這篇文章主要介紹了Maven基礎(chǔ)之如何修改本地倉(cāng)庫(kù)的默認(rèn)路徑問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05Java 獲取當(dāng)前類(lèi)名和方法名的實(shí)現(xiàn)方法
這篇文章主要介紹了 Java 獲取當(dāng)前類(lèi)名和方法名的實(shí)現(xiàn)方法的相關(guān)資料,這里不僅提供了實(shí)現(xiàn)方法并比較幾種方法的效率,需要的朋友可以參考下2017-07-07java fastJson轉(zhuǎn)JSON兩種常見(jiàn)的轉(zhuǎn)義操作
在實(shí)際開(kāi)發(fā)中,我們有時(shí)需要將特殊字符進(jìn)行轉(zhuǎn)義,本文主要介紹了java fastJson轉(zhuǎn)JSON兩種常見(jiàn)的轉(zhuǎn)義操作,具有一定的參考價(jià)值,感興趣的可以了解一下2024-03-03java實(shí)現(xiàn)一致性hash算法實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)一致性hash算法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12使用Java 壓縮文件打包tar.gz 包的詳細(xì)教程
本文帶領(lǐng)大家學(xué)習(xí)如何使用Java 壓縮文件打包tar.gz 包,主要通過(guò) Apache compress 工具打包,通過(guò)示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2021-05-05Spring Data JPA自動(dòng)生成表時(shí)列順序混亂的最新解決辦法
文章主要介紹了Spring Boot 3.3.5版本中SpringDataJPA自動(dòng)生成表時(shí)列順序混亂的問(wèn)題,以及如何通過(guò)替換Hibernate實(shí)現(xiàn)來(lái)解決這個(gè)問(wèn)題,感興趣的朋友跟隨小編一起看看吧2024-11-11MybatisPlus多表連接查詢的問(wèn)題及解決方案
MybatisPlus官方并沒(méi)有提供多表連接查詢的通用解決方案,然而連接查詢是相當(dāng)普遍的需求,今天通過(guò)本文給大家介紹下MybatisPlus多表連接查詢的問(wèn)題及解決方案,感興趣的朋友一起看看吧2022-01-01