用例spring_cloud_feign
項目地址:傳送門
一、服務調用Feign入門
前面我們使用的RestTemplate實現REST API調用,代碼大致如下:
/** * 基於ribbon的形式調用遠程微服務 * 1.使用@LoadBalanced聲明RestTemplate * 2.使用服務名稱替換ip地址 */ @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET) public Product findById(@PathVariable Long id) { //服務名稱service-product替換ip地址 Product product = restTemplate.getForObject("http://service-product/product/"+id,Product.class); return product; }
由代碼可知,我們是使用拼接字符串的方式構造URL的,該URL只有一個參數。但是,在現實中,URL 中往往含有多個參數。這時候我們如果還用這種方式構造URL,那么就會非常痛苦。那應該如何解決?我們帶着這樣的問題進入到本章的學習。
1、Feign簡介
Feign是Netflix開發的聲明式,模板化的HTTP客戶端,其靈感來自Retrofit,JAXRS-2.0以及WebSocket.
-
Feign可幫助我們更加便捷,優雅的調用HTTP API。
-
在SpringCloud中,使用Feign非常簡單——創建一個接口,並在接口上添加一些注解,代碼就完成了。
-
Feign支持多種注解,例如Feign自帶的注解或者JAX-RS注解等。
-
SpringCloud對Feign進行了增強,使Feign支持了SpringMVC注解,並整合了Ribbon和Eureka,從而讓Feign的使用更加方便。
2、基於Feign的服務調用
(1)引入依賴
在服務消費者 order_service 添加Fegin依賴
<!--springcloud整合的openFeign--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
(2)訂單模塊啟動類添加Feign的支持
通過@EnableFeignClients注解開啟Spring Cloud Feign的支持功能
@SpringBootApplication @EntityScan("cn.hzp.order.domain") //激活Feign @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class,args); } }
(3)配置調用商品服務的接口
/** * 聲明需要調用的微服務名稱 * @FeignClient * * name : 服務提供者的名稱 */ @FeignClient(name="service-product") public interface ProductFeignClient { /** * 配置需要調用的微服務接口 */ @RequestMapping(value="/product/{id}",method = RequestMethod.GET) public Product findById(@PathVariable("id") Long id); }
(4)訂單服務通過自動的接口調用商品服務
其程序最終還是通過Feign轉化成restTemplate方式調用商品服務。
@RestController @RequestMapping("/order") public class OrderController { @Autowired private ProductFeignClient productFeignClient; /** * 通過Feign方式,聲明式調用接口 */ @RequestMapping(value = "/buy/{id}",method = RequestMethod.GET) public Product findById(@PathVariable Long id) { //調用接口實現調用商品服務。本質上還是調用restTemplate的方式,feign會進行轉化 Product product= productFeignClient.findById(id); // Product product = restTemplate.getForObject("http://service-product/product/"+id,Product.class); return product; } }
(5)測試效果
3、Feign 和Ribbon的聯系
Ribbon是一個基於 HTTP 和 TCP 客戶端 的負載均衡的工具。它可以 在客戶端 配置RibbonServerList(服務端列表),使用 HttpClient 或 RestTemplate 模擬http請求,步驟相當繁瑣。
Feign 是在 Ribbon的基礎上進行了一次改進,是一個使用起來更加方便的 HTTP 客戶端。采用接口的方式, 只需要創建一個接口,然后在上面添加注解即可 ,將需要調用的其他服務的方法定義成抽象方法即可, 不需要自己構建http請求。然后就像是調用自身工程的方法調用,而感覺不到是調用遠程方法,使得編寫客戶端變得非常容易
4、負載均衡
Feign 中本身已經集成了Ribbon依賴和自動配置,因此我們不需要額外引入依賴,也不需要再注冊RestTemplate 對象。另外,我們可以像上節課中講的那樣去配置Ribbon,可以通過 ribbon.xx 來進行全局配置。也可以通過 服務名 .ribbon.xx 來對指定服務配置:
啟動兩個 product_service,端口為9001,9011 ,重新測試可以發現使用Ribbon的輪詢策略進行負載均衡
二、服務調用Feign高級
1、Feign的配置
從Spring Cloud Edgware開始,Feign支持使用屬性自定義Feign。對於一個指定名稱的Feign Client(例如該Feign Client的名稱為 feignName ),Feign支持如下配置項:
feign: client: config: feignName: ##定義FeginClient的名稱 connectTimeout: 5000 # 相當於Request.Options readTimeout: 5000 # 相當於Request.Options # 配置Feign的日志級別,相當於代碼配置方式中的Logger loggerLevel: full # Feign的錯誤解碼器,相當於代碼配置方式中的ErrorDecoder errorDecoder: com.example.SimpleErrorDecoder # 配置重試,相當於代碼配置方式中的Retryer retryer: com.example.SimpleRetryer # 配置攔截器,相當於代碼配置方式中的RequestInterceptor requestInterceptors: - com.example.FooRequestInterceptor - com.example.BarRequestInterceptor decode404: false
-
feignName :FeginClient的名稱
-
connectTimeout : 建立鏈接的超時時長
-
readTimeout : 讀取超時時長
-
loggerLevel: Fegin 的日志級別
-
errorDecoder :Feign的錯誤解碼器
-
retryer : 配置重試
-
requestInterceptors : 添加請求攔截器
-
decode404 : 配置熔斷不處理404異常
2、請求壓縮
Spring Cloud Feign 支持對請求和響應進行GZIP壓縮,以減少通信過程中的性能損耗。通過下面的參數即可開啟請求與響應的壓縮功能:
feign: compression: request: enabled: true # 開啟請求壓縮 response: enabled: true # 開啟響應壓縮
同時,我們也可以對請求的數據類型,以及觸發壓縮的大小下限進行設置:
feign: compression: request: enabled: true # 開啟請求壓縮 mime-types: text/html,application/xml,application/json # 設置壓縮的數據類型 min-request-size: 2048 # 設置觸發壓縮的大小下限
注:上面的數據類型、壓縮大小下限均為默認值
3、查看被調用的服務的日志
在開發或者運行階段往往希望看到Feign請求過程的日志記錄,默認情況下Feign的日志是沒有開啟的。要想用屬性配置方式來達到日志效果,只需在 application.yml 中添加如下內容即可:
#配置feign日志的輸出 #日志級別 NONE : 不輸出日志(高) BASIC: 適用於生產環境追蹤問題 HEADERS : 在BASIC的基礎上,記錄請求和響應頭信息 FULL : 記錄所有 feign: client: config: service-product: #需要調用的服務名稱,這里查詢商品服務的日志情況 loggerLevel: FULL #日志級別 logging: level: cn.hzp.order.feign.ProductFeignClient: debug #只查看商品服務接口的調用日志
-
logging.level.xx : debug : Feign日志只會對日志級別為debug的做出響應
-
feign.client.config.shop -service-product.loggerLevel : 配置Feign的日志Feign有四種日志級別:
-
NONE 【性能最佳,適用於生產】:不記錄任何日志(默認值)
-
BASIC 【適用於生產環境追蹤問題】:僅記錄請求方法、URL、響應狀態代碼以及執行時間
-
HEADERS :記錄BASIC級別的基礎上,記錄請求和響應的header。
-
FULL 【比較適用於開發及測試環境定位問題】:記錄請求和響應的header、body和元數據。
-
4、 源碼分析