• <bdo id="qgeso"></bdo>
        • <strike id="qgeso"></strike>
        • <sup id="qgeso"></sup><center id="qgeso"></center>
        • <input id="qgeso"></input>

          微服務組件Feign

          首頁 > 探索 > > 正文

          日期:2023-05-14 13:03:32    來源:嗶哩嗶哩    

          Feign 是Spring Cloud Netflix組件中的一個輕量級Restful的 HTTP 服務客戶端,實現了負載均衡和 Rest 調用的開源框架,封裝了Ribbon和RestTemplate, 實現了WebService的面向接口編程,進一步降低了項目的耦合度。


          (相關資料圖)

          先來看我們以前利用RestTemplate發起遠程調用的代碼:

          String?url?=?"http://user-service:8081/user/"+order.getUserId();User?user?=?restTemplate.getForObject(url,?User.class);

          以上的代碼存在參數復雜、URL難以維護等問題,如當我有一臺服務地址換了,那么這時候就需要云同步修改url,那要是多臺要修改的情況下那就得改很多臺,當我們服務多的時候這是個很麻煩的事情。

          1.Feign替代RestTemplate

          Fegin的使用步驟如下:

          1)引入依賴

          我們在order-service服務的pom文件中引入feign的依賴:

          <dependency>??<groupId>org.springframework.cloud</groupId>??<artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

          2)添加注解

          在order-service的啟動類添加注解開啟Feign的功能:

          3)編寫Feign的客戶端

          在order-service中新建一個接口,內容如下:

          package?cn.itcast.order.service.feign;import?cn.itcast.order.pojo.User;import?org.springframework.cloud.openfeign.FeignClient;import?org.springframework.web.bind.annotation.GetMapping;import?org.springframework.web.bind.annotation.PathVariable;@FeignClient("user-service")public?interface?UserFeignClient?{????@GetMapping("/user/{id}")????User?queryById(@PathVariable("id")?Long?id);}

          這個客戶端主要是基于SpringMVC的注解來聲明遠程調用的信息,比如:

          服務名稱:user-service

          請求方式:GET

          請求路徑:/user/{id}

          請求參數:Long id

          返回值類型:User

          這樣,Feign就可以幫助我們發送http請求,無需自己使用RestTemplate來發送了。底層會通過服務名稱:user-service去映射到具體的user服務對應的url地址。

          4)測試

          修改order-service中的OrderService類中的queryOrderById方法,使用Feign客戶端代替RestTemplate:

          @Servicepublic?class?OrderService?{????@Autowired????private?OrderMapper?orderMapper;????@Autowired????private?RestTemplate?restTemplate;????@Autowired????UserFeignClient?feignClient;????public?Order?queryOrderById(Long?orderId)?{????????//?1.查詢訂單????????Order?order?=?orderMapper.findById(orderId);????????User?user?=?feignClient.queryById(orderId);????????order.setUser(user);????????//?4.返回????????return?order;????}}

          測試調用:

          2.自定義配置

          Feign可以支持很多的自定義配置,如下表所示:

          類型

          作用

          說明

          feign.Logger.Level

          修改日志級別

          包含四種不同的級別:NONE、BASIC、HEADERS、FULL

          feign.codec.Decoder

          響應結果的解析器

          http遠程調用的結果做解析,例如解析json字符串為java對象

          feign.codec.Encoder

          請求參數編碼

          將請求參數編碼,便于通過http請求發送

          feign. Contract

          支持的注解格式

          默認是SpringMVC的注解

          feign. Retryer

          失敗重試機制

          請求失敗的重試機制,默認是沒有,不過會使用Ribbon的重試

          一般情況下,默認值就能滿足我們使用,如果要自定義時,只需要創建自定義的@Bean覆蓋默認Bean即可。

          下面以日志為例來演示如何自定義配置。

          2.1.配置文件方式

          基于配置文件修改feign的日志級別可以針對單個服務:(注意:有時yml配置文件中有中文注釋會報錯)

          feign:????client:????config:???????user-service:?#?針對某個微服務的配置????????loggerLevel:?FULL?#??日志級別

          也可以針對所有服務:

          feign:????client:????config:???????default:?#?這里用default就是全局配置,如果是寫服務名稱,則是針對某個微服務的配置????????loggerLevel:?FULL?#??日志級別

          而日志的級別分為四種:

          NONE:不記錄任何日志信息,這是默認值。

          BASIC:僅記錄請求的方法,URL以及響應狀態碼和執行時間

          HEADERS:在BASIC的基礎上,額外記錄了請求和響應的頭信息

          FULL:記錄所有請求和響應的明細,包括頭信息、請求體、元數據。

          2.2.Java代碼方式

          也可以基于Java代碼來修改日志級別,先聲明一個類,然后聲明一個Logger.Level的對象:

          public?class?DefaultFeignConfiguration??{????@Bean????public?Logger.Level?feignLogLevel(){????????return?Logger.Level.BASIC;?//?日志級別為BASIC????}}

          如果要全局生效,將其放到啟動類的@EnableFeignClients這個注解中:

          package?cn.itcast.order;import?cn.itcast.order.config.DefaultFeignConfiguration;import?com.netflix.loadbalancer.IRule;import?com.netflix.loadbalancer.RandomRule;import?org.mybatis.spring.annotation.MapperScan;import?org.springframework.boot.SpringApplication;import?org.springframework.boot.autoconfigure.SpringBootApplication;import?org.springframework.cloud.client.loadbalancer.LoadBalanced;import?org.springframework.cloud.openfeign.EnableFeignClients;import?org.springframework.context.annotation.Bean;import?org.springframework.web.client.RestTemplate;@MapperScan("cn.itcast.order.mapper")????@SpringBootApplication????//?配置類的方式開啟全局日志記錄????//@EnableFeignClients(defaultConfiguration?=?DefaultFeignConfiguration.class)?//?開啟feign客戶端的支持????@EnableFeignClients?//?開啟feign客戶端的支持????public?class?OrderApplication?{????????public?static?void?main(String[]?args)?{????????????SpringApplication.run(OrderApplication.class,?args);????????}????????//......????}

          如果是局部生效,則把它放到對應的@FeignClient這個注解中:

          package?cn.itcast.order.feign;import?cn.itcast.order.config.DefaultFeignConfiguration;import?cn.itcast.order.pojo.User;import?org.springframework.cloud.openfeign.FeignClient;import?org.springframework.web.bind.annotation.GetMapping;import?org.springframework.web.bind.annotation.PathVariable;//?指定服務日志配置//@FeignClient(value?=?"userservice",configuration?=?DefaultFeignConfiguration.class)@FeignClient(value?=?"userservice")????public?interface?UserFeignClient?{????????@GetMapping("/user/{id}")????????User?queryById(@PathVariable("id")?Long?id);????}

          2.3.Feign使用優化

          Feign底層發起http請求,依賴于其它的框架。其底層客戶端實現包括:

          ?URLConnection:默認實現,不支持連接池

          ?Apache HttpClient :支持連接池

          ?OKHttp:支持連接池

          因此提高Feign的性能主要手段就是使用連接池代替默認的URLConnection。

          這里我們用Apache的HttpClient來演示。

          1)引入依賴

          在order-service的pom文件中引入Apache的HttpClient依賴:

          <!--httpClient的依賴?--><dependency>??<groupId>io.github.openfeign</groupId>??<artifactId>feign-httpclient</artifactId></dependency>

          2)配置連接池

          在order-service的application.yml中添加配置:

          feign:??client:????config:??????default:?#?default全局的配置????????loggerLevel:?BASIC?#?日志級別,BASIC就是基本的請求和響應信息??httpclient:????enabled:?true?#?開啟feign對HttpClient的支持????max-connections:?200?#?最大的連接數????max-connections-per-route:?50?#?每個路徑的最大連接數

          max-connections解釋:比如有以下情況,有一個服務A同時有可能會訪問B服務和C服務,這時候配置的最大連接數指的就是A在訪問B和C時,總的連接數不超過200。

          max-connections-per-route解釋:指的是A服務訪問B服務時的路徑最大連接數據為50,也就是200個連接,A服務到B服務的訪問最多只會有50個連接,當超出50個連接時,其他連接就會路由到B服務之外的服務中。

          接下來,在FeignClientFactoryBean中的loadBalance方法中打斷點:

          Debug方式啟動order-service服務,可以看到這里的client,底層就是Apache HttpClient:

          改成http連接池后,從演示項目后臺的請求日志中可以發現會從原來的幾十ms變成個位數ms,有興趣的小伙伴可以自己測試一下。

          2.4.最佳實踐-抽取feign-api接口

          目前存在一個問題,我們目前演示的是只有一個order-service調用user-service,那如果當有多個服務要去調userservice的時候呢,那是否需要在每個service里都去寫一份遠程調用user-service的代碼?完成沒必要是不是?所以,把這部分代碼直接抽成一個module打成jar包,在需要調用的地方引入即可。

          將Feign的Client抽取為獨立模塊,并且把接口有關的POJO、默認的Feign配置都放到這個模塊中,提供給所有消費者使用。

          即將UserClient、User、Feign的默認配置都抽取到一個feign-api包中,所有微服務引用該依賴包,即可直接使用。

          1)抽取

          首先創建一個module,命名為feign-api:

          項目結構:

          在feign-api中然后引入feign的starter依賴

          <dependency>??<groupId>org.springframework.cloud</groupId>??<artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

          然后,order-service中編寫的UserClient、User、DefaultFeignConfiguration都復制到feign-api項目中

          2)在order-service中使用feign-api

          首先,刪除order-service中的UserClient、User、DefaultFeignConfiguration等類或接口。

          在order-service的pom文件中中引入feign-api的依賴:

          <dependency>??<groupId>cn.itcast.demo</groupId>??<artifactId>feign-api</artifactId>??<version>1.0</version></dependency>

          修改order-service中的所有與上述三個組件有關的導包部分,改成導入feign-api中的包

          掃描包問題

          最后,包的掃描要指定一下,不然啟動會報錯找不到userfeignclient

          方式一:

          指定Feign應該掃描的包:

          @EnableFeignClients(basePackages = "cn.itcast.feign.clients")

          方式二:

          指定需要加載的Client接口:

          @EnableFeignClients(clients = {UserClient.class})

          Feign實現原理

          Feign的底層源碼實現主要包括以下幾個部分:

          1. 接口定義

          Feign的接口定義類似于Java的接口定義,但是它使用了注解來描述HTTP請求的參數和返回值。例如,@RequestMapping注解用于指定HTTP請求的URL和請求方法,@RequestParam注解用于指定HTTP請求的參數,@RequestBody注解用于指定HTTP請求的請求體,@PathVariable注解用于指定HTTP請求的路徑參數等。

          2. 動態代理

          Feign使用了Java的動態代理技術來生成HTTP請求的實現類。當應用程序調用Feign接口的方法時,Feign會動態生成一個HTTP請求的實現類,并將請求參數傳遞給該實現類。該實現類會將請求參數轉換為HTTP請求,并發送給遠程服務。當遠程服務返回響應時,該實現類會將響應轉換為Java對象,并返回給應用程序。

          3. 編碼器和解碼器

          Feign使用了編碼器和解碼器來將Java對象轉換為HTTP請求和響應。編碼器將Java對象轉換為HTTP請求的請求體,解碼器將HTTP響應的響應體轉換為Java對象。Feign支持多種編碼器和解碼器,例如JSON編碼器和解碼器、XML編碼器和解碼器等。

          4. 負載均衡

          Feign可以與負載均衡器無縫集成,以實現服務的負載均衡。當應用程序調用Feign接口的方法時,Feign會將請求發送給負載均衡器,負載均衡器會選擇一個可用的服務實例,并將請求轉發給該實例。如果該實例不可用,則負載均衡器會選擇另一個可用的服務實例,并將請求轉發給該實例。

          5. 斷路器

          Feign可以與斷路器無縫集成,以實現服務的容錯。當應用程序調用Feign接口的方法時,Feign會將請求發送給斷路器,斷路器會檢查服務實例的可用性。如果服務實例不可用,則斷路器會返回一個默認的響應,以避免應用程序出現異常。如果服務實例可用,則斷路器會將請求轉發給該實例,并返回實例的響應。

          關鍵詞:

          下一篇:福建京劇院優秀青年演員折子戲展演精彩紛呈 “00后”主演嶄露頭角
          上一篇:最后一頁

           
          国产三级日本三级日产三级66,五月天激情婷婷大综合,996久久国产精品线观看,久久精品人人做人人爽97
          • <bdo id="qgeso"></bdo>
              • <strike id="qgeso"></strike>
              • <sup id="qgeso"></sup><center id="qgeso"></center>
              • <input id="qgeso"></input>
                主站蜘蛛池模板: 色欲精品国产一区二区三区AV| 久久久无码人妻精品无码| 亚洲午夜爱爱香蕉片| GOGOGO高清在线观看中文版| 高清破外女出血视频| 最新国产三级在线不卡视频| 在线观看中文字幕第一页| 国产在线无码精品电影网| 亚洲精品无码专区在线| 中文字幕无码视频专区| 四虎1515hh永久久免费| 狂野黑人性猛交xxxxxx| 成年人在线免费观看| 国产破外女出血视频| 人人妻人人玩人人澡人人爽| 久久久久大香线焦| 超兴奋的朋…中文字幕| 欧美aaaa在线观看视频免费| 国产猛男猛女超爽免费视频| 五十路亲子中出中文字幕| 黑人巨大精品欧美一区二区免费| 武林高贵肥臀胖乳美妇 | 国产欧美一区二区精品久久久| 亲密爱人完整版在线观看韩剧| bt√天堂资源在线官网| 精品国产亚洲AV麻豆| 日本老熟妇xxxxx| 国产日韩一区二区三区在线观看 | 麻豆精产国品一二三产品区| 欧美日韩国产一区二区 | 久久精品无码一区二区www| 97久人人做人人妻人人玩精品 | eeuss影院在线观看| 毛片基地在线观看| 国产精品亚洲精品日韩已方| 亚洲欧美综合视频| a在线观看免费| 欧美性黑人极品hd| 国产精品酒店视频免费看| 亚洲精品国精品久久99热 | 精品无码人妻一区二区三区品|