激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 淺談SpringCloud feign的http請求組件優化方案

淺談SpringCloud feign的http請求組件優化方案

2021-08-13 13:49小魚兒_karl Java教程

這篇文章主要介紹了淺談SpringCloud feign的http請求組件優化方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

1 描述

如果我們直接使用SpringCloud Feign進行服務間調用的時候,http組件使用的是JDK的HttpURLConnection,每次請求都會新建一個連接,沒有使用線程池復用。具體的可以從源碼進行分析

2 源碼分析

我們在分析源碼很難找到入口,不知道從何開始入手,我們在分析SpringCloud feign的時候可用在配置文件下面我講一下個人的思路。

1 首先我點擊@EnableFeignClients 看一下這個注解在哪個資源路徑下

如下圖所示:

淺談SpringCloud feign的http請求組件優化方案

2 找到服務啟動加載的配置文件

淺談SpringCloud feign的http請求組件優化方案

3 因為feign底層的負載均衡是基于Ribbon的所以很快就找到了FeignRibbonClientAutoConfiguration.java 這個類

  1. @ConditionalOnClass({ ILoadBalancer.class, Feign.class })
  2. @Configuration
  3. @AutoConfigureBefore(FeignAutoConfiguration.class)
  4. @EnableConfigurationProperties({ FeignHttpClientProperties.class })
  5. //Order is important here, last should be the default, first should be optional
  6. // see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
  7. @Import({ HttpClientFeignLoadBalancedConfiguration.class,
  8. OkHttpFeignLoadBalancedConfiguration.class,
  9. DefaultFeignLoadBalancedConfiguration.class })
  10. public class FeignRibbonClientAutoConfiguration {

首先我們從這三個類進行分析,從名字上來看我為了驗證沒有特殊配置,feign底層走的是不是默認的DefaultFeignLoadBalancedConfiguration.class

OkHttpFeignLoadBalancedConfiguration.class

HttpClientFeignLoadBalancedConfiguration.class

DefaultFeignLoadBalancedConfiguration.class

DefaultFeignLoadBalancedConfiguration.class

  1. @Configuration
  2. class DefaultFeignLoadBalancedConfiguration {
  3. @Bean
  4. @ConditionalOnMissingBean
  5. public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
  6. SpringClientFactory clientFactory) {
  7. return new LoadBalancerFeignClient(new Client.Default(null, null),
  8. cachingFactory, clientFactory);
  9. }
  10. }

從上面代碼可知每次請求過來都會創建一個新的client,具體的源碼演示有興趣的可以深入研究,在這里不是我們所研究的重點。

OkHttpFeignLoadBalancedConfiguration.class

  1. @Configuration
  2. @ConditionalOnClass(OkHttpClient.class)
  3. @ConditionalOnProperty(value = "feign.okhttp.enabled")
  4. class OkHttpFeignLoadBalancedConfiguration {
  5. @Configuration
  6. @ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
  7. protected static class OkHttpFeignConfiguration {
  8. private okhttp3.OkHttpClient okHttpClient;
  9. @Bean
  10. @ConditionalOnMissingBean(ConnectionPool.class)
  11. public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties,
  12. OkHttpClientConnectionPoolFactory connectionPoolFactory) {
  13. Integer maxTotalConnections = httpClientProperties.getMaxConnections();
  14. Long timeToLive = httpClientProperties.getTimeToLive();
  15. TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
  16. return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
  17. }
  18. @Bean
  19. public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
  20. ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
  21. Boolean followRedirects = httpClientProperties.isFollowRedirects();
  22. Integer connectTimeout = httpClientProperties.getConnectionTimeout();
  23. this.okHttpClient = httpClientFactory.createBuilder(httpClientProperties.isDisableSslValidation()).
  24. connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
  25. followRedirects(followRedirects).
  26. connectionPool(connectionPool).build();
  27. return this.okHttpClient;
  28. }
  29. @PreDestroy
  30. public void destroy() {
  31. if(okHttpClient != null) {
  32. okHttpClient.dispatcher().executorService().shutdown();
  33. okHttpClient.connectionPool().evictAll();
  34. }
  35. }
  36. }
  37. @Bean
  38. @ConditionalOnMissingBean(Client.class)
  39. public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
  40. SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
  41. OkHttpClient delegate = new OkHttpClient(okHttpClient);
  42. return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
  43. }
  44. }

從源碼可以看出

1 該類是個配置類,當引入OkHttpClient.Class會加載

  1. client方法中可以看出會返回一個http連接池的client
  2. HttpClientFeignLoadBalancedConfiguration
  3. @Configuration
  4. @ConditionalOnClass(ApacheHttpClient.class)
  5. @ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
  6. class HttpClientFeignLoadBalancedConfiguration {

這個類和OkHttpFeignLoadBalancedConfiguration原理類型

使用OKHttp替代默認的JDK的HttpURLConnection

使用appach httpclient使用教程類似

使用方法

1 pom

  1. <dependency>
  2. <groupId>io.github.openfeign</groupId>
  3. <artifactId>feign-okhttp</artifactId>
  4. </dependency>

2 Yml文件

  1. feign:
  2. okhttp:
  3. enabled: true

3 自定義連接池

可以通過代碼進行配置,也可以通過yml配置

  1. @Configuration
  2. @ConditionalOnClass(Feign.class)
  3. @AutoConfigureBefore(FeignAutoConfiguration.class)
  4. public class FeignOkHttpConfig {
  5. @Bean
  6. public okhttp3.OkHttpClient okHttpClient(){
  7. return new okhttp3.OkHttpClient.Builder()
  8. .readTimeout(60,TimeUnit.SECONDS)
  9. .connectTimeout(60,TimeUnit.SECONDS)
  10. .connectionPool(new ConnectionPool())
  11. .build();
  12. }
  13. }

驗證

默認的Feign處理會走到如下位置;

位置處于如下圖所示

淺談SpringCloud feign的http請求組件優化方案

  1. @Override
  2. public Response execute(Request request, Options options) throws IOException {
  3. HttpURLConnection connection = convertAndSend(request, options);
  4. return convertResponse(connection).toBuilder().request(request).build();
  5. }

走okhttp客戶端會走如下代碼

具體位置如下圖所示:

淺談SpringCloud feign的http請求組件優化方案

  1. @Override public Response execute() throws IOException {
  2. synchronized (this) {
  3. if (executed) throw new IllegalStateException("Already Executed");
  4. executed = true;
  5. }
  6. captureCallStackTrace();
  7. try {
  8. client.dispatcher().executed(this);
  9. Response result = getResponseWithInterceptorChain();
  10. if (result == null) throw new IOException("Canceled");
  11. return result;
  12. } finally {
  13. client.dispatcher().finished(this);
  14. }
  15. }

驗證結果

如下所示:

淺談SpringCloud feign的http請求組件優化方案

彩蛋

okhttp客戶端會走的代碼可以看出來okhttp有synchronized鎖線程安全的那默認的是否是線程安全的呢 有待去驗證。

追加

如果發現配置的超時時間無效,可以添加以下配置,因為讀取超時配置的時候沒有讀取上面的okhttp的配置參數,而是從Request中讀取。

具體配置如下所示:

  1. @Bean
  2. public Request.Options options(){
  3. return new Request.Options(60000,60000);
  4. }

補充:springCloud feign使用/優化總結

基于springCloud Dalston.SR3版本

1.當接口參數是多個的時候 需要指定@RequestParam 中的value來明確一下。

  1. /**
  2. * 用戶互掃
  3. * @param uid 被掃人ID
  4. * @param userId 當前用戶ID
  5. * @return
  6. */
  7. @PostMapping(REQ_URL_PRE + "/qrCodeReturnUser")
  8. UserQrCode qrCodeReturnUser(@RequestParam("uid") String uid,@RequestParam("userId") Integer userId);

2.接口參數為對象的時候 需要使用@RequestBody注解 并采用POST方式。

3.如果接口是簡單的數組/列表參數 這里需要使用Get請求才行

  1. @GetMapping(REQ_URL_PRE + "/getUserLevels")
  2. Map<Integer, UserLevel> getUserLevels(@RequestParam("userIds") List<Integer> userIds);

4.直接可以在@FeignClient中配置降級處理方式 對于一些不重要的業務 自定義處理很有幫助

  1. @FeignClient(value = "cloud-user", fallback = IUsers.UsersFallback.class)

5.feign默認只有HystrixBadRequestException異常不會走熔斷,其它任何異常都會進入熔斷,需要重新實現一下ErrorDecoder包裝業務異常

示例:https://github.com/peachyy/feign-support

6. feign HTTP請求方式選擇

feign默認使用的是基于JDK提供的URLConnection調用HTTP接口,不具備連接池。所以資源開銷上有點影響,經測試JDK的URLConnection比Apache HttpClient快很多倍。但是Apache HttpClient和okhttp都支持配置連接池功能。具體選擇需要權衡

7.默認不啟用hystrix 需要手動指定feign.hystrix.enabled=true 開啟熔斷

8.啟用壓縮也是一種有效的優化方式

  1. feign.compression.request.enabled=true
  2. feign.compression.response.enabled=true
  3. feign.compression.request.mime-types=text/xml,application/xml,application/json

9.參數相關調優

hystrix線程數設置

設置參數hystrix.threadpool.default.coreSize 來指定熔斷隔離的線程數 這個數需要調優,經測試 線程數我們設置為和提供方的容器線程差不多,吞吐量高許多。

第一次訪問服務出錯的問題

啟用Hystrix后,很多服務當第一次訪問的時候都會失敗 是因為初始化負載均衡一系列操作已經超出了超時時間了 默認的超時時間為1S,設置參數超時時間hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=30000 可解決這個問題。

負載均衡參數設置

設置了Hystrix的超時參數會 還需設置一下ribbon的相關參數 這些參數和Hystrix的超時參數有一定的邏輯關系

請求處理的超時時間 ribbon.ReadTimeout=120000

請求連接的超時時間 ribbon.ConnectTimeout=30000

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持我們。如有錯誤或未考慮完全的地方,望不吝賜教。

原文鏈接:https://blog.csdn.net/qq_33249725/article/details/88532160

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲午夜视频 | 国产99一区二区 | 成人免费一区二区三区在线观看 | 久久精品女人天堂av | 国产一区二区在线免费观看 | www.精品视频 | 在线观看av国产一区二区 | 日本羞羞的午夜电视剧 | 久久不雅视频 | 91精选视频在线观看 | 欧美18—19sex性护士中国 | 久久久久久久久成人 | 九九热国产视频 | 国产精品成人一区二区三区吃奶 | 久久久成人精品视频 | 免费淫视频 | 成人在线视频精品 | 91懂色 | 女女久久 | 污片视频网站 | av电影在线观看网站 | 亚洲成人在线视频网站 | 久草在线最新 | 中文字幕一区久久 | 久久97视频| 国产亚洲精品久久久久久网站 | 最新av在线免费观看 | 国产亚洲精品久久久久5区 综合激情网 | 国产福利视频 | 精品欧美一区二区精品久久久 | 国产乱淫av片免费观看 | 91在线色 | 欧洲a级片| 黄色大片大毛片 | 欧美成人精品h版在线观看 国产一级淫片在线观看 | av不卡免费观看 | 久久思思爱 | 爱看久久 | 国产资源视频在线观看 | 99久久久国产精品免费99 | 久久亚洲一区二区三区成人国产 |