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

Spring中@Scheduled和HttpClient的連環(huán)坑

 更新時間:2018年03月29日 11:37:25   作者:白色夜空  
這篇文章主要給大家介紹了關(guān)于Spring中@Scheduled和HttpClient的連環(huán)坑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。

前言

本文主要給大家介紹了關(guān)于Spring中@Scheduled和HttpClient的坑,分享出來供大家參考學(xué)習(xí),下面話不多說了,來一起看看詳細(xì)的介紹吧。

曾經(jīng)踩過一個大坑:

由于業(yè)務(wù)特殊性,會定時跑很多定時任務(wù),對業(yè)務(wù)數(shù)據(jù)進(jìn)行補(bǔ)償操作等。

在Spring使用過程中,我們可以使用@Scheduled注解可以方便的實現(xiàn)定時任務(wù)。

有一天早上突然發(fā)現(xiàn),從前一天晚上某一時刻開始,所有的定時任務(wù)全部都卡死不再運行了。

@Scheduled默認(rèn)單線程

經(jīng)排查后發(fā)現(xiàn),我們使用@Scheduled注解默認(rèn)的配置的話,所有的任務(wù)都是單線程去跑的。寫了一個測試的task讓它sleep住,就很容易發(fā)現(xiàn),其他所有的task在時間到的時候都沒有觸發(fā)。

如果需要開啟多線程處理,則需要進(jìn)行如下的配置,設(shè)置一下線程數(shù):

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
 @Override
 public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
  taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
 }
}

這樣就解決了如果一個task卡住,會引起所有task全部卡住的問題。

但是為什么會有task卡住呢?

HttpClient默認(rèn)參數(shù)配置

原來,有些task會定時請求外部服務(wù)的restful接口,而HttpClient的配置如下:

PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
  connManager.setMaxTotal(maxConnection);
  httpClient = HttpClients.custom()
    .setConnectionManager(connManager)
    .build();

在最開始使用HttpClient的時候,根本沒有想這么多,基本也都是用用默認(rèn)配置。

追蹤源碼可以發(fā)現(xiàn),在使用上述方式進(jìn)行配置的時候,HttpClient的timeout時間竟然全部都是-1,也就是說如果對方服務(wù)有問題,HttpClient的請求會永不超時,一直等待。源碼如下:

Builder() {
  super();
  this.staleConnectionCheckEnabled = false;
  this.redirectsEnabled = true;
  this.maxRedirects = 50;
  this.relativeRedirectsAllowed = true;
  this.authenticationEnabled = true;
  this.connectionRequestTimeout = -1;
  this.connectTimeout = -1;
  this.socketTimeout = -1;
  this.contentCompressionEnabled = true;
}

所以我們這時候必須手動指定timeout時間,問題就解決了。例如:

PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
  connManager.setMaxTotal(maxConnection);
  RequestConfig defaultRequestConfig = RequestConfig.custom()
    .setSocketTimeout(3000)
    .setConnectTimeout(3000)
    .setConnectionRequestTimeout(3000)
    .build();
  httpClient = HttpClients.custom()
    .setDefaultRequestConfig(defaultRequestConfig)
    .setConnectionManager(connManager)
    .build();

聯(lián)想到另一個問題

其實HttpClient的使用過程中也遇到過另外一個配置的問題,就是defaultMaxPerRoute這個參數(shù)。

最開始使用的時候也沒有注意過這個參數(shù),只是設(shè)置過連接池的最大連接數(shù)maxTotal。

defaultMaxPerRoute參數(shù)其實代表了每個路由的最大連接數(shù)。比如你的系統(tǒng)需要訪問另外兩個服務(wù):google.com 和 bing.com。如果你的maxTotal設(shè)置了100,而defaultMaxPerRoute設(shè)置了50,那么你的每一個服務(wù)的最大請求數(shù)最大只能是50。

那么如果defaultMaxPerRoute沒有設(shè)置呢,追蹤源碼:

public PoolingHttpClientConnectionManager(
  final HttpClientConnectionOperator httpClientConnectionOperator,
  final HttpConnectionFactory<HttpRoute, ManagedHttpClientConnection> connFactory,
  final long timeToLive, final TimeUnit tunit) {
  super();
  this.configData = new ConfigData();
  //這里使用的CPool構(gòu)造方法,第二個參數(shù)即為defaultMaxPerRoute,也就是默認(rèn)為2。
  this.pool = new CPool(new InternalConnectionFactory(
    this.configData, connFactory), 2, 20, timeToLive, tunit);
  this.pool.setValidateAfterInactivity(2000);
  this.connectionOperator = Args.notNull(httpClientConnectionOperator, "HttpClientConnectionOperator");
  this.isShutDown = new AtomicBoolean(false);
}

這里發(fā)現(xiàn),原來默認(rèn)值竟然只有2。怪不得當(dāng)時在高并發(fā)情況下總會出現(xiàn)超時,明明maxTotal已經(jīng)設(shè)的很高。

所以如果你的服務(wù)訪問很多不同的外部服務(wù),并且并發(fā)量比較大,一定要好好配置maxTotal和defaultMaxPerRoute兩個參數(shù)。

所以后來再使用任何新的東西,都有好好看下都什么配置,有疑問的一定要先查一下,不要網(wǎng)上copy一段代碼直接就用。當(dāng)時可能沒問題,但是以后沒準(zhǔn)就被坑了。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

  • java如何獲取實體類的屬性名和屬性值

    java如何獲取實體類的屬性名和屬性值

    這篇文章主要介紹了java如何獲取實體類的屬性名和屬性值問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 深入淺析Java反射機(jī)制

    深入淺析Java反射機(jī)制

    Java反射機(jī)制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為Java語言的反射機(jī)制
    2015-11-11
  • java實現(xiàn)畫圖板上畫一條直線

    java實現(xiàn)畫圖板上畫一條直線

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)畫圖板上畫一條直線,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • Java靜態(tài)static關(guān)鍵字原理詳解

    Java靜態(tài)static關(guān)鍵字原理詳解

    這篇文章主要介紹了Java靜態(tài)static關(guān)鍵字原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • java&javascript自定義加密數(shù)據(jù)傳輸代碼示例

    java&javascript自定義加密數(shù)據(jù)傳輸代碼示例

    這篇文章主要介紹了java&javascript自定義加密數(shù)據(jù)傳輸代碼示例,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • 基于Retrofit+Rxjava實現(xiàn)帶進(jìn)度顯示的下載文件

    基于Retrofit+Rxjava實現(xiàn)帶進(jìn)度顯示的下載文件

    這篇文章主要為大家詳細(xì)介紹了基于Retrofit+Rxjava實現(xiàn)帶進(jìn)度顯示的下載文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Springboot 整合 Java DL4J 實現(xiàn)文物保護(hù)系統(tǒng)的詳細(xì)過程

    Springboot 整合 Java DL4J 實現(xiàn)文物保護(hù)系統(tǒng)的詳細(xì)過程

    在數(shù)字化時代,文物保護(hù)尤為關(guān)鍵,本文介紹如何利用SpringBoot和Deeplearning4j構(gòu)建一個圖像識別的文物保護(hù)系統(tǒng),系統(tǒng)采用卷積神經(jīng)網(wǎng)絡(luò)(CNN),能夠識別文物的損壞情況,本文介紹Springboot 整合 Java DL4J 實現(xiàn)文物保護(hù)系統(tǒng),感興趣的朋友一起看看吧
    2024-10-10
  • Java 線程池的作用以及該如何使用

    Java 線程池的作用以及該如何使用

    這篇文章主要介紹了Java 線程池的作用以及該如何使用,幫助大家更好的理解和學(xué)習(xí)Java的相關(guān)知識,感興趣的朋友可以了解下
    2021-01-01
  • Java springboot壓縮文件上傳,解壓,刪除壓縮包方式

    Java springboot壓縮文件上傳,解壓,刪除壓縮包方式

    這篇文章主要介紹了Java springboot壓縮文件上傳,解壓,刪除壓縮包方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-04-04
  • 淺析Java中ConcurrentHashMap的存儲流程

    淺析Java中ConcurrentHashMap的存儲流程

    ConcurrentHashMap技術(shù)在互聯(lián)網(wǎng)技術(shù)使用如此廣泛,幾乎所有的后端技術(shù)面試官都要在ConcurrentHashMap技術(shù)的使用和原理方面對小伙伴們進(jìn)行360°的刁難,本文詳細(xì)給大家介紹一下ConcurrentHashMap的存儲流程,需要的朋友可以參考下
    2023-05-05

最新評論

苏州市| 鹤壁市| 安龙县| 云南省| 石泉县| 华安县| 清原| 韶关市| 通辽市| 大方县| 永定县| 老河口市| 聂荣县| 武陟县| 孝昌县| 横峰县| 望谟县| 蓝田县| 宜都市| 建水县| 沙田区| 阳曲县| 达尔| 师宗县| 沙雅县| 陆河县| 昆明市| 光山县| 平利县| 沙洋县| 崇明县| 营口市| 嘉黎县| 临泉县| 乌什县| 白山市| 拉孜县| 绥滨县| 荔浦县| 华亭县| 灌云县|