旅游網(wǎng)站國際業(yè)務(wù)怎樣做廈門seo專業(yè)培訓(xùn)學(xué)校
微服務(wù)架構(gòu)中,服務(wù)之間的通信變得尤為關(guān)鍵。OpenFeign,一個聲明式的Web服務(wù)客戶端,使得REST API的調(diào)用變得更加簡單和優(yōu)雅。OpenFeign集成了Ribbon和Hystrix,具有負(fù)載均衡和容錯的能力,并且在Spring Cloud的加持下,可以輕松地與注冊中心(nacos,Eureka)和配置中心(Spring Cloud Config,nacos)等組件集成。
目錄
- 一、OpenFeign簡介
- 二、OpenFeign的使用
- 1. 添加依賴
- 2. 啟用OpenFeign
- 3. 定義Feign客戶端
- 4. 注入和使用Feign客戶端
- 三、@FeignClient注解
- 四、feign緩存
- 1. Feign緩存的意義
- 2. feign緩存的使用
- 五、@QueryMap支持
- 使用方法
- 六、@MatrixVariable支持
- 使用 `@MatrixVariable`
- URI 結(jié)構(gòu)
- 七、@CollectionFormat支持
- 八、其他高級特性
- 總結(jié)
一、OpenFeign簡介
OpenFeign是一個聲明式的Web服務(wù)客戶端,它使得編寫HTTP客戶端變得更簡單。使用Feign,你只需要創(chuàng)建一個接口并用注解來配置它,Feign會自動完成接口的實(shí)現(xiàn)。OpenFeign具有可插拔的注解特性,同時也支持JAX-RS注解和Feign注解。此外,它還支持負(fù)載均衡和容錯,通過集成Spring Cloud alibaba和Spring Cloud,可以輕松地查找服務(wù)并進(jìn)行調(diào)用。
二、OpenFeign的使用
1. 添加依賴
首先需要在項(xiàng)目中添加OpenFeign的依賴。Maven可以在pom.xml文件中添加以下依賴:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 啟用OpenFeign
在spring Boot應(yīng)用主類上添加@EnableFeignClients
注解,以啟用OpenFeign。
@SpringBootApplication
@EnableFeignClients
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);}
}
3. 定義Feign客戶端
定義Feign客戶端接口,并使用@FeignClient
注解進(jìn)行配置。假設(shè)有一個名為user-service
的遠(yuǎn)程服務(wù),可以這樣定義一個Feign客戶端:
@FeignClient("user-service")
public interface UserClient {@GetMapping("/users/{id}")User getUser(@PathVariable("id") Long id);
}
@FeignClient
注解指定了要調(diào)用的遠(yuǎn)程服務(wù)的名稱(在本例中是user-service
),而接口中的方法則定義了具體的HTTP請求。@GetMapping
注解表示這是一個GET請求,@PathVariable
注解則用于從URL路徑中提取參數(shù)。
4. 注入和使用Feign客戶端
一旦你定義了Feign客戶端接口,你就可以在你的服務(wù)中注入并使用它了。例如:
@Service
public class UserService {private final UserClient userClient;@Autowiredpublic UserService(UserClient userClient) {this.userClient = userClient;}public User getUser(Long userId) {return userClient.getUser(userId);}
}
在這個例子中,UserService
類注入了UserClient
的實(shí)例,并通過它來調(diào)用遠(yuǎn)程服務(wù)。當(dāng)你調(diào)用getUser
方法時,OpenFeign會自動將HTTP請求發(fā)送到指定的遠(yuǎn)程服務(wù),并將響應(yīng)映射到Java對象上。
三、@FeignClient注解
@FeignClient注解是用于標(biāo)記Feign客戶端接口的關(guān)鍵注解。通過此注解,OpenFeign能夠自動生成接口的實(shí)現(xiàn),使得開發(fā)者能夠以聲明式的方式調(diào)用遠(yuǎn)程服務(wù)。
下面是@FeignClient注解的詳細(xì)參數(shù)及其用法:
-
name:
- 含義:指定Feign客戶端的名稱,這個名稱通常用于服務(wù)發(fā)現(xiàn)和服務(wù)間的負(fù)載均衡。在微服務(wù)架構(gòu)中,這個名稱通常與服務(wù)提供者在服務(wù)注冊中心注冊的服務(wù)名相對應(yīng)。
- 用法:
@FeignClient(name = "serviceName")
,其中"serviceName"是遠(yuǎn)程服務(wù)的名稱。
-
url:
- 含義:直接指定Feign客戶端的請求地址。當(dāng)該參數(shù)被設(shè)置時,Feign將不再從服務(wù)注冊中心獲取服務(wù)地址,而是直接使用這個URL作為請求的目標(biāo)地址。
- 用法:
@FeignClient(url = "http://localhost:8080")
,指定具體的服務(wù)地址。 - 注意:如果同時指定了name和url,url會覆蓋name中定義的地址。
-
configuration:
- 含義:指定Feign客戶端的配置類。在這個配置類中,可以自定義Feign的各種參數(shù),如請求攔截器、編碼器、解碼器等。
- 用法:
@FeignClient(configuration = CustomFeignConfiguration.class)
,其中CustomFeignConfiguration
是自定義的配置類。
-
fallback:
- 含義:指定Feign客戶端的降級方案。當(dāng)請求出現(xiàn)異常時,如遠(yuǎn)程服務(wù)不可用或請求超時,Feign會返回fallback指定的實(shí)例的數(shù)據(jù)。這通常用于實(shí)現(xiàn)熔斷和降級邏輯,以提高系統(tǒng)的穩(wěn)定性。
- 用法:
@FeignClient(fallback = UserClientFallback.class)
,其中UserClientFallback
是實(shí)現(xiàn)了Feign客戶端接口的降級處理類。
-
fallbackFactory:
- 含義:與fallback類似,但是提供了一個工廠類來創(chuàng)建降級邏輯的實(shí)例。這個工廠類需要實(shí)現(xiàn)
FallbackFactory
接口,并覆蓋create(Throwable cause)
方法。這個方法返回一個實(shí)現(xiàn)了Feign客戶端接口的實(shí)例,用于處理降級邏輯。 - 用法:通常與Hystrix等熔斷框架結(jié)合使用,提供更靈活的降級策略。
- 含義:與fallback類似,但是提供了一個工廠類來創(chuàng)建降級邏輯的實(shí)例。這個工廠類需要實(shí)現(xiàn)
-
path:
- 含義:定義所有方法請求的基礎(chǔ)路徑。這樣可以在Feign客戶端的接口方法中省略這個基礎(chǔ)路徑。
- 用法:
@FeignClient(path = "/api/users")
,指定所有請求的基礎(chǔ)路徑。
-
qualifier:
- 含義:當(dāng)使用Spring的自動裝配功能時,可以使用qualifier參數(shù)來指定一個bean的名稱,以便在多個相同類型的Feign客戶端之間進(jìn)行區(qū)分。
- 用法:通常與
@Qualifier
注解結(jié)合使用,用于解決自動裝配時的歧義。
-
decode404:
- 含義:指定當(dāng)服務(wù)端返回404狀態(tài)時是否拋出
FeignException
。默認(rèn)情況下,Feign會將404視為一個正常的響應(yīng)(即不會拋出異常)。如果將此參數(shù)設(shè)置為true,則當(dāng)服務(wù)端返回404狀態(tài)時,Feign會拋出一個FeignException
。 - 用法:在需要特殊處理404響應(yīng)的場景中使用。
- 含義:指定當(dāng)服務(wù)端返回404狀態(tài)時是否拋出
-
primary:
- 含義:當(dāng)存在多個相同類型的bean時,將此參數(shù)設(shè)置為true可以將該bean設(shè)置為首選bean。這樣,在使用
@Autowired
進(jìn)行自動裝配時,Spring會優(yōu)先選擇標(biāo)記為primary的bean。 - 用法:在需要指定首選bean的場景中使用。
- 含義:當(dāng)存在多個相同類型的bean時,將此參數(shù)設(shè)置為true可以將該bean設(shè)置為首選bean。這樣,在使用
此外,@FeignClient注解還支持使用Spring Expression Language (SpEL) 表達(dá)式來動態(tài)地指定某些參數(shù)值。例如,可以使用${property.name}
來從配置文件或環(huán)境變量中讀取值。這種動態(tài)配置方式使得Feign客戶端更加靈活和可配置。
四、feign緩存
1. Feign緩存的意義
在網(wǎng)絡(luò)請求中,頻繁地調(diào)用相同的接口會消耗大量的時間和資源。通過引入緩存機(jī)制,可以將一些不經(jīng)常變化且查詢頻繁的數(shù)據(jù)存儲在本地,從而減少對遠(yuǎn)程服務(wù)的調(diào)用,提高系統(tǒng)的響應(yīng)速度和性能。
Feign 緩存是通過結(jié)合 Spring Framework 的緩存抽象來實(shí)現(xiàn)的。當(dāng)你使用 @EnableCaching
注解時,Spring Boot 會啟用對 @Cacheable
、@CacheEvict
、@CachePut
等緩存相關(guān)注解的支持。對于 Feign 客戶端來說,這意味著你可以在 Feign 接口的方法上使用這些注解來控制緩存行為。
2. feign緩存的使用
啟用緩存
首先在 Spring Boot 應(yīng)用中使用 @EnableCaching
注解來啟用緩存支持。這通常是在配置類或者啟動類上添加的。
@EnableCaching
@SpringBootApplication
public class MyApp {public static void main(String[] args) {SpringApplication.run(MyApp.class, args);}
}
使用 @Cacheable 注解
在Feign 客戶端接口中,可以使用 @Cacheable
注解來標(biāo)記需要緩存的方法。這個注解指定了緩存的名稱(cacheNames
)和用于生成緩存鍵的表達(dá)式(key
)。
@FeignClient("some-service")
public interface SomeServiceClient {@Cacheable(cacheNames = "infos", key = "#id")@GetMapping("/info/{id}")public Object info(@PathVariable("id") Integer id);
}
info
方法被標(biāo)記為可緩存的。當(dāng)這個方法被調(diào)用時,Spring 會檢查名為 infos
的緩存中是否已經(jīng)有對應(yīng) id
的緩存項(xiàng)。如果有,就直接返回緩存的數(shù)據(jù);如果沒有,就執(zhí)行遠(yuǎn)程調(diào)用,并將結(jié)果存儲到緩存中。
配置緩存管理器
通過配置文件來指定緩存管理器的類型和其他相關(guān)設(shè)置。使用了Redis 作為緩存存儲,并配置了 Redis 緩存的相關(guān)參數(shù)。
spring:cache:type: redis # 指定緩存類型為 Redisredis:key-prefix: 'feign:' # 設(shè)置 Redis 緩存鍵的前綴time-to-live: 60s # 設(shè)置緩存的有效期為 60 秒
這樣配置后,Feign 客戶端的緩存數(shù)據(jù)會被存儲到 Redis 中,并且每個緩存項(xiàng)的有效期為 60 秒。這意味著在 60 秒內(nèi)對同一個 id
的多次請求都會直接從 Redis 緩存中獲取數(shù)據(jù),而不會觸發(fā)遠(yuǎn)程調(diào)用。當(dāng)緩存過期后,下一次請求會觸發(fā)遠(yuǎn)程調(diào)用,并更新緩存。
五、@QueryMap支持
在Feign中使用@QueryMap
或Spring Cloud OpenFeign中的@SpringQueryMap
注解可以非常方便地將一個POJO(Plain Old Java Object,即簡單的Java對象)或Map的屬性和值映射為HTTP GET請求的查詢參數(shù)。這在構(gòu)建具有多個查詢參數(shù)的API調(diào)用時特別有用,因?yàn)樗试S你以聲明式的方式組織這些參數(shù),而不是手動構(gòu)建查詢字符串。
簡單點(diǎn)說:可以將一個對象中的所有屬性值以get的方式拼接到地址欄進(jìn)行傳遞。
@QueryMap 和 @SpringQueryMap
- @QueryMap: OpenFeign原生提供的注解,用于將POJO映射為查詢參數(shù)。但是,它與Spring不兼容,因?yàn)樗鼪]有
value
屬性。 - @SpringQueryMap: Spring Cloud OpenFeign提供的與Spring兼容的注解,功能和@QueryMap類似,但可以在Spring環(huán)境中使用。
使用方法
- 定義參數(shù)對象:
創(chuàng)建一個簡單的Java類Params
,并為其添加屬性和getter方法。這些屬性和方法將用于生成查詢參數(shù)。
public class Params {private Long id;private String name;// getters and setters}
- 在Feign客戶端中使用@SpringQueryMap:
在Feign客戶端接口中,使用@GetMapping
注解來定義一個GET請求,并使用@SpringQueryMap
注解來標(biāo)記你的POJO參數(shù)。
@FeignClient("some-service")public interface DemoFeign {@GetMapping("/format")Object format(@SpringQueryMap Params params);}
- 調(diào)用Feign客戶端:
在服務(wù)中創(chuàng)建一個Params
對象,設(shè)置其屬性,并通過Feign客戶端調(diào)用該方法。
@GetMapping("/format")public Object format(Params params) {return demoFeign.format(params);}
- 日志輸出:
當(dāng)調(diào)用這個方法時,Feign會自動將Params
對象的屬性轉(zhuǎn)換為查詢參數(shù),并附加到GET請求的URL上??梢酝ㄟ^查看Feign的請求日志來確認(rèn)這一點(diǎn)。
[DemoFeign#format] ---> GET http://localhost:8088/demos/format?name=test&id=111 HTTP/1.1
通過這種方式,可以簡潔地將復(fù)雜的查詢參數(shù)組織到一個對象中,并讓Feign自動處理參數(shù)到查詢字符串的轉(zhuǎn)換,從而簡化了代碼并提高了可讀性。
六、@MatrixVariable支持
在Spring Cloud OpenFeign中,@MatrixVariable
注解被用來處理 URI 中的矩陣變量。矩陣變量是 URI 的一種特殊參數(shù)形式,允許你在 URI 路徑段中直接包含鍵值對。這種形式的參數(shù)在某些 RESTful API 設(shè)計(jì)中很有用,尤其是當(dāng)你需要在 URI 中傳遞多個參數(shù),并且這些參數(shù)都是針對同一資源的時候。
使用 @MatrixVariable
@MatrixVariable
被用來接收一個映射(Map),其中鍵是字符串,值是字符串列表。這在處理可能包含多個值的矩陣變量時非常有用。
@GetMapping("/m3/{params}")
public Object matrix3(@MatrixVariable Map<String, List<String>> params) {// ...
}
{params}
是一個路徑占位符,它表示這個部分將由傳遞的矩陣變量填充。@MatrixVariable
注解告訴 Spring,params
參數(shù)應(yīng)該接收來自 URI 矩陣變量的值。
URI 結(jié)構(gòu)
一個包含矩陣變量的 URI 看起來像這樣:
/m3/someValue;key1=value1a,value1b;key2=value2
在這個 URI 中:
/m3/someValue
是基本的路徑。;key1=value1a,value1b;key2=value2
是矩陣變量部分,其中key1
和key2
是矩陣變量的名稱,value1a,value1b
和value2
是相應(yīng)的值。
注意事項(xiàng)
- 路徑占位符的名稱(在這個例子中是
{params}
)必須與@MatrixVariable
注解的變量名一致,或者你可以在注解中明確指定名稱。 - 矩陣變量的值可以是單個值,也可以是用逗號分隔的多個值,這取決于你的 API 如何設(shè)計(jì)。
- 使用矩陣變量時,要確保你的 URI 編碼和解碼邏輯能夠正確處理這些變量,特別是當(dāng)值中包含特殊字符時。
七、@CollectionFormat支持
在Feign中,@CollectionFormat
注解用于指定集合參數(shù)的格式化方式。當(dāng)你在Feign客戶端的方法中使用集合類型的參數(shù)(如 List<String>
)時,這個注解能夠幫助你定義如何將集合中的元素串聯(lián)起來,以便通過HTTP請求發(fā)送給服務(wù)端。
@CollectionFormat
注解接受一個 feign.CollectionFormat
枚舉值,該枚舉定義了不同的格式化選項(xiàng)。在你提供的例子中,展示了兩種格式化方式:CSV
和 PIPES
。
-
CSV (Comma Separated Values):
當(dāng)使用feign.CollectionFormat.CSV
時,集合中的元素會使用逗號,
進(jìn)行分隔。這是最常見和默認(rèn)的格式。示例:
@GetMapping("/cf") @CollectionFormat(feign.CollectionFormat.CSV) public Object cf(@RequestParam("ids") List<String> ids);
調(diào)用該方法并傳遞
List.of("S1", "S2", "S3")
時,生成的URL查詢參數(shù)會是ids=S1,S2,S3
。 -
PIPES (
|
separator):
當(dāng)使用feign.CollectionFormat.PIPES
時,集合中的元素會使用豎線|
進(jìn)行分隔。示例:
@GetMapping("/cf") @CollectionFormat(feign.CollectionFormat.PIPES) public Object cf(@RequestParam("ids") List<String> ids);
同樣地,調(diào)用該方法并傳遞
List.of("S1", "S2", "S3")
時,生成的URL查詢參數(shù)會是ids=S1|S2|S3
。
這個注解在處理需要特定格式的集合參數(shù)時非常有用,尤其是當(dāng)服務(wù)端期望接收特定格式的集合數(shù)據(jù)時。通過使用 @CollectionFormat
,你可以確保Feign客戶端發(fā)送的請求符合服務(wù)端的期望,從而避免格式錯誤導(dǎo)致的問題。
@CollectionFormat
可以應(yīng)用于整個Feign客戶端類或者單獨(dú)的方法上。如果應(yīng)用于類上,它將影響該類中所有使用集合參數(shù)的方法。如果只需要對某個特定方法應(yīng)用不同的集合格式,可以將注解直接應(yīng)用于該方法上。
八、其他高級特性
OpenFeign還提供了許多高級特性,如負(fù)載均衡、容錯、請求攔截和重試等。這些特性可以幫助構(gòu)建更健壯、更可靠的微服務(wù)架構(gòu)。
- 負(fù)載均衡:OpenFeign集成了Ribbon,支持多種負(fù)載均衡策略,如輪詢、隨機(jī)等。你可以根據(jù)需要選擇合適的策略來分發(fā)請求。
- 容錯:通過與Hystrix的集成,OpenFeign提供了熔斷和降級功能。當(dāng)遠(yuǎn)程服務(wù)出現(xiàn)故障或響應(yīng)過慢時,可以自動切換到降級邏輯,保證系統(tǒng)的穩(wěn)定性。
- 請求攔截:可以使用
RequestInterceptor
接口實(shí)現(xiàn)自定義的請求攔截器,用于在發(fā)送請求之前或之后執(zhí)行特定的邏輯,如添加認(rèn)證信息、記錄日志等。 - 重試機(jī)制:OpenFeign支持配置請求的重試次數(shù)和間隔,以提高系統(tǒng)的可靠性。
總結(jié)
OpenFeign是一個強(qiáng)大的聲明式Web服務(wù)客戶端,它簡化了遠(yuǎn)程服務(wù)調(diào)用的復(fù)雜性,并提供了負(fù)載均衡、容錯等高級特性。通過使用OpenFeign,你可以更加專注于業(yè)務(wù)邏輯的實(shí)現(xiàn),而無需關(guān)心底層的HTTP通信細(xì)節(jié)。希望本文能幫助你更好地理解和使用OpenFeign,構(gòu)建高效、穩(wěn)定的微服務(wù)架構(gòu)。