?作者簡介:大家好,我是Leo,熱愛Java后端開發(fā)者,一個想要與大家共同進步的男人????
??個人主頁:Leo的博客
??當前專欄: 微服務(wù)探索之旅
?特色專欄: MySQL學(xué)習(xí)
??本文內(nèi)容:微服務(wù)遠程調(diào)用openFeign整合
???個人小站 :個人博客,歡迎大家訪問
??個人知識庫: 知識庫,歡迎大家訪問
在上一節(jié) Ribbon和 Nacos服務(wù)注冊中心, 我們學(xué)習(xí)了使用nacos進行服務(wù)注冊和服務(wù)發(fā)現(xiàn)以及Ribbon負載均衡以及他的簡單原理剖析。這一節(jié)我們來繼續(xù)認識SpringCloud
的一些核心組件openFeign
。
1. 問題分析
先來看我們以前利用RestTemplate發(fā)起遠程調(diào)用的代碼:
存在的問題:
- 在服務(wù)消費者中,我們把
url
地址硬編碼到代碼中,不方便后期維護。 - 在服務(wù)消費者中,不清楚服務(wù)提供者的狀態(tài)。
- 服務(wù)消費者調(diào)用服務(wù)提供者時候,如果出現(xiàn)故障能否及時發(fā)現(xiàn)不向用戶拋出異常頁面?
- RestTemplate這種請求調(diào)用方式是否還有優(yōu)化空間?能不能類似于Dubbo那樣玩?
2. 了解Feign
Feign
是一個聲明式的http客戶端,官方地址:https://github.com/OpenFeign/feign
其作用就是幫助我們優(yōu)雅的實現(xiàn)http請求的發(fā)送,解決上面提到的問題。
3. 項目整合Feign
Fegin的使用步驟如下:
3.1 引入依賴
我們在order-service服務(wù)的pom文件中引入feign的依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
3.2 添加注解
在order-service
的啟動類添加注解開啟Feign
的功能:
3.3 編寫Feign客戶端
package com.cisyam.order.client;
import com.cisyam.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* @author gaoziman
*/
@FeignClient("userservice")
public interface UserClient {
/**
* 通過用戶后編號去獲取用戶對象
* @param id
* @return
*/
@GetMapping("/user/{id}")
User findById(@PathVariable("id") Long id);
}
這個客戶端主要是基于SpringMVC的注解來聲明遠程調(diào)用的信息,比如:
- 服務(wù)名稱:
userservice
- 請求方式:
GET
- 請求路徑:
/user/{id}
- 請求參數(shù):
Long id
- 返回值類型:
User
這樣,Feign
就可以幫助我們發(fā)送http
請求,無需自己使用RestTemplate來發(fā)送了。
3.4 測試
修改order-service中的OrderService
類中的queryOrderById
方法,使用Feign客戶端代替RestTemplate:
3.5 總結(jié)
使用Feign的步驟:
① 引入依賴
② 添加@EnableFeignClients注解
③ 編寫FeignClient接口
④ 使用FeignClient中定義的方法代替RestTemplate
4. 自定義配置
Feign可以支持很多的自定義配置,如下表所示:
類型 | 作用 | 說明 |
---|---|---|
feign.Logger.Level | 修改日志級別 | 包含四種不同的級別:NONE、BASIC、HEADERS、FULL |
feign.codec.Decoder | 響應(yīng)結(jié)果的解析器 | http遠程調(diào)用的結(jié)果做解析,例如解析json字符串為java對象 |
feign.codec.Encoder | 請求參數(shù)編碼 | 將請求參數(shù)編碼,便于通過http請求發(fā)送 |
feign. Contract | 支持的注解格式 | 默認是SpringMVC的注解 |
feign. Retryer | 失敗重試機制 | 請求失敗的重試機制,默認是沒有,不過會使用Ribbon的重試 |
一般情況下,默認值就能滿足我們使用,如果要自定義時,只需要創(chuàng)建自定義的@Bean覆蓋默認Bean即可。
下面以日志為例來演示如何自定義配置。
4.1 配置文件方式
基于配置文件修改feign的日志級別可以針對單個服務(wù):
feign:
client:
config:
userservice: # 針對某個微服務(wù)的配置
loggerLevel: FULL # 日志級別
也可以針對所有服務(wù):
feign:
client:
config:
default: # 這里用default就是全局配置,如果是寫服務(wù)名稱,則是針對某個微服務(wù)的配置
loggerLevel: FULL # 日志級別
而日志的級別分為四種:
- NONE:不記錄任何日志信息,這是默認值。
- BASIC:僅記錄請求的方法,URL以及響應(yīng)狀態(tài)碼和執(zhí)行時間
- HEADERS:在BASIC的基礎(chǔ)上,額外記錄了請求和響應(yīng)的頭信息
- FULL:記錄所有請求和響應(yīng)的明細,包括頭信息、請求體、元數(shù)據(jù)。
4.2 Java代碼方式
也可以基于Java代碼來修改日志級別,先聲明一個類,然后聲明一個Logger.Level的對象:
public class DefaultFeignConfiguration {
@Bean
public Logger.Level feignLogLevel(){
return Logger.Level.BASIC; // 日志級別為BASIC
}
}
如果要全局生效,將其放到啟動類的@EnableFeignClients這個注解中:
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)
如果是局部生效,則把它放到對應(yīng)的@FeignClient這個注解中:
@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class)
5. Feign使用優(yōu)化
Feign底層發(fā)起http請求,依賴于其它的框架。其底層客戶端實現(xiàn)包括:
- URLConnection:默認實現(xiàn),不支持連接池
- Apache HttpClient :支持連接池
- OKHttp:支持連接池
因此提高Feign的性能主要手段就是使用連接池代替默認的URLConnection。
這里我們用Apache的HttpClient來演示。
5.1 引入依賴
在order-service的pom文件中引入Apache的HttpClient依賴:
<!--httpClient的依賴 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
5.2 配置連接池
在order-service的application.yml中添加配置:
feign:
client:
config:
default: # default全局的配置
loggerLevel: BASIC # 日志級別,BASIC就是基本的請求和響應(yīng)信息
httpclient:
enabled: true # 開啟feign對HttpClient的支持
max-connections: 200 # 最大的連接數(shù)
max-connections-per-route: 50 # 每個路徑的最大連接數(shù)
接下來,在FeignClientFactoryBean
中的loadBalance
方法中打斷點:
Debug方式啟動order-service服務(wù),可以看到這里的client,底層就是Apache HttpClient
:
總結(jié),Feign的優(yōu)化:
- 日志級別盡量用basic
- 使用
HttpClient
或OKHttp
代替URLConnection
- 引入
feign-httpClient
依賴 - 配置文件開啟
httpClient
功能,設(shè)置連接池參數(shù)
- 引入
6. Feign最佳實踐
所謂 最佳時間,就是使用過程中總結(jié)的經(jīng)驗,最好的一種使用方式。
仔細的同學(xué)可以觀察可以發(fā)現(xiàn),Feign
的客戶端與服務(wù)提供者的controller代碼非常相似:
feign客戶端:
UserController:
有沒有一種辦法簡化這種重復(fù)的代碼編寫呢 ?大家想到的結(jié)局方式是什么呢 ?
這里提供兩種解決方式,看看你有沒有想到呢
6.1 繼承方式
一樣的代碼可以通過繼承來共享:
- 定義一個API接口,利用定義方法,并基于SpringMVC注解做聲明。
- Feign客戶端和Controller都集成改接口
優(yōu)點:
- 簡單
- 實現(xiàn)了代碼共享
缺點:
-
服務(wù)提供方、服務(wù)消費方緊耦合
-
參數(shù)列表中的注解映射并不會繼承,因此Controller中必須再次聲明方法、參數(shù)列表、注解
6.2 抽取方式
將Feign
的Client
抽取為獨立模塊,并且把接口有關(guān)的POJO、默認的Feign配置都放到這個模塊中,提供給所有消費者使用。
例如,將UserClient、User、Feign
的默認配置都抽取到一個feign-api包中,所有微服務(wù)引用該依賴包,即可直接使用。
文章來源:http://www.zghlxwxcb.cn/news/detail-487775.html
今天就到這里了,下一節(jié)我們繼續(xù)學(xué)習(xí)分享SpringCloud的相關(guān)組件----GateWay網(wǎng)關(guān)組件
,歡迎大家評論區(qū)留言討論!文章來源地址http://www.zghlxwxcb.cn/news/detail-487775.html
到了這里,關(guān)于微服務(wù)遠程調(diào)用openFeign整合的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!