原文鏈接:https://zhuanlan.zhihu.com/p/81107006
1.概念部分
http 的背景原理
a. 兩台服務器建立 http 連接的過程是很復雜的一個過程,涉及到多個數據包的交換,並
且也很耗時間。
b. Http 連接需要的 3 次握手 4 次分手開銷很大,這一開銷對於大量的比較小的 http 消
息來說更大。
2優化解決方案
a. 如果我們直接采用 http 連接池,節約了大量的 3 次握手 4 次分手;這樣能大大提升吞
吐率。
b. feign 的 http 客戶端支持 3 種框架;HttpURLConnection、httpclient、okhttp;默認是
HttpURLConnection。
c. 傳統的 HttpURLConnection 是 JDK 自帶的,並不支持連接池,如果要實現連接池的
機制,還需要自己來管理連接對象。對於網絡請求這種底層相對復雜的操作,如果有可用的
其他方案,也沒有必要自己去管理連接對象。
d. HttpClient 相比傳統 JDK 自帶的 HttpURLConnection,它封裝了訪問 http 的請求頭,
參數,內容體,響應等等;它不僅使客戶端發送 HTTP 請求變得容易,而且也方便了開發人
員測試接口(基於 Http 協議的),即提高了開發的效率,也方便提高代碼的健壯性;另外
高並發大量的請求網絡的時候,還是用“連接池”提升吞吐量。
2.在consumer端添加httpClient相關坐標
注意:httpClien與feign版本之間的適配
Dalston.SR5版本
<!-- 添加 Feign 坐標 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <!-- 使用Apache HttpClient替換Feign原生httpURLConnection --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-httpclient</artifactId> <version>8.17.0</version> </dependency>\
Greenwich.SR2版本
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- 使用Apache HttpClient替換Feign原生httpURLConnection --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency> <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> <version>10.1.0</version> </dependency>
3.修改application.properties
#啟用 httpclient
feign.httpclient.enabled=true
4.案例
server端
注意:
1.在傳遞對象時在server端@RequestBody注解可寫可不寫
2.與默認的相比支持get和post方式傳遞對象
3.1.x版本需在@RequestMapping注解中指定consumes屬性,而2.x版本不需要
Dalston.SR5版本
//添加商品傳遞多個參數 方式二 :POST 方式 @RequestMapping(value="/add2",method=RequestMethod.POST,consumes=MediaType.APPLICATION_JSON_VALUE) public Product addProduct2(@RequestBody Product product); //使用 HttpClient 工具 添加商品傳遞多個參數 :基於 GET 方式 @RequestMapping(value="/add3",method=RequestMethod.GET,consumes=MediaType.APPLICATION_JSON_VALUE) public Product addProduct3(Product product); }
Greenwich.SR2版本
//傳遞對象 post方式 @PostMapping(value = "/add2") String addItem2( Item item); //傳遞對象 get方式 @GetMapping(value = "/add3") String addItem3( Item item);
provier端
注意: 1.傳遞對象時必須在參數前使用@RequestBody注解
2.普通參數需使用@requestParam注解
//post方式傳遞對象 @Override public String addItem2(@RequestBody Item item) { System.out.println(item); return "添加商品Ok"; } //get方式傳遞對象 @Override public String addItem3(@RequestBody Item item) { System.out.println(item); return "添加商品Ok"; }
consumer端
service層
@FeignClient(name = "feign-provider") public interface ItemConsumerService extends ItemService { }
controller層
//post方式傳遞對象 @GetMapping("/add2") public String addItem2(Item item){ return itemConsumerService.addItem2(item); } //post方式傳遞對象 @GetMapping("/add3") public String addItem3(Item item){ return itemConsumerService.addItem3(item); }
啟動器
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class FeignConsumerApplication { public static void main(String[] args) { SpringApplication.run(FeignConsumerApplication.class, args); } }
spring.application.name=feign-consumer
server.port=6001
eureka.client.service-url.defaultZone=http://root:root@eureka1:8761/eureka/,http://root:root@eureka2:8761/eureka/
#-----------------------------feign gzip
#配置請求 GZIP 壓縮
feign.compression.request.enabled=true
#配置響應 GZIP 壓縮
feign.compression.response.enabled=true
#配置壓縮支持的 MIME TYPE
feign.compression.request.mime-types=text/xml,application/xml,application/json
#配置壓縮數據大小的最小閥值,默認 2048
feign.compression.request.min-request-size=512
#-----------------------------spring boot gzip
#是否啟用壓縮
server.compression.enabled=true
server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain
#啟用 httpclient
feign.httpclient.enabled=true