Springboot集成OpenFeign Demo詳解
最近整理一下微服務(wù)的文章,先拿一直用的OpenFeign開刀
思考:微服務(wù)之間如何方便優(yōu)雅的實(shí)現(xiàn)服務(wù)間的遠(yuǎn)程調(diào)用
一、說說openFeign是什么吧
說到這個(gè),那不得不先說說RPC
1.什么是RPC
RPC 全稱是 Remote Procedure Call ,即遠(yuǎn)程過程調(diào)用,其對(duì)應(yīng)的是我們的本地調(diào)用。RPC 的目的是:讓我們調(diào)用遠(yuǎn)程方法像調(diào)用本地方法一樣。
//本地調(diào)用 R result = orderService.findOrderByUserId(id); //RPC遠(yuǎn)程調(diào)用 orderService為代理對(duì)象 R result = orderService.findOrderByUserId(id);
RPC框架設(shè)計(jì)架構(gòu)
2. 什么是Feign
Feign是Netflix開發(fā)的聲明式、模板化的HTTP客戶端,F(xiàn)eign可幫助我們更加便捷、優(yōu)雅地調(diào)用HTTP API。
Feign可以做到使用 HTTP 請(qǐng)求遠(yuǎn)程服務(wù)時(shí)就像調(diào)用本地方法一樣的體驗(yàn),開發(fā)者完全感知不到這是遠(yuǎn)程方法,更感知不到這是個(gè) HTTP 請(qǐng)求。它像 Dubbo 一樣,consumer 直接調(diào)用接口方法調(diào)用 provider,而不需要通過常規(guī)的 Http Client 構(gòu)造請(qǐng)求再解析返回?cái)?shù)據(jù)。它解決了讓開發(fā)者調(diào)用遠(yuǎn)程接口就跟調(diào)用本地方法一樣,無需關(guān)注與遠(yuǎn)程的交互細(xì)節(jié),更無需關(guān)注分布式環(huán)境開發(fā)。
Spring Cloud openfeign對(duì)Feign進(jìn)行了增強(qiáng),使其支持Spring MVC注解,另外還整合了Ribbon和Eureka,從而使得Feign的使用更加方便。
2.1 OpenFeign和Feign的區(qū)別
Feign
Feign是SpringCloud組件中的一個(gè)輕量級(jí)RESTful的Http服務(wù)客戶端,F(xiàn)eign內(nèi)置了Ribbon,用來做客戶端負(fù)載均衡,去調(diào)用服務(wù)注冊(cè)中心的服務(wù)。Feign的使用方式是:使用Feign的注解定義接口,調(diào)用這個(gè)接口,就可以調(diào)用服務(wù)注冊(cè)中心的服務(wù)。
OpenFeign
OpenFeign是SpringCloud在Feign的基礎(chǔ)上支持了SpringMVC的注解,如@RequestMapping等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通過動(dòng)態(tài)代理的方式產(chǎn)生實(shí)現(xiàn)類,實(shí)現(xiàn)類中做負(fù)載均衡并調(diào)用其他服務(wù)。
2.2 Ribbon&Feign對(duì)比
Ribbon+RestTemplate進(jìn)行微服務(wù)調(diào)用
@Bean @LoadBalanced public RestTemplate restTemplate() { return new RestTemplate(); } //調(diào)用方式 String url = "http://mall-order/order/findOrderByUserId/"+id; R result = restTemplate.getForObject(url,R.class);
Feign進(jìn)行微服務(wù)調(diào)用
@FeignClient(value = "mall-order",path = "/order") public interface OrderFeignService { @RequestMapping("/findOrderByUserId/{userId}") public R findOrderByUserId(@PathVariable("userId") Integer userId); } //調(diào)用 @Autowired OrderFeignService orderFeignService; //feign調(diào)用 R result = orderFeignService.findOrderByUserId(id);
2.3 Feign的設(shè)計(jì)架構(gòu)
二、Spring Cloud Alibaba快速整合Feign
下面是Springboot集成OpenFeign Demo,完全照著來妥妥的沒問題
服務(wù)提供者我就不寫了,這就是正常的controller,主要是調(diào)用者這塊,接下來寫的也是這個(gè)
1.在pom.xml文件中添加以下依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
2.調(diào)用端添加啟動(dòng)注解 @EnableFeignClients
@EnableAsync @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class }) @EnableDiscoveryClient @EnableFeignClients //掃描和注冊(cè)feign客戶端的beanDefinition @MapperScan("com.**.**.**.**.mapper") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
3.編寫調(diào)用接口+@FeignClient注解
創(chuàng)建一個(gè)FeignClient接口,用于定義要調(diào)用的遠(yuǎn)程服務(wù)的方法:
@FeignClient(value = "base-application", path = "/base") @RequestMapping("/api/testDemo") public interface OpenFeignBaseDemo { @PostMapping("/queryList") String queryList(@RequestBody JSONObject jsonObject); }
在上面的代碼中,我們使用@FeignClient注解指定了要調(diào)用的遠(yuǎn)程服務(wù)的名稱。然后,我們定義了一個(gè)名為queryList的方法,并使用@PostMapping注解指定了要調(diào)用的遠(yuǎn)程服務(wù)的API路徑。
4.發(fā)起調(diào)用,像調(diào)用本地方式一樣調(diào)用遠(yuǎn)程服務(wù)
在其他類中使用OpenFeignBaseDemo 來調(diào)用遠(yuǎn)程服務(wù)的方法
@RestController @RequestMapping("/openFeignDemo") public class OpenFeignControllerDemo { @Autowired private OpenFeignBaseDemo openFeignBase; @PostMapping(value = "/test", produces = { "application/json;charset=utf-8" }) public ResponseEntity test(@RequestBody JSONObject jsonObject) { //feign調(diào)用 String res = openFeignBase.queryList(jsonObject); return new ResponseEntity(res, HttpStatus.OK); } }
5.結(jié)果預(yù)覽
啟動(dòng)兩個(gè)工程,postmain調(diào)用 請(qǐng)求url :localhost:8088/server/openFeignDemo/test。
6.這里我必須強(qiáng)調(diào)一下第3步這個(gè)參數(shù)設(shè)置的含義
public @interface FeignClient { @AliasFor("name") String value() default ""; String contextId() default ""; @AliasFor("value") String name() default ""; String qualifier() default ""; String url() default ""; boolean decode404() default false; Class<?>[] configuration() default {}; Class<?> fallback() default void.class; Class<?> fallbackFactory() default void.class; String path() default ""; boolean primary() default true; }
下面就對(duì)各個(gè)屬性進(jìn)行分析
1.value、name
value和name的作用一樣,如果沒有配置url那么配置的值將作為服務(wù)名稱,用于服務(wù)發(fā)現(xiàn)。反之只是一個(gè)名稱。
2.contextId
我們不想將所有的調(diào)用接口都定義在一個(gè)類中,有一種解決方案就是為每個(gè)Client手動(dòng)指定不同的contextId,這樣就不會(huì)沖突了。
3.url
url用于配置指定服務(wù)的地址,相當(dāng)于直接請(qǐng)求這個(gè)服務(wù),不經(jīng)過Ribbon的服務(wù)選擇。像調(diào)試等場景可以使用。
4.decode404
當(dāng)調(diào)用請(qǐng)求發(fā)生404錯(cuò)誤時(shí),decode404的值為true,那么會(huì)執(zhí)行decoder解碼,否則拋出異常。
5.configuration
configuration是配置Feign配置類,在配置類中可以自定義Feign的Encoder、Decoder、LogLevel、Contract等。
6.fallback
定義容錯(cuò)的處理類,也就是回退邏輯,fallback的類必須實(shí)現(xiàn)Feign Client的接口,無法知道熔斷的異常信息。
7.fallbackFactory
也是容錯(cuò)的處理,可以知道熔斷的異常信息。
8.path
path定義當(dāng)前FeignClient訪問接口時(shí)的統(tǒng)一前綴,比如接口地址是/user/get, 如果你定義了前綴是user, 那么具體方法上的路徑就只需要寫/get 即可。
9.primary
primary對(duì)應(yīng)的是@Primary注解,默認(rèn)為true,官方這樣設(shè)置也是有原因的。當(dāng)我們的Feign實(shí)現(xiàn)了fallback后,也就意味著Feign Client有多個(gè)相同的Bean在Spring容器中,當(dāng)我們?cè)谑褂聾Autowired進(jìn)行注入的時(shí)候,不知道注入哪個(gè),所以我們需要設(shè)置一個(gè)優(yōu)先級(jí)高的,@Primary注解就是干這件事情的。
10.qualifier
qualifier對(duì)應(yīng)的是@Qualifier注解,使用場景跟上面的primary關(guān)系很淡,一般場景直接@Autowired直接注入就可以了。
7.報(bào)錯(cuò)解決
如果遇到這樣的錯(cuò)誤:feign.RetryableException: Read timed out executing POST
可以做如下處理:yaml配置
feign: client: config: default: connectTimeout: 1000 readTimeout: 6000
或者propertis配置
feign.client.config.default.connect-timeout=20000 feign.client.config.default.read-timeout=20000
到此這篇關(guān)于Springboot集成OpenFeign Demo詳解的文章就介紹到這了,更多相關(guān)Springboot集成OpenFeign內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用Calendar類實(shí)現(xiàn)動(dòng)態(tài)日歷
這篇文章主要為大家詳細(xì)介紹了Java使用Calendar類實(shí)現(xiàn)動(dòng)態(tài)日歷,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07SpringMVC整合SSM實(shí)現(xiàn)異常處理器詳解
SpringMVC是一種基于Java,實(shí)現(xiàn)了Web MVC設(shè)計(jì)模式,請(qǐng)求驅(qū)動(dòng)類型的輕量級(jí)Web框架,即使用了MVC架構(gòu)模式的思想,將Web層進(jìn)行職責(zé)解耦?;谡?qǐng)求驅(qū)動(dòng)指的就是使用請(qǐng)求-響應(yīng)模型,框架的目的就是幫助我們簡化開發(fā),SpringMVC也是要簡化我們?nèi)粘eb開發(fā)2022-10-10springMVC之HandlerExceptionResolver使用
這篇文章主要介紹了springMVC之HandlerExceptionResolver使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11springboot項(xiàng)目如何設(shè)置session的過期時(shí)間
這篇文章主要介紹了springboot項(xiàng)目如何設(shè)置session的過期時(shí)間,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01SpringMVC多線程下無法獲取請(qǐng)求的原因和解決方法
從問題出發(fā),逐步講透在SpringMVC中使用RequestContextHolder對(duì)象在多線程情況下無法獲取請(qǐng)求的真實(shí)原因,本文將和大家一起深入剖析SpringMVC多線程下無法獲取請(qǐng)求的原因和解決,需要的朋友可以參考下2024-04-04