您好,登錄后才能下訂單哦!
這篇文章主要介紹“springcloud整合openfeign使用的方法是什么”,在日常操作中,相信很多人在springcloud整合openfeign使用的方法是什么問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”springcloud整合openfeign使用的方法是什么”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
隨著微服務治理手段越來越多,對開發者來說,不同微服務之間的接口調用是日常開發中非常普遍的事情,以springcloud生態體系的微服務治理方案,或者dubbo解決方案,各自都提供了不同的接口處理方式,需要根據自身的情況進行合理的選擇。
在正式學習openfeign之前,大家是否記得在日常項目的開發中,是如何實現不同微服務之間的接口調用的呢?下面列舉幾種在Java項目中常用到的幾種組件。
HttpClient是Apache 的子項目,用以提供高效、最新、功能豐富的支持http協議的客戶端編程工具包,并且支持 HTTP協議最新版本。
相比傳統 JDK自帶的 URLConnection,提升了易用性和靈活性,使客戶端發送 HTTP 請求變得容易,提高了開發的效率。
一個用以處理網絡請求的開源項目,是安卓端最火的輕量級框架,由 Square 公司貢獻,用于替代
HttpUrlConnection 和 Apache HttpClient。
OkHttp 擁有簡潔的 API、高效的性能,并支持多種協議(HTTP/2 和 SPDY)。
HttpURLConnection是Java 的標準類,它繼承自URLConnection,可用于向指定網站發送
get、post請求,HttpURLConnection 相比HttpClient使用比較復雜。
RestTemplate 是 Spring 提供的用于訪問 Rest 服務的客戶端,RestTemplate 提供了多種便
捷訪問遠程 HTTP 服務的方法,能夠大大提升客戶端編寫效率。
上面介紹了常見的幾種接口調用方法,接下來要介紹的方法比上面更簡單方便,它就是Feign。
Feign是Netflix開發的聲明式、模板化的HTTP客戶端;Feign可幫助開發者更加便捷、優雅地調用HTTP API;Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等;
Feign可以做到使用 HTTP 請求遠程服務時就像調用本地方法一樣的體驗,開發者完全感知不
到這是遠程方法,更感知不到這是個 HTTP 請求。具體來說:
它像 Dubbo 一樣,consumer 直接調用接口方法調用 provider,而不需要通過常規的 Http Client 構造請求再解析返回數據;它解決了讓開發者調用遠程接口就跟調用本地方法一樣,無需關注與遠程的交互細節,更無需關注分布式環境開發;
接下來,通過實際的操作,演示如何基于Spring Cloud Alibaba實現與OpenFeign的整合
創建一個新的order模塊,工程結構和目錄如下
添加如下依賴,主要是open-feign的依賴
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--nacos-config 配置中心-自帶動態刷新--> <!--<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>--> <!--nacos-discovery 注冊中心-服務發現與注冊--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies>
使用過dubbo的同學應該對此不陌生,使用服務端提供的接口時只需要注入就可以像調用本地方法一樣使用了,feign的使用也是類似,只需在調用方定義一個接口類,里面添加被調用的接口中的完整的方法名,參數等,即保持與接口中的方法體參數一致即可;
比如在order模塊調用stock模塊時,stock的接口類提供了下面的方法
@GetMapping("/reduct") public String reduct(){ System.out.println("扣減庫存 : 8021"); return "扣減庫存 : 8021"; }
那么在order模塊中,自定義一個接口類,如下
@FeignClient(name = "stock-service",path = "/stock") public interface StockFeignService { @GetMapping("/reduct") public String reduct(); }
參數說明:
該接口中的方法名,參數,請求類型等都與接口提供方接口保持一致;
接口上面用FeignClient注解修飾,name為服務提供方名稱,path為接口根路徑;
在之前的調用中,我們一直使用的是restTemplate的方式調用,如果使用了feign,調用看起來就變得簡單了,做一下簡單的改造即可;
@RestController @RequestMapping("/order") public class OrderController { @Value("${service-url.nacos-user-service}") private String serverURL; @Autowired private StockFeignService stockFeignService; //localhost:8083/order/add @GetMapping("/add") public String add(){ System.out.println("下單成功"); String reduct = stockFeignService.reduct(); return "add order :" + reduct; } } @RestController @RequestMapping("/order") public class OrderController { @Value("${service-url.nacos-user-service}") private String serverURL; @Autowired private StockFeignService stockFeignService; //localhost:8083/order/add @GetMapping("/add") public String add(){ System.out.println("下單成功"); String reduct = stockFeignService.reduct(); return "add order :" + reduct; } }
這里調整一下端口即可
server: port: 8040 spring: application: name: order-service cloud: nacos: discovery: server-addr: localhost:8848 #服務注冊中心地址
啟動stock-service的兩個工程,再啟動order模塊,啟動完成后,瀏覽器進行接口調用
反復調用,默認情況下,呈現輪詢的效果
Feign 提供了很多的擴展機制,讓開發者可以更靈活的使用這些機制擴展系統的功能。
使用了Feign之后,有時候開發過程中遇到Bug,比如接口調用失敗、參數沒收到等問題,或者想看看調用性能,這就需要配置Feign的日志了,以便讓Feign把請求的完整信息輸出來定位和分析問題。配置過程也很簡單,只需要添加一個配置類, 定制Feign提供的Logger級別即可。
添加如下配置類,指定level的級別為FULL,表示輸出完整的日志信息
import feign.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignConfig { @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } }
也可以根據自身的需求配置其他的日志級別,從源碼中可以看到提供了多種級別的配置
默認情況下,服務工程以info級別輸出,但Feign的日志級別為debug,兩者不匹配,所以還需要額外做一下配置,在配置文件中補充下面的配置即可,即針對
logging: level: com.congge.feign: debug
在order模塊的Feign中添加一個新的接口進行調用
@GetMapping("/get") public String get(@RequestParam("id") Integer id);
接口調用
//localhost:8040/order/get @GetMapping("/get") public String get(){ String stockInfo = stockFeignService.get(1); return stockInfo; }
瀏覽器執行調用:localhost:8040/order/get,說明調用成功
此時再看控制臺,發現輸出了詳細的調用日志信息
上面配置的這種方式是針對全局生效的,即Feign包路徑下的所有類都生效,如果僅僅是針對某個具體的類生效,該怎么做呢?其實也很簡單,只需要下面的兩步;
與上面的想必,去掉那個@Configuration注解即可
import feign.Logger; import org.springframework.context.annotation.Bean; public class FeignConfig { @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } }
在@FeignClient注解中有一個configuration的熟悉,使用上面的配置類即可
@FeignClient(name = "stock-service",path = "/stock",configuration = FeignConfig.class) public interface StockFeignService { @GetMapping("/reduct") public String reduct(); @GetMapping("/get") public String get(@RequestParam("id") Integer id); }
在5.2.1的基礎上,也可以不用通過5.2.2的方式通過指定配置類添加,而是在配置文件中指定,只需要在配置文件中添加下面的配置即可;
feign: client: config: stock-service: loggerLevel: FULL
配置完成后調用一下,控制臺仍然可以輸出完整的調用日志信息
Spring Cloud 在 Feign 的基礎上做了擴展,使用 Spring MVC 的注解來完成Feign的功
能,以減少使用者的學習成本。
而原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的
注解方式來定義客戶端也是可以的,通過配置契約來改變這個配置,Spring Cloud 中默認的
是 SpringMvcContract。
Spring Cloud 1 早期版本就是用的原生Fegin. 隨著netflix的停更替換成了Open feign
接下來看具體的操作過程
在配置類中添加Contract 的bean
@SpringBootApplication //@EnableDiscoveryClient @EnableFeignClients public class FeignOrderApp { public static void main(String[] args) { SpringApplication.run(FeignOrderApp.class, args); } @Bean public Contract feignContract() { return new Contract.Default(); } }
注意:修改契約配置后,OrderFeignService 不再支持springmvc的注解,需要使用Feign原
生的注解
接口中的調用改為如下(更多語法配置可以參閱相關資料)
@FeignClient(name = "stock-service",path = "/stock") public interface StockFeignServiceV2 { @RequestLine("GET /reduct") public String reduct(); @RequestLine("GET /get") public String get(@Param("id") Integer id); }
再次啟動order模塊服務,然后在瀏覽器調用
在6.1.1 基礎上,將契約的配置配置到配置文件中也可以實現相同的效果,具體如下
feign: client: config: stock-service: loggerLevel: FULL #配置契約 concontract: feign.Contract.Default
客戶端微服務通過Fiegn調用其他微服務接口時,可能因為某些原因導致接口響應超時達到默認的設置時間而調用失敗,如果業務允許超時時長更長一點的話,就可以考慮手動配置openfeign的超時時間;
在上述的配置類中添加下面的超時配置bean;
通過 Options 可以配置連接超時時間和讀取超時時間;
Options 的第一個參數是連接的超時時間(ms),默認值是 2s;
Options 的第一個參數是連接的超時,第二個是請求處理的超時時間(ms),默認值是 5s;
@Bean public Request.Options options() { return new Request.Options(5000, 10000); }
核心配置如下
feign: client: config: stock-service: loggerLevel: FULL #配置契約 #concontract: feign.Contract.Default connectTimeout: 5000 readTimeout: 3000
補充說明: Feign的底層用的是Ribbon,但超時時間以Feign配置為準
為了模擬效果,將調用的stock-service中的接口加一個sleep時間
@GetMapping("/get") public String get(@RequestParam("id") Integer id) throws InterruptedException { Thread.sleep(4000); return "查詢到的庫存商品ID : " + id; }
啟動兩個模塊的工程,瀏覽器調用接口:localhost:8040/order/get,將會看到下面的效果
同時觀察控制臺輸出日志,可以看到輸出了 超時的信息;
使用過springmvc攔截器的同學對攔截器應該不陌生,攔截器可以在請求真正到達后端接口之前做一下預處理工作,比如非法請求攔截、參數校驗過濾、全局token的認證、加解密、審計等等,在openfeign 中也提供了類似的可以自定義的攔截器,其存在的目的主要是針對服務調用端在調用服務接口時可以做的一些預處理工作。
接下來演示如何在openfeign 中自定義攔截器;
主要是實現RequestInterceptor 接口,重寫里面的apply方法即可,比如在下面的apply方法中,給請求頭中添加了兩個參數,這樣的話,服務提供方就可以解析到header中參數的值;
import feign.RequestInterceptor; import feign.RequestTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.UUID; public class FeignInterceptor implements RequestInterceptor { static final Logger logger = LoggerFactory.getLogger(FeignInterceptor.class); @Override public void apply(RequestTemplate requestTemplate) { logger.info("enter FeignInterceptor ..."); String accessToken=UUID.randomUUID().toString(); requestTemplate.header("accessToken",accessToken); requestTemplate.header("username","jerry"); } }
可以通過配置全局bean的方式或者在yaml中配置都可以
配置bean的方式
@Bean public FeignInterceptor feignInterceptor() { return new FeignInterceptor(); }
配置文件方式
feign: client: config: stock-service: loggerLevel: FULL connectTimeout: 5000 readTimeout: 3000 #自定義攔截器 requestInterceptors: com.congge.config.FeignInterceptor
這里將請求中的參數進行解析,并打印輸出結果
@GetMapping("/get") public String get(@RequestParam("id") Integer id) throws InterruptedException { String accessToken = request.getHeader("accessToken"); System.out.println(accessToken); String username = request.getHeader("username"); System.out.println(username); //Thread.sleep(4000); return "查詢到的庫存商品ID : " + id; }
分別啟動stock模塊的工程和order模塊的工程,然后瀏覽器調用:localhost:8040/order/get
接口可以正常返回結果;
觀察stock服務控制臺,header中的參數值也能正確的被解析出來;
這是一種很有用的技巧,尤其是內部各個微服務之間進行調用的時候,為了確認對方的身份是否授信或者互信,可以通過這種方式傳遞一些可以加解密的參數進行身份確認。
到此,關于“springcloud整合openfeign使用的方法是什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。