水果網(wǎng)站建設(shè)案例免費(fèi)宣傳平臺(tái)有哪些
SpringCloudAlibaba微服務(wù)調(diào)用組件-Feign
本項(xiàng)目代碼與筆記已存放在Gitee倉(cāng)庫(kù) 地址: 代碼,筆記
文章目錄
- SpringCloudAlibaba微服務(wù)調(diào)用組件-Feign
- 1. 什么是Feign
- 1.1 優(yōu)勢(shì)
- 2. Spring Cloud Alibaba快速整合OpenFeign
- 1)引入依賴
- 2)編寫調(diào)用接口+@FeignClient注解
- 3)調(diào)用端在啟動(dòng)類上添加@EnableFeignClients注解(不加的話會(huì)找不到客戶端service)
- 4)發(fā)起調(diào)用,像調(diào)用本地方式一樣調(diào)用遠(yuǎn)程服務(wù)
- 3. Spring Cloud Feign的自定義配置及使用
- 3.1 日志配置
- 3.2 契約配置 (可以把openFeign還原為feign使用feign的原生注解)
- 3.3 超時(shí)時(shí)間配置
- 3.4自定義攔截器實(shí)現(xiàn)認(rèn)證邏輯
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)類,它繼承自 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ù)的方法,能夠大大提高客戶端的編寫效率。上面介紹的是最常見(jiàn)的幾種調(diào)用接口的方法,我們下面要介紹的方法比上面的更簡(jiǎn)單、方便,它就是 Feign。
1. 什么是Feign
Feign是Netflix開(kāi)發(fā)的聲明式、模板化的HTTP客戶端**(feign是聲明在服務(wù)消費(fèi)端的)**,其靈感來(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的使用更加方便 。
1.1 優(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ā)。
2. Spring Cloud Alibaba快速整合OpenFeign
1)引入依賴
<!--openfeign遠(yuǎn)程調(diào)用-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2)編寫調(diào)用接口+@FeignClient注解
/*** Create with IntelliT IDEA** @Author: zhengmingzhe* @Date: 2023/03/15/21:15* @Description: 調(diào)用stock-service服務(wù)service*/
/*name 指定調(diào)用的rest接口的服務(wù)名,比如這里調(diào)用庫(kù)存服務(wù)stock-service* path 指定rest接口所在的StockController指定的@RequestMapping("/stock")* **/
@FeignClient(name = "stock-service", path = "/stock")
public interface StockFeignService {//聲明需要調(diào)用的rest接口對(duì)應(yīng)的方法,直接復(fù)制過(guò)來(lái),對(duì)應(yīng)的就行(不用寫實(shí)現(xiàn)類)@RequestMapping("/reduct")String reduct();
}
3)調(diào)用端在啟動(dòng)類上添加@EnableFeignClients注解(不加的話會(huì)找不到客戶端service)
@SpringBootApplication
@EnableDiscoveryClient //啟動(dòng)nacos的客戶端 不加也行在后續(xù)的版本這個(gè)注解可不用手動(dòng)添加
@EnableFeignClients
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}
}
4)發(fā)起調(diào)用,像調(diào)用本地方式一樣調(diào)用遠(yuǎn)程服務(wù)
@RestController
@RequestMapping("/order")
public class OrderController {@AutowiredStockFeignService stockService;@RequestMapping("/add")public String add() {System.out.println("下單成功");String msg = stockService.reduct();return "Hello Feign!" + msg;}
}
3. 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)。
1)定義一個(gè)配置類,指定日志級(jí)別
/* 全局配置:當(dāng)使用@Configuation會(huì)將配置作用于所有的服務(wù)提供方* 局部配置: 如果只想針對(duì)某一個(gè)服務(wù)進(jìn)行配置,就不要加@Configuration*/
@Configuration
public class FeignConfig {/*** 日志級(jí)別* <p>* @return*/@Beanpublic Logger.Level feignLoggerLevel() {return Logger.Level.BASIC;}
}
通過(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ù)。
2) 局部配置,讓調(diào)用的微服務(wù)生效,在@FeignClient 注解中指定使用的配置類(如果是全局配置就不用加)
@FeignClient(name = "stock-service", path = "/stock", configuration = FeignConfig.class)
public interface StockFeignService {//聲明需要調(diào)用的rest接口對(duì)應(yīng)的方法,直接復(fù)制過(guò)來(lái),對(duì)應(yīng)的就行(不用寫實(shí)現(xiàn)類)@RequestMapping("/reduct")String reduct();
}
3) 在yml配置文件中執(zhí)行 Client 的日志級(jí)別才能正常輸出日志,格式是"logging.level.feign接口包路徑
=debug" (找到對(duì)應(yīng)的service所在的包右鍵copy reference)
logging:level:com.zmz.order.feign: debug
就會(huì)顯示BASIC級(jí)別的日志信息
下單成功
2023-03-15 22:39:48.867 DEBUG 23504 — [nio-8040-exec-1] com.zmz.order.feign.StockFeignService : [StockFeignService#reduct] —> GET http://stock-service/stock/reduct HTTP/1.1
2023-03-15 22:39:48.871 DEBUG 23504 — [nio-8040-exec-1] com.zmz.order.feign.StockFeignService : [StockFeignService#reduct] <— HTTP/1.1 200 (3ms)
補(bǔ)充:局部配置可以在yml中配置
對(duì)應(yīng)屬性配置類:
org.springframework.cloud.openfeign.FeignClientProperties.FeignClientConfiguration
#feign日志局部配置
feign:client:config:stock-service:loggerLevel: FULL
3.2 契約配置 (可以把openFeign還原為feign使用feign的原生注解)
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 1 早期版本就是用的原生Fegin. 隨著netflix的停更替換成了Open feign 。
/*** 修改契約配置,支持Feign原生的注解* @return*/@Beanpublic Contract feignContract() {return new Contract.Default();}
注意:修改契約配置后,OrderFeignService 不再支持springmvc的注解,需要使用Feign原 生的注解 。
@FeignClient(name = "stock-service", path = "/stock", configuration = FeignConfig.class)
public interface StockFeignService {//聲明需要調(diào)用的rest接口對(duì)應(yīng)的方法,直接復(fù)制過(guò)來(lái),對(duì)應(yīng)的就行(不用寫實(shí)現(xiàn)類)
// @RequestMapping("/reduct")
// String reduct();@RequestLine("GET/reduct") // @RequestLine替換@RequestMapping加上請(qǐng)求方式GETString reduct();
}
3)補(bǔ)充,也可以通過(guò)yml配置契約
#feign日志局部配置
feign:client:config:stock-service:loggerLevel: FULLcontract: feign.Contract.Default #設(shè)置為默認(rèn)的契約(還原成原生注解)
3.3 超時(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。
/*設(shè)置feign調(diào)用超時(shí)時(shí)間*/@Beanpublic Request.Options options() {return new Request.Options(5000, 10000);}
yml中配置
feign:client:config:stock-service:loggerLevel: FULLcontract: feign.Contract.Default #設(shè)置為默認(rèn)的契約(還原成原生注解)connectTimeout: 5000readTimeout: 3000
補(bǔ)充說(shuō)明: Feign的底層用的是Ribbon,但超時(shí)時(shí)間以Feign配置為準(zhǔn)
3.4自定義攔截器實(shí)現(xiàn)認(rèn)證邏輯
在消費(fèi)端調(diào)用提供端的時(shí)候起作用(要驗(yàn)證認(rèn)證Authorization的時(shí)候把feign日志級(jí)別設(shè)置為FULL)
public class FeignAuthRequestInterceptor implements RequestInterceptor {Logger logger = LoggerFactory.getLogger(this.getClass());@Overridepublic void apply(RequestTemplate template) {logger.info("feign攔截器----");
// 業(yè)務(wù)邏輯String access_token = UUID.randomUUID().toString();template.header("Authorization", access_token);}
}
//@Configuration
public class FeignConfig {/*** 日志級(jí)別* <p>* @return*/@Beanpublic Logger.Level feignLoggerLevel() {return Logger.Level.FULL;}/*定義攔截器*/@Beanpublic FeignAuthRequestInterceptor feignAuthRequestInterceptor() {return new FeignAuthRequestInterceptor();}
}