亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

趙連江 / 1934人閱讀

摘要:在使用過程中,我們可以使用注解可以方便的實(shí)現(xiàn)定時(shí)任務(wù)。默認(rèn)單線程經(jīng)排查后發(fā)現(xiàn),我們使用注解默認(rèn)的配置的話,所有的任務(wù)都是單線程去跑的。參數(shù)其實(shí)代表了每個(gè)路由的最大連接數(shù)。怪不得當(dāng)時(shí)在高并發(fā)情況下總會(huì)出現(xiàn)超時(shí),明明已經(jīng)設(shè)的很高。

前言

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

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

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

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

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

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

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

如果需要開啟多線程處理,則需要進(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全部卡住的問題。

但是為什么會(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();

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

追蹤源碼可以發(fā)現(xiàn),在使用上述方式進(jìn)行配置的時(shí)候,HttpClient的timeout時(shí)間竟然全部都是-1,也就是說(shuō)如果對(duì)方服務(wù)有問題,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í)間,問題就解決了。例如:

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è)問題

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

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

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

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

public PoolingHttpClientConnectionManager(
  final HttpClientConnectionOperator httpClientConnectionOperator,
  final HttpConnectionFactory 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ù),并且并發(fā)量比較大,一定要好好配置maxTotal和defaultMaxPerRoute兩個(gè)參數(shù)。

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

總結(jié)

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/74399.html

相關(guān)文章

  • Springboot定時(shí)任務(wù)踩記錄

    摘要:前言在使用整合定時(shí)任務(wù),發(fā)現(xiàn)當(dāng)某個(gè)定時(shí)任務(wù)執(zhí)行出現(xiàn)執(zhí)行時(shí)間過長(zhǎng)的情況時(shí)會(huì)阻塞其他定時(shí)任務(wù)的執(zhí)行。問題定位后續(xù)通過翻查的文檔以及打印日志輸出當(dāng)前線程信息得知問題是由于默認(rèn)使用只要個(gè)線程處理定時(shí)任務(wù)。問題復(fù)盤需要注意示例的版本為。 前言 在使用Springboot整合定時(shí)任務(wù),發(fā)現(xiàn)當(dāng)某個(gè)定時(shí)任務(wù)執(zhí)行出現(xiàn)執(zhí)行時(shí)間過長(zhǎng)的情況時(shí)會(huì)阻塞其他定時(shí)任務(wù)的執(zhí)行。 問題定位 后續(xù)通過翻查Springboo...

    liujs 評(píng)論0 收藏0
  • Spring之定時(shí)任務(wù)基本使用篇

    摘要:表示起始時(shí)間開始觸發(fā),然后每隔固定時(shí)間觸發(fā)一次如在域使用則意味著分鐘觸發(fā)一次,而,等分別觸發(fā)一次表示列出枚舉值值。 showImg(https://segmentfault.com/img/remote/1460000015852353); 文章鏈接:https://liuyueyi.github.io/hexblog/2018/08/01/180801-Spring之定時(shí)任務(wù)基本使用...

    Jingbin_ 評(píng)論0 收藏0
  • SpringBoot并發(fā)定時(shí)任務(wù)實(shí)現(xiàn)、動(dòng)態(tài)定時(shí)任務(wù)實(shí)現(xiàn)(看這一篇就夠了)

    摘要:也是自帶的一個(gè)基于線程池設(shè)計(jì)的定時(shí)任務(wù)類。其每個(gè)調(diào)度任務(wù)都會(huì)分配到線程池中的一個(gè)線程執(zhí)行,所以其任務(wù)是并發(fā)執(zhí)行的,互不影響。 原創(chuàng)不易,如需轉(zhuǎn)載,請(qǐng)注明出處https://www.cnblogs.com/baixianlong/p/10659045.html,否則將追究法律責(zé)任?。。?一、在JAVA開發(fā)領(lǐng)域,目前可以通過以下幾種方式進(jìn)行定時(shí)任務(wù) 1、單機(jī)部署模式 Timer:jdk中...

    BWrong 評(píng)論0 收藏0
  • spring-boot | 多線程并發(fā)定時(shí)任務(wù)

    摘要:多線程并發(fā)定時(shí)任務(wù)剛剛看了下實(shí)現(xiàn)定時(shí)任務(wù)的文章,感覺還不錯(cuò)。存在問題但是后來(lái)發(fā)現(xiàn)個(gè)問題,通過同時(shí)測(cè)試幾個(gè)任務(wù)發(fā)現(xiàn),所有的任務(wù)都是在同一個(gè)線程池中的同一個(gè)線程來(lái)完成的。 spring-boot | 多線程并發(fā)定時(shí)任務(wù) 剛剛看了下Spring Boot實(shí)現(xiàn)定時(shí)任務(wù)的文章,感覺還不錯(cuò)。Spring Boot 使用Spring自帶的Schedule來(lái)實(shí)現(xiàn)定時(shí)任務(wù)變得非常簡(jiǎn)單和方便。在這里個(gè)大家...

    silenceboy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

趙連江

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<