Feign是一種聲明式、模板化的HTTP客戶端(僅在Application Client中使用)。聲明式調用是指,就像調用本地方法同樣調用遠程方法,無需感知操做遠程http請求。
Spring Cloud的聲明式調用, 能夠作到使用 HTTP請求遠程服務時能就像調用本地方法同樣的體驗,開發者徹底感知不到這是遠程方法,更感知不到這是個HTTP請求。Feign的應用,讓Spring Cloud微服務調用像Dubbo同樣,Application Client直接經過接口方法調用Application Service,而不須要經過常規的RestTemplate構造請求再解析返回數據。它解決了讓開發者調用遠程接口就跟調用本地方法同樣,無需關注與遠程的交互細節,更無需關注分佈式環境開發。html
在總體微服務開發中,Eureka Server做爲註冊中心必不可少,註冊中心的做用不變,仍舊是註冊和發現服務。java
服務標準工程,是用於定義Application Service須要對外發布的服務標準接口的工程。這個工程中定義的接口須要使用SpringMVC中的註解來描述,因此工程依賴的資源必須有SpringMVC。在案例中,爲了簡化依賴複雜度,使用spring-boot中的spring-boot-starter-web資源依賴實現SpringMVC技術的導入。git
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.16.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>spring-cloud-feign-serviceapi</artifactId> <version>1.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <!-- 主要使用其中的SpringMVC相關技術。將請求的URL和服務的方法耦合到一塊兒。 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
定義的服務接口和普通的服務接口沒有太大的區別,可是爲了讓Feign技術能夠識別到服務的訪問URL,須要使用SpringMVC註解@RequestMapping來描述接口中定義的方法,表明方法對外提供服務時監聽的URL路徑是什麼。github
/** * 微服務標準。 * 是Application Service要提供的服務的標準。 * 也是Application Client要調用遠程服務的標準。 * 就是一個普通的接口。 */ public interface FirstFeignService { /** * 測試GET請求的方法。 * 請求不傳遞任何的參數。 * 請求地址是 - /testFeign -> http://ip:port/testFeign * @return */ @RequestMapping(value="/testFeign", method=RequestMethod.GET) public List<String> testFeign(); /** * 測試GET請求傳遞一個普通的參數。 /get?id=xxx * 在爲Feign定義服務標準接口的時候,處理請求參數的方法參數,必須使用@RequestParam註解描述。 * 而且,不管方法參數名和請求參數名是否一致,都須要定義@RequestParam註解的value/name屬性。 * @return */ @RequestMapping(value="/get", method=RequestMethod.GET) public FeignTestPOJO getById(@RequestParam(value="id") Long id); /** * 測試使用POST請求傳遞一個普通參數 * 在Feign技術中,默認的發起POST請求的時候,請求的參數,都是在請求體中使用JSON數據傳遞的。 * 不是name=value對傳遞的。 * 必須使用@RequestBody註解來解析請求體中的數據。 * * 若是使用POST方式發起請求,傳遞多個普通參數,是使用請求頭傳遞的參數。可使用@RequestParam註解來處理請求參數。 * POST請求的請求體類型仍是application/json。feign會經過請求頭傳遞多個請求參數: /xxx?a=xxx&b=xxx&c=xxx * @return */ @RequestMapping(value="/get", method=RequestMethod.POST) public FeignTestPOJO getByIdWithPOST(@RequestBody Long id); /** * 使用GET請求傳遞多個普通參數。 /add?id=xxx&name=xxx * 必須使用@RequestParam註解處理請求參數。 * @return */ @RequestMapping(value="/add", method=RequestMethod.GET) public FeignTestPOJO add(@RequestParam("id") Long id, @RequestParam("name") String name); /** * 錯誤案例 * 使用GET請求傳遞特殊參數。自定義類型的參數。 * 在Feign發起的默認的請求中,GET請求方式不能傳遞自定義類型數據。只能經過POST請求傳遞。 * @return */ @RequestMapping(value="/addWithGET", method=RequestMethod.GET) public FeignTestPOJO add(@RequestBody FeignTestPOJO pojo); /** * 使用POST請求傳遞特殊參數。自定義類型的參數。 * 默認環境中,只要是Feign發起的POST請求,請求參數都是JSON數據。 * 必須使用@RequestBody處理。 * @return */ @RequestMapping(value="/addWithPOST", method=RequestMethod.POST) public FeignTestPOJO addWithPOST(@RequestBody FeignTestPOJO pojo); }
服務提供者在開發的時候,須要實現服務標準工程中定義的服務接口,並註冊服務到Eureka Server註冊中心上,因此須要依賴的資源必須有eureka和服務標準接口。web
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.16.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>spring-cloud-feign-appservice</artifactId> <version>1.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- web啓動器。 springmvc相關內容 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- spring cloud 默認配置啓動器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- spring cloud Eureka Client 啓動器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- 自定義的服務標準工程。 --> <dependency> <groupId>com.bjsxt</groupId> <artifactId>spring-cloud-feign-serviceapi</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
在Spring Cloud微服務架構中,服務是由Controller對外提供的,是基於HTTP協議發佈的REST服務。因此實現服務接口的是控制器。注意,服務不表明服務層代碼。算法
/** * 自定義的服務控制器 * 對外提供服務的Application Service。 * 不能隨便的定義服務了。若是想讓Application Client能夠經過Feign技術訪問當前類型提供的服務, * 則必須遵循服務標準。 */ @RestController public class TestFeignAppServiceController implements FirstFeignService { /** * 由於當前的方法都是實現接口FirstFeignService中的方法。 * 而在接口中,已經將請求URL和方法耦合到一塊兒了。 * 因此在當前的控制器中,不能重複定義@RequestMapping來約束請求URL。 */ @Override public List<String> testFeign() { List<String> result = new ArrayList<>(); result.add("test feign"); result.add("this is first spring cloud with feign"); return result; } @Override public FeignTestPOJO getById(Long id) { return new FeignTestPOJO(id, "getById"); } /** * 若是方法參數是處理POST請求的JSON數據的。 * 那麼仍是須要定義@RequestBody註解來描述方法參數的。 */ @Override public FeignTestPOJO getByIdWithPOST(@RequestBody Long id) { return new FeignTestPOJO(id, "getByIdWithPOST"); } @Override public FeignTestPOJO add(Long id, String name) { System.out.println( "add(Long id, String name)" ); return new FeignTestPOJO(id, name); } /** * 在默認的狀況下,Feign不能經過GET請求傳遞自定義類型的請求參數。 */ @Override public FeignTestPOJO add(@RequestBody FeignTestPOJO pojo) { System.out.println( "add(@RequestBody FeignTestPOJO pojo)" ); return pojo; } @Override public FeignTestPOJO addWithPOST(@RequestBody FeignTestPOJO pojo) { System.out.println( "addWithPOST(@RequestBody FeignTestPOJO pojo)" ); return pojo; } }
服務消費者在開發的時候,須要在Eureka Server中發現可用服務,並經過Feign來實現遠程服務調用。在這個過程當中,須要依賴於服務標準工程中定義的服務接口。spring
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.16.RELEASE</version> </parent> <groupId>com.bjsxt</groupId> <artifactId>spring-cloud-feign-appclient</artifactId> <version>1.0</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Edgware.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- spring cloud 默認配置啓動器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- spring cloud Eureka Client 啓動器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <!-- feign啓動器。封裝了全部的feign相關資源的jar包。提供的是默認環境。 feign技術在請求遠程服務的時候,依託於http協議。 默認底層使用JDK提供的HttpUrlConnection來實現http遠程訪問的。 httpurlconnection技術不支持http鏈接池。因此效率上較低。 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!-- 服務標準工程。 --> <dependency> <groupId>com.bjsxt</groupId> <artifactId>spring-cloud-feign-serviceapi</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
啓動器:apache
/** * @EnableFeignClients - 啓動FeignClient技術。 * 開啓Feign的應用。 * * @EnableDiscoveryClient - 啓動發現機制。 * 就是輔助Feign技術,發現服務,定義服務動態代理的輔助技術。 * * @EnableEurekaClient 註解刪除。是使用Discovery來發現服務的。discovery是輔助feign技術的一個發現客戶端。 */ @EnableFeignClients @EnableDiscoveryClient @SpringBootApplication public class FeignApplicationClientApplication { public static void main(String[] args) { SpringApplication.run(FeignApplicationClientApplication.class, args); } }
在經過Feign來實現遠程服務調用時,須要提供一個本地接口來繼承服務標準工程提供的服務接口。這個本地接口不須要給予任何實現,在底層Spring容器會爲這個接口提供一個基於JDK實現的代理對象,這個代理對象由Feign技術提供具體的HandlerInterceptor邏輯,實現遠程的調用。實現過程相似經過代碼調用LoadBalancerClient實現的Rest遠程訪問。
而本地接口繼承服務標準接口後,須要提供註解@FeignClient,註解的屬性name表明當前接口要調用的遠程服務的應用命名。json
/** * 本地接口,繼承服務標準接口。 * 在接口上增長註解@FeignClient,表明當前接口是一個Feign技術中的客戶端。 * 須要發起遠程的http請求。 * 註解有屬性name - 表明當前的FeignClient在請求application service的時候,是調用哪個服務? * 所謂的哪個服務,就是application service全局配置文件中的spring.application.name屬性值。 */ @FeignClient(name="test-feign-application-service") public interface FirstClientFeignService extends FirstFeignService { }
控制器中能夠像調用本地定義服務對象那樣來調用遠程服務。api
/** * Application Client中的控制器。是和用戶直接交互的控制器。 * 像平時開發代碼同樣。調用本地的一個service接口。經過service接口遠程訪問Application Service。 */ @RestController public class TestFeignAppClientController { /** * 本地定義的服務接口。用於實現遠程調用application service的接口。 */ @Autowired private FirstClientFeignService service; /** * 無參 * @return */ @GetMapping("/testFeign") public List<String> testFeign(){ System.out.println(this.service.getClass().getName()); return this.service.testFeign(); } }
在Feign處理遠程服務調用時,傳遞參數是經過HTTP協議傳遞的,參數存在的位置是請求頭或請求體中。請求頭傳遞的參數必須依賴@RequestParam註解來處理請求參數,請求體傳遞的參數必須依賴@RequestBody註解來處理請求參數。
上述的要求是指Feign技術傳遞參數,也就是Application Client遠程調用Application Service過程。
使用請求頭傳遞參數時,定義的服務標準接口中,必須使用@RequestParam註解來描述方法參數,且註解屬性value/name必須指定,表明從請求頭中獲取的請求參數命名是什麼。
在默認環境中,使用請求頭傳遞參數時,Application Service中的控制器沒法使用SpringMVC中的自動對象封裝能力。只能處理簡單數據類型。如:數學類型,字符串類型,數組類型等。沒法處理自定義對象類型。
使用請求體傳遞參數時,定義的服務標準接口中,必須使用@RequestBody註解來描述方法參數,由於Feign技術發起的POST請求,請求參數是使用JSON字符串來傳遞的,且form表單類型爲RAW。
使用請求體傳遞參數時,Application Service中的控制器必須使用@RequestBody註解來描述方法參數,且RAW類型的form表單上傳的是一個文本內容,只能轉換爲惟一的一個參數。
若是使用POST方式提交請求,並傳遞多個普通類型的參數時,Feign不會經過請求體傳遞參數,是經過請求頭傳遞的參數。也就是請求路徑爲 : http://applicationserver:port/url?paramName=paramValue。
gzip介紹:gzip是一種數據格式,採用deflate算法壓縮數據;gzip是一種流行的數據壓縮算法,應用十分普遍,尤爲是在Linux平臺。
gzip能力:當Gzip壓縮到一個純文本數據時,效果是很是明顯的,大約能夠減小70%以上的數據大小。
gzip做用:網絡數據通過壓縮後實際上下降了網絡傳輸的字節數,最明顯的好處就是能夠加快網頁加載的速度。網頁加載速度加快的好處不言而喻,除了節省流量,改善用戶的瀏覽體驗外,另外一個潛在的好處是Gzip與搜索引擎的抓取工具備着更好的關係。例如 Google就能夠經過直接讀取gzip文件來比普通手工抓取更快地檢索網頁。
如圖所示:
第一:客戶端向服務器請求頭中帶有:Accept-Encoding:gzip, deflate 字段,向服務器表示,客戶端支持的壓縮格式(gzip或者deflate),若是不發送該消息頭,服務器是不會壓縮的。
第二:服務端在收到請求以後,若是發現請求頭中含有Accept-Encoding字段,而且支持該類型的壓縮,就對響應報文壓縮以後返回給客戶端,而且攜帶Content-Encoding:gzip消息頭,表示響應報文是根據該格式壓縮過的。
第三:客戶端接收到響應以後,先判斷是否有Content-Encoding消息頭,若是有,按該格式解壓報文。不然按正常報文處理。
在Spring Cloud微服務體系中,一次請求的完整流程以下:
在總體流程中,若是使用GZIP壓縮來傳輸數據,涉及到兩次請求-應答。而這兩次請求-應答的鏈接點是Application Client,那麼咱們須要在Application Client中配置開啓GZIP壓縮,來實現壓縮數據傳輸。
這裏只開啓Feign請求-應答過程當中的GZIP,也就是瀏覽器-Application Client之間的請求應答不開啓GZIP壓縮。在全局配置文件中,使用下述配置來實現Feign請求-應答的GZIP壓縮:
# feign gzip # 局部配置。只配置feign技術相關的http請求-應答中的gzip壓縮。 # 配置的是application client和application service之間通信是否使用gzip作數據壓縮。 # 和瀏覽器到application client之間的通信無關。 # 開啓feign請求時的壓縮, application client -> application service
feign.compression.request.enabled=true
# 開啓feign技術響應時的壓縮, application service -> application client
feign.compression.response.enabled=true
# 設置能夠壓縮的請求/響應的類型。
feign.compression.request.mime-types=text/xml,application/xml,application/json
# 當請求的數據容量達到多少的時候,使用壓縮。默認是2048字節。
feign.compression.request.min-request-size=512
在全局配置文件中配置下述內容,來開啓全部請求-應答中的GZIP壓縮,這裏使用的是Spring Boot中的GZIP技術。在Spring Boot中已經集成了GZIP壓縮技術,並對全部的請求-應答實現GZIP數據壓縮。Spring Cloud中已經集成了Spring Boot技術,因此在配置文件中能夠開啓Spring Boot中的GZIP壓縮技術,對完整流程中與當前節點(Application Client)全部相關的請求-應答開啓GZIP壓縮。
# spring boot gzip # 開啓spring boot中的gzip壓縮。就是針對和當前應用全部相關的http請求-應答的gzip壓縮。
server.compression.enabled=true
# 哪些客戶端發出的請求不壓縮,默認是不限制
server.compression.excluded-user-agents=gozilla,traviata
# 配置想壓縮的請求/應答數據類型,默認是 text/html,text/xml,text/plain
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
# 執行壓縮的閾值,默認爲2048
server.compression.min-response-size=512
兩臺服務器創建HTTP鏈接的過程是很複雜的一個過程,涉及到多個數據包的交換,而且也很耗時間。HTTP鏈接須要的3次握手4次揮手開銷很大,這一開銷對於大量的比較小的HTTP消息來講更大。
那麼如何來優化HTTP鏈接性能?咱們能夠採用HTTP鏈接池來提高性能,鏈接池能夠節約大量的3次握手4次揮手的時間,這樣能大大提高吞吐率。
Feign的HTTP客戶端支持3種框架,分別是;HttpURLConnection、HttpClient、OKHttp。Feign中默認使用HttpURLConnection。
HttpURLConnection是JDK自帶的HTTP客戶端技術,並不支持鏈接池,若是要實現鏈接池的機制,還須要本身來管理鏈接對象。對於網絡請求這種底層相對複雜的操做,若是有可用的其餘方案,也沒有必要本身去管理鏈接對象。
Apache提供的HttpClient框架相比傳統JDK自帶的HttpURLConnection,它封裝了訪問http的請求頭,參數,內容體,響應等等;它不只使客戶端發送HTTP請求變得容易,並且也方便了開發人員測試接口(基於Http協議的),即提升了開發的效率,也方便提升代碼的健壯性;另外高併發大量的請求網絡的時候,仍是用「HTTP鏈接池」提高吞吐量。
OKHttp是一個處理網絡請求的開源項目,是安卓端最火熱的輕量級框架,由移動支付Square公司貢獻用於替代HttpUrlConnection和Apache HttpClient。OKHttp擁有共享Socket,減小對服務器的請求次數,經過鏈接池,減小了請求延遲等技術特色。
本案例中,經過替換Feign底層的HTTP客戶端實現爲HttpClient,來提高Feign的通信性能。
資源依賴:Feign技術發起請求的位置是Application Client端,下述依賴只須要在Application Client所在工程中添加便可。
<!-- httpclient相關依賴 --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency>
修改全局配置文件:
# 開啓feign技術對底層httpclient的依賴。 切換底層實現技術。
feign.httpclient.enabled=true
提供鏈接池配置類:
/** * 配置類型 * 用於提供一個HTTP鏈接池,並實現鏈接池管理。 * 主要目的是,提供一個合理的資源回收方式。 */ @Configuration public class HttpClientConfiguration { @Bean public HttpClient httpClient(){ System.out.println("init feign httpclient configuration " ); // 生成默認請求配置 RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); // 超時時間 requestConfigBuilder.setSocketTimeout(5 * 1000); // 鏈接時間 requestConfigBuilder.setConnectTimeout(5 * 1000); RequestConfig defaultRequestConfig = requestConfigBuilder.build(); // 鏈接池配置 // 長鏈接保持30秒 final PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.MILLISECONDS); // 總鏈接數 pollingConnectionManager.setMaxTotal(5000); // 同路由的併發數 pollingConnectionManager.setDefaultMaxPerRoute(100); // httpclient 配置 HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); // 保持長鏈接配置,須要在頭添加Keep-Alive httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()); httpClientBuilder.setConnectionManager(pollingConnectionManager); httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig); HttpClient client = httpClientBuilder.build(); // 啓動定時器,定時回收過時的鏈接, 最重要。 若是沒有定義回收策略。鏈接池會在運行一段時間後失效。 Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { pollingConnectionManager.closeExpiredConnections(); pollingConnectionManager.closeIdleConnections(5, TimeUnit.SECONDS); } }, 10 * 1000, 5 * 1000); System.out.println("===== Apache httpclient 初始化鏈接池==="); return client; } }
使用HttpClient客戶端替換HttpURLConnection,僅需修改Application Client,其他無需修改。當使用HttpClient技術做爲Feign的底層HTTP技術應用時,使用GET請求方式請求頭傳遞自定義類型對象是可行的,只要在服務標準對象中定義的方法參數上增長註解@RequestBody便可處理。
請求超時/請求時間: 客戶端發起請求,服務端響應併成功創建雙向連接的時間。
連接超時/連接時間: 雙向連接創建成功後,須要多久必須獲得服務端的響應結果。
在Feign聲明式遠程調用中,負載均衡仍是使用的Ribbon技術。而Ribbon技術默認的連接超時是1秒,也就是1秒內Application Service沒有處理Application Client的請求,且連接請求處理後,1秒以內沒有返回響應,Application Client都會拋出超時異常。在商業項目中,部分服務是很難在1秒以內處理連接,並在處理連接後1秒以內返回響應的,因此配置超時信息就頗有必要了。
定義超時配置的時候,建議爲每一個服務定義超時策略。若是有部分服務可使用一樣的超時策略,可使用全局配置。指定服務配置超時策略,會覆蓋全局配置。
超時策略的使用優先級: 指定服務的超時策略 -> 全局配置的超時策略 -> 默認的超時策略。
對Ribbon連接超時的配置都在全局配置文件中定義。具體以下。
全局服務配置粒度粗糙。商業項目中不一樣的服務對響應時長的限制也不一樣,全局服務配置不推薦應用。
# 全局服務配置 # 請求鏈接的超時時間 默認的時間爲1秒
ribbon.ConnectTimeout=1000
# 請求處理的超時時間
ribbon.ReadTimeout=5000
部分服務配置粒度細緻,能夠爲每一個具體服務配置不一樣的超時信息,推薦使用。
# 部分服務配置 服務名.ribbon.屬性=屬性值 # 對全部操做請求都進行重試
spring-cloud-feign-appservice.ribbon.OkToRetryOnAllOperations=true
# 對當前實例的重試次數
spring-cloud-feign-appservice.ribbon.MaxAutoRetries=2
# 請求鏈接的超時時間
spring-cloud-feign-appservice.ribbon.ConnectTimeout=3000
# 請求處理的超時時間
spring-cloud-feign-appservice.ribbon.ReadTimeout=3000