最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談SpringCloud feign的http請求組件優(yōu)化方案

 更新時間:2021年02月25日 10:26:01   作者:小魚兒_karl  
這篇文章主要介紹了淺談SpringCloud feign的http請求組件優(yōu)化方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

1 描述

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

2 源碼分析

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

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

如下圖所示:

2 找到服務(wù)啟動加載的配置文件

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

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

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

OkHttpFeignLoadBalancedConfiguration.class

HttpClientFeignLoadBalancedConfiguration.class

DefaultFeignLoadBalancedConfiguration.class

DefaultFeignLoadBalancedConfiguration.class

@Configuration
class DefaultFeignLoadBalancedConfiguration {
	@Bean
	@ConditionalOnMissingBean
	public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
							 SpringClientFactory clientFactory) {
		return new LoadBalancerFeignClient(new Client.Default(null, null),
				cachingFactory, clientFactory);
	}
}

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

OkHttpFeignLoadBalancedConfiguration.class

@Configuration
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled")
class OkHttpFeignLoadBalancedConfiguration {
	@Configuration
	@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
	protected static class OkHttpFeignConfiguration {
		private okhttp3.OkHttpClient okHttpClient;
		@Bean
		@ConditionalOnMissingBean(ConnectionPool.class)
		public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties,
													 OkHttpClientConnectionPoolFactory connectionPoolFactory) {
			Integer maxTotalConnections = httpClientProperties.getMaxConnections();
			Long timeToLive = httpClientProperties.getTimeToLive();
			TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
			return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
		}
		@Bean
		public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
										 ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
			Boolean followRedirects = httpClientProperties.isFollowRedirects();
			Integer connectTimeout = httpClientProperties.getConnectionTimeout();
			this.okHttpClient = httpClientFactory.createBuilder(httpClientProperties.isDisableSslValidation()).
					connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
					followRedirects(followRedirects).
					connectionPool(connectionPool).build();
			return this.okHttpClient;
		}
		@PreDestroy
		public void destroy() {
			if(okHttpClient != null) {
				okHttpClient.dispatcher().executorService().shutdown();
				okHttpClient.connectionPool().evictAll();
			}
		}
	}
	@Bean
	@ConditionalOnMissingBean(Client.class)
	public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
							 SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
		OkHttpClient delegate = new OkHttpClient(okHttpClient);
		return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
	}
}

從源碼可以看出

1 該類是個配置類,當(dāng)引入OkHttpClient.Class會加載

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

這個類和OkHttpFeignLoadBalancedConfiguration原理類型

使用OKHttp替代默認的JDK的HttpURLConnection

使用appach httpclient使用教程類似

使用方法

1 pom

 <dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-okhttp</artifactId>
 </dependency>

2 Yml文件

feign:
 okhttp:
 enabled: true

3 自定義連接池

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

@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig {
 @Bean
 public okhttp3.OkHttpClient okHttpClient(){
 return new okhttp3.OkHttpClient.Builder()
  .readTimeout(60,TimeUnit.SECONDS)
  .connectTimeout(60,TimeUnit.SECONDS)
  .connectionPool(new ConnectionPool())
  .build();
 }
}

驗證

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

位置處于如下圖所示

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

走okhttp客戶端會走如下代碼

具體位置如下圖所示:

@Override public Response execute() throws IOException {
 synchronized (this) {
 if (executed) throw new IllegalStateException("Already Executed");
 executed = true;
 }
 captureCallStackTrace();
 try {
 client.dispatcher().executed(this);
 Response result = getResponseWithInterceptorChain();
 if (result == null) throw new IOException("Canceled");
 return result;
 } finally {
 client.dispatcher().finished(this);
 }
 }

驗證結(jié)果

如下所示:

彩蛋

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

追加

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

具體配置如下所示:

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

補充:springCloud feign使用/優(yōu)化總結(jié)

基于springCloud Dalston.SR3版本

1.當(dāng)接口參數(shù)是多個的時候 需要指定@RequestParam 中的value來明確一下。

/**
 * 用戶互掃
 * @param uid 被掃人ID
 * @param userId 當(dāng)前用戶ID
 * @return
 */
@PostMapping(REQ_URL_PRE + "/qrCodeReturnUser")
UserQrCode qrCodeReturnUser(@RequestParam("uid") String uid,@RequestParam("userId") Integer userId);

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

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

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

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

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

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

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

6. feign HTTP請求方式選擇

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

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

8.啟用壓縮也是一種有效的優(yōu)化方式

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

9.參數(shù)相關(guān)調(diào)優(yōu)

hystrix線程數(shù)設(shè)置

設(shè)置參數(shù)hystrix.threadpool.default.coreSize 來指定熔斷隔離的線程數(shù) 這個數(shù)需要調(diào)優(yōu),經(jīng)測試 線程數(shù)我們設(shè)置為和提供方的容器線程差不多,吞吐量高許多。

第一次訪問服務(wù)出錯的問題

啟用Hystrix后,很多服務(wù)當(dāng)?shù)谝淮卧L問的時候都會失敗 是因為初始化負載均衡一系列操作已經(jīng)超出了超時時間了 默認的超時時間為1S,設(shè)置參數(shù)超時時間hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=30000 可解決這個問題。

負載均衡參數(shù)設(shè)置

設(shè)置了Hystrix的超時參數(shù)會 還需設(shè)置一下ribbon的相關(guān)參數(shù) 這些參數(shù)和Hystrix的超時參數(shù)有一定的邏輯關(guān)系

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

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

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • 一文搞懂Java并發(fā)AQS的共享鎖模式

    一文搞懂Java并發(fā)AQS的共享鎖模式

    這篇文章主要為大家闡述AQS另外一個重要模式,共享鎖模式。共享鎖可以由多個線程同時獲取,?比較典型的就是讀鎖,感興趣的小伙伴可以了解一下
    2022-10-10
  • 使用Cloud?Studio構(gòu)建SpringSecurity權(quán)限框架(騰訊云?Cloud?Studio?實戰(zhàn)訓(xùn)練營)

    使用Cloud?Studio構(gòu)建SpringSecurity權(quán)限框架(騰訊云?Cloud?Studio?實戰(zhàn)訓(xùn)練

    隨著云計算技術(shù)的成熟和普及,傳統(tǒng)編程能力和資源以云服務(wù)的形式開放出來,從中間件、數(shù)據(jù)庫等水平能力服務(wù)組件到人臉識別、鑒權(quán)服務(wù)等基本業(yè)務(wù)服務(wù)組件很容易的在云端獲取,本文介紹使用Cloud?Studio構(gòu)建SpringSecurity權(quán)限框架的相關(guān)知識,感興趣的朋友一起看看吧
    2023-08-08
  • java利用反射實現(xiàn)動態(tài)代理示例

    java利用反射實現(xiàn)動態(tài)代理示例

    這篇文章主要介紹了java利用反射實現(xiàn)動態(tài)代理示例,需要的朋友可以參考下
    2014-04-04
  • Java網(wǎng)絡(luò)編程之IO模型阻塞與非阻塞簡要分析

    Java網(wǎng)絡(luò)編程之IO模型阻塞與非阻塞簡要分析

    這篇文章主要介紹Java網(wǎng)絡(luò)編程中的IO模型阻塞與非阻塞簡要分析,文中附有示例代碼,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • java中每月等額與先息后本計算

    java中每月等額與先息后本計算

    一般信用貸款會提供兩種還款方式:每月等額或者先息后本。每月等額,就是每月歸還等同的部分本金和利息,你手里在使用的本金其實是逐月減少的。先息后本就是先還利息,到期歸還本金。本文將介紹他們的實現(xiàn)方法。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-03-03
  • Springboot與vue實現(xiàn)數(shù)據(jù)導(dǎo)出方法具體介紹

    Springboot與vue實現(xiàn)數(shù)據(jù)導(dǎo)出方法具體介紹

    這篇文章主要介紹了Springboot與vue實現(xiàn)數(shù)據(jù)導(dǎo)出方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-02-02
  • Protostuff序列化和反序列化的使用說明

    Protostuff序列化和反序列化的使用說明

    今天小編就為大家分享一篇關(guān)于Protostuff序列化和反序列化的使用說明,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Java設(shè)計模式之狀態(tài)模式詳解

    Java設(shè)計模式之狀態(tài)模式詳解

    Java?中的狀態(tài)模式(State?Pattern)是一種行為型設(shè)計模式,它允許對象在內(nèi)部狀態(tài)發(fā)生改變時改變其行為,本文將詳細介紹?Java?中的狀態(tài)模式,我們將從狀態(tài)模式的概述、結(jié)構(gòu)與實現(xiàn)、優(yōu)缺點、適用場景等方面進行講解,需要的朋友可以參考下
    2023-05-05
  • MyBatis 探秘之#{} 與 ${} 參傳差異解碼(數(shù)據(jù)庫連接池筑牢數(shù)據(jù)交互根基)

    MyBatis 探秘之#{} 與 ${} 參傳差異解碼(數(shù)據(jù)庫連接池筑牢數(shù)據(jù)交互

    本文詳細介紹了MyBatis中的`#{}`和`${}`的區(qū)別與使用場景,包括預(yù)編譯SQL和即時SQL的區(qū)別、安全性問題,以及如何正確使用數(shù)據(jù)庫連接池來提高性能,感興趣的朋友一起看看吧
    2024-12-12
  • IDEA中properties與yml文件的轉(zhuǎn)變方式

    IDEA中properties與yml文件的轉(zhuǎn)變方式

    文章介紹了如何在IntelliJ IDEA 2021.1.1中安裝和使用ConvertYAMLandPropertiesFile插件進行YAML和Properties文件之間的轉(zhuǎn)換,安裝步驟包括導(dǎo)航到設(shè)置、安裝插件、找到并安裝插件等,插件支持從Properties文件轉(zhuǎn)換為YAML文件,但轉(zhuǎn)換過程中會丟失注釋
    2024-12-12

最新評論

黄浦区| 崇义县| 高淳县| 光山县| 兴国县| 图木舒克市| 仁寿县| 崇州市| 明光市| 兴山县| 大英县| 巴林左旗| 新乡县| 海口市| 南部县| 从江县| 共和县| 长治市| 汾西县| 应用必备| 定州市| 察雅县| 库车县| 炎陵县| 灯塔市| 大埔区| 吉水县| 富锦市| 大理市| 临邑县| 高雄市| 安远县| 古浪县| 石狮市| 平昌县| 深州市| 虞城县| 微博| 湛江市| 伊通| 卢湾区|