欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前言

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

曾經(jīng)踩過(guò)一個(gè)大坑:

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

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

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

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

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

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

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

這樣就解決了如果一個(gè)task卡住,會(huì)引起所有task全部卡住的問(wèn)題。

但是為什么會(huì)有task卡住呢?

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

原來(lái),有些task會(huì)定時(shí)請(qǐng)求外部服務(wù)的restful接口,而HttpClient的配置如下:

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

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

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

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;
}

所以我們這時(shí)候必須手動(dòng)指定timeout時(shí)間,問(wèn)題就解決了。例如:

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)想到另一個(gè)問(wèn)題

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

最開(kāi)始使用的時(shí)候也沒(méi)有注意過(guò)這個(gè)參數(shù),只是設(shè)置過(guò)連接池的最大連接數(shù)maxTotal。

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

那么如果defaultMaxPerRoute沒(méi)有設(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)造方法,第二個(gè)參數(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),原來(lái)默認(rèn)值竟然只有2。怪不得當(dāng)時(shí)在高并發(fā)情況下總會(huì)出現(xiàn)超時(shí),明明maxTotal已經(jīng)設(shè)的很高。

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

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

總結(jié)

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

相關(guān)文章

  • Java web中 war exploded 的解決方案

    Java web中 war exploded 的解決方案

    這篇文章主要介紹了Java web中 war exploded 的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java分布式流處理組件Producer入門(mén)詳解

    java分布式流處理組件Producer入門(mén)詳解

    這篇文章主要為大家介紹了java分布式流處理組件Producer入門(mén)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 七個(gè)Spring核心模塊詳解

    七個(gè)Spring核心模塊詳解

    這篇文章主要為大家詳細(xì)介紹了七個(gè)Spring的核心模塊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Java案例之HashMap集合存儲(chǔ)學(xué)生對(duì)象并遍歷

    Java案例之HashMap集合存儲(chǔ)學(xué)生對(duì)象并遍歷

    這篇文章主要介紹了Java案例之HashMap集合存儲(chǔ)學(xué)生對(duì)象并遍歷,創(chuàng)建一個(gè)HashMap集合,鍵是學(xué)號(hào)(String),值是學(xué)生對(duì)象(Student),存儲(chǔ)三個(gè)鍵值對(duì)元素并遍歷,下文具體操作需要的朋友可以參考一下
    2022-04-04
  • Java將字符串String轉(zhuǎn)換為整型Int的兩種方式

    Java將字符串String轉(zhuǎn)換為整型Int的兩種方式

    這篇文章主要介紹了Java如何將字符串String轉(zhuǎn)換為整型Int,在 Java 中要將 String 類型轉(zhuǎn)化為 int 類型時(shí),需要使用 Integer 類中的 parseInt() 方法或者 valueOf() 方法進(jìn)行轉(zhuǎn)換,本文通過(guò)實(shí)例代碼給大家詳細(xì)講解,需要的朋友可以參考下
    2023-04-04
  • JSP頁(yè)面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案

    JSP頁(yè)面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案

    這篇文章主要介紹了JSP頁(yè)面?zhèn)鲄⒊霈F(xiàn)中文亂碼的解決方案,非常實(shí)用,需要的朋友可以參考下
    2014-08-08
  • Springboot jar包遠(yuǎn)程調(diào)試詳解

    Springboot jar包遠(yuǎn)程調(diào)試詳解

    這篇文章主要為大家詳細(xì)介紹了Springboot jar包遠(yuǎn)程調(diào)試,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • java收集器Collector案例匯總

    java收集器Collector案例匯總

    這篇文章主要介紹了java收集器Collector案例匯總,Collectors作為Stream的collect方法的參數(shù),Collector是一個(gè)接口,它是一個(gè)可變的匯聚操作,更多相關(guān)介紹,需要的朋友可以參考下
    2022-06-06
  • Java注解方式之防止重復(fù)請(qǐng)求

    Java注解方式之防止重復(fù)請(qǐng)求

    這篇文章主要介紹了關(guān)于Java注解方式防止重復(fù)請(qǐng)求,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 新建springboot項(xiàng)目時(shí),entityManagerFactory報(bào)錯(cuò)的解決

    新建springboot項(xiàng)目時(shí),entityManagerFactory報(bào)錯(cuò)的解決

    這篇文章主要介紹了新建springboot項(xiàng)目時(shí),entityManagerFactory報(bào)錯(cuò)的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論