国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

頁面查詢多項數據組合的線程池設計

這篇具有很好參考價值的文章主要介紹了頁面查詢多項數據組合的線程池設計。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

背景

我們應對并發(fā)場景時一般會采用下面方式去預估線程池的線程數量,比如QPS需求是1000,平均每個任務需要執(zhí)行的時間是t秒,那么我們需要的線程數是t * 1000。

但是在一些情況下,這個t是不好估算的,即便是估算出來了,在實際的線程環(huán)境上也需要進行驗證和微調。比如在本文所闡述分頁查詢的數據項組合場景中。

1、數據組合依賴不同的上游接接口, 它們的響應時間參差不齊,甚至差距還非常大。有些接口支持批量查詢而另一些則不支持批量查詢。有些接口因為性能問題還需要考慮降級和平滑方案。

2、為了提升用戶體驗,這里的查詢設計了動態(tài)列,因此每一次訪問所需要組合的數據項和數量也是不同的。

因此這里如果需要估算出一個合理的t是不太現實的。

方案

一種可動態(tài)調節(jié)的策略,根據監(jiān)控的反饋對線程池進行微調。整體設計分為裝配邏輯線程池封裝設計。

1、裝配邏輯

查詢結果,拆分分片(水平拆分),并行裝配(垂直拆分),獲得裝配項列表(動態(tài)列), 并行裝配每一項。

2、線程池封裝

可調節(jié)的核心線程數、最大線程數、線程保持時間,隊列大小,提交任務重試等待時間,提交任務重試次數。 固定異常拒絕策略。

調節(jié)參數:

字段 名稱 說明
corePoolSize 核心線程數 參考線程池定義
maximumPoolSize 最大線程數 參考線程池定義
keepAliveTime 線程存活時間 參考線程池定義
queueSize 隊列長度 參考線程池定義
resubmitSleepMillis 提交任務重試等待時間 添加任務被拒絕后重試時的等待時間
resubmitTimes 提交任務重試次數 添加任務被拒絕后重試添加的最大次數
    @Data
	private static class PoolPolicy {

		/** 核心線程數 */
		private Integer corePoolSize;

		/** 最大線程數 */
		private Integer maximumPoolSize;

		/** 線程存活時間 */
		private Integer keepAliveTime;

		/** 隊列容量 */
		private Integer queueSize;

		/** 重試等待時間 */
		private Long resubmitSleepMillis;

		/** 重試次數 */
		private Integer resubmitTimes;
	}

創(chuàng)建線程池:

線程池的創(chuàng)建考慮了動態(tài)的需求,滿足根據壓測結果進行微調的要求。首先緩存舊的線程池后再創(chuàng)建新的線程,當新的線程池創(chuàng)建成功后再去關閉舊的線程池。保證在這個替換過程中不影響正在執(zhí)行的業(yè)務。線程池使用了中斷策略,用戶可以及時感知到系統(tǒng)繁忙并保證了系統(tǒng)資源占用的安全。

public void reloadThreadPool(PoolPolicy poolPolicy) {
    if (poolPolicy == null) {
        throw new RuntimeException("The thread pool policy cannot be empty.");
    }
    if (poolPolicy.getCorePoolSize() == null) {
        poolPolicy.setCorePoolSize(0);
    }
    if (poolPolicy.getMaximumPoolSize() == null) {
        poolPolicy.setMaximumPoolSize(Runtime.getRuntime().availableProcessors() + 1);
    }
    if (poolPolicy.getKeepAliveTime() == null) {
        poolPolicy.setKeepAliveTime(60);
    }
    if (poolPolicy.getQueueSize() == null) {
        poolPolicy.setQueueSize(Runtime.getRuntime().availableProcessors() + 1);
    }
    if (poolPolicy.getResubmitSleepMillis() == null) {
        poolPolicy.setResubmitSleepMillis(200L);
    }
    if (poolPolicy.getResubmitTimes() == null) {
        poolPolicy.setResubmitTimes(5);
    }
    // - 線程池策略沒有變化直接返回已有線程池。
    ExecutorService original = this.executorService;
    this.executorService = new ThreadPoolExecutor(
            poolPolicy.getCorePoolSize(),
            poolPolicy.getMaximumPoolSize(),
            poolPolicy.getKeepAliveTime(), TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(poolPolicy.getQueueSize()),
            new ThreadFactoryBuilder().setNameFormat(threadNamePrefix + "-%d").setDaemon(true).build(),
            new ThreadPoolExecutor.AbortPolicy());
    this.poolPolicy = poolPolicy;
    if (original != null) {
        original.shutdownNow();
    }
}

任務提交:

線程池封裝對象中使用的線程池拒絕策略是AbortPolicy,因此在線程數和阻塞隊列到達上限后會觸發(fā)異常。另外在這里為了保證提交的成功率利用重試策略實現了一定程度的延遲處理,具體場景中可以結合業(yè)務特點進行適當的調節(jié)和配置。

public <T> Future<T> submit(Callable<T> task) {
    RejectedExecutionException exception = null;
    Future<T> future = null;
    for (int i = 0; i < this.poolPolicy.getResubmitTimes(); i++) {
        try {
            // - 添加任務
            future = this.executorService.submit(task);
            exception = null;
            break;
        } catch (RejectedExecutionException e) {
            exception = e;
            this.theadSleep(this.poolPolicy.getResubmitSleepMillis());
        }
    }
    if (exception != null) {
        throw exception;
    }
    return future;
}

監(jiān)控:

1、submit提交的監(jiān)控

見代碼中的「監(jiān)控點①」,在submit方法中添加監(jiān)控點,監(jiān)控key的需要添線程池封裝對象的線程名稱前綴,用于區(qū)分具體的線程池對象。

「監(jiān)控點①」用于監(jiān)控添加任務的動作是否正常,以便對線程池對象及策略參數進行微調。

public <T> Future<T> submit(Callable<T> task) {
    // - 監(jiān)控點①
    CallerInfo callerInfo = Profiler.registerInfo(UmpConstant.THREAD_POOL_WAP + threadNamePrefix,
                UmpConstant.APP_NAME,
                UmpConstant.UMP_DISABLE_HEART,
                UmpConstant.UMP_ENABLE_TP);
    RejectedExecutionException exception = null;
    Future<T> future = null;
    for (int i = 0; i < this.poolPolicy.getResubmitTimes(); i++) {
        try {
            // - 添加任務
            future = this.executorService.submit(task);
            exception = null;
            break;
        } catch (RejectedExecutionException e) {
            exception = e;
            this.theadSleep(this.poolPolicy.getResubmitSleepMillis());
        }
    }
    if (exception != null) {
        // - 監(jiān)控點①
        Profiler.functionError(callerInfo);
        throw exception;
    }
    // - 監(jiān)控點①
    Profiler.registerInfoEnd(callerInfo);
    return future;
}

2、線程池并行任務

見代碼的「監(jiān)控點②」,分別在添加任務和任務完成后。

「監(jiān)控點②」實時統(tǒng)計在線程中執(zhí)行的總任務數量,用于評估線程池的任務的數量的滿載水平。

/** 任務并行數量統(tǒng)計 */
private AtomicInteger parallelTaskCount = new AtomicInteger(0);

public <T> Future<T> submit(Callable<T> task) {
    RejectedExecutionException exception = null;
    Future<T> future = null;
    for (int i = 0; i < this.poolPolicy.getResubmitTimes(); i++) {
        try {
            // - 添加任務
            future = this.executorService.submit(()-> {
                T rst = task.call();
                // - 監(jiān)控點②
                log.info("{} - Parallel task count {}", this.threadNamePrefix,  this.parallelTaskCount.decrementAndGet());
                return rst;
            });
            // - 監(jiān)控點②
            log.info("{} + Parallel task count {}", this.threadNamePrefix,  this.parallelTaskCount.incrementAndGet());
            exception = null;
            break;
        } catch (RejectedExecutionException e) {
            exception = e;
            this.theadSleep(this.poolPolicy.getResubmitSleepMillis());
        }
    }
    if (exception != null) {
        throw exception;
    }
    return future;
}

3、調節(jié)

線程池封裝對象策略的調節(jié)時機

1)上線前基于流量預估的壓測階段;

2)上線后跟進監(jiān)控數據和線程池中任務的滿載水平進行人工微調,也可以通過JOB在指定的時間自動調整;

3)大促前依據往期大促峰值來調高相關參數。

線程池封裝對象策略的調節(jié)經驗

1)訪問時長要求較低時,我們可以考慮調小線程數和阻塞隊列,適當調大提交任務重試等待時間和次數,以便降低資源占用。

2)訪問時長要求較高時,就需要調大線程數并保證相對較小的阻塞隊列,調小提交任務的重試等待時間和次數甚至分別調成0和1(即關閉重試提交邏輯)。

作者:京東零售 王文明

來源:京東云開發(fā)者社區(qū) 轉載請注明來源文章來源地址http://www.zghlxwxcb.cn/news/detail-711518.html

到了這里,關于頁面查詢多項數據組合的線程池設計的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • mongo——or查詢包含多項模糊匹配

    MongoDB OR 條件語句使用了? $or MongoDB 模糊查詢使用了? $regex 兩者整合在一起,語法格式如下:

    2024年02月12日
    瀏覽(12)
  • JDK 21預告:虛擬線程正式發(fā)布及十多項新特性

    Java 21進入發(fā)布候選階段,其中包括15個最終特性,包括虛擬線程、分代Z垃圾收集器和密鑰封裝機制API。 JDK21計劃于9月19日作為Oracle標準Java實現的下一個LTS版本發(fā)布,已進入發(fā)布候選(RC)階段。Java 21將具有15個新特性,之前提議的第16個特性實驗性Shenandoah垃圾收集器已在6月被舍

    2024年02月10日
    瀏覽(26)
  • java查詢數據庫百萬條數據,優(yōu)化之:多線程+數據庫

    java查詢數據庫百萬條數據,優(yōu)化之:多線程+數據庫

    今天去面試時hr問了個關于大量數據查詢的問題。 面試官:“我們公司是做數據分析的,每次需要從數據庫中查詢100萬條數據進行分析,該接口不能用分頁(不限制具體怎么實現),請問怎么優(yōu)化sql或者java代碼呢??” 如果用普通查詢需要5分多分鐘才查詢完畢,所以我們用

    2024年02月15日
    瀏覽(21)
  • 編寫jsp頁面實現對數據庫表的查詢

    編寫jsp頁面實現對數據庫表的查詢

    在本次作業(yè)中,我將eclipse與sql server連接起來,并在SSMS中進行插入數據,從而編寫jsp頁面實現對數據庫表的查詢。 一、連接數據庫 按照(4條消息) eclipse連接SQL server數據庫_eclipse如何連接數據庫_shexianyu的博客-CSDN博客 教程中的步驟,最初只得到了加載驅動成功,連接數據庫失

    2024年02月07日
    瀏覽(15)
  • Elasticsearch 中 bool組合查詢(must 和 should 組合)

    需求 查詢考試成績是 60分 或 90分 的 女生 。 所以查詢條件應該這么寫 sex == \\\'女\\\' ( score == 60 || score ==90 ); ?先看下bool的語法 在ES中的實現 方式一: 在bool查詢的must 中再嵌套一層bool來做should過濾。 方式二: 使用 minimum_should_match 選項 ,至少匹配一項should子句。 GET stu/_search

    2023年04月09日
    瀏覽(16)
  • vue設置頁面背景及背景圖片

    vue設置頁面背景及背景圖片

    本地靜態(tài)圖片? cdn圖片 設置背景色 實戰(zhàn)-PC web登錄頁 實戰(zhàn)-小程序登錄頁

    2024年02月12日
    瀏覽(28)
  • 【MySQL】組合查詢

    【MySQL】組合查詢

    目錄 一、組合查詢 1.創(chuàng)建組合查詢 2.union規(guī)則 3.包含或取消重復的行 4.對組合查詢結果排序 一、組合查詢 ? ? ? ? 多數SQL查詢都只包含從一個或多個表中返回數據的單條SELECT語句。MySQL也允許執(zhí)行多個查詢(多條SELECT語句),并將結果作為單個查詢結果返回。 這些組合查詢

    2024年02月11日
    瀏覽(14)
  • Elasticsearch 組合查詢的使用

    這里介紹Elasticsearch 中的組合查詢的使用細節(jié),Elasticsearch支持類似于在SQL中使用AND、OR以及NOT的運算符,可以通過組合嵌套這些條件進行復雜的數據篩選。 數據準備 復用上篇文章的mapping和數據供這里的demo使用。 mapping: 數據: filter的用法 在使用filter查詢的時候,會使用一

    2024年02月08日
    瀏覽(13)
  • ES組合查詢-Boolean Query

    ES組合查詢-Boolean Query

    BooleanQuery可以將多個查詢語句組合在一起。下面是一個基礎的模板: 上面是從官網搬過來的官網地址 must 中的語句是必須滿足的,會影響最終文檔的得分 filter 中的語句是必須滿足的,但是不會影響最終的得分 must_not 中的語句是必須不滿足的, 不影響最終的得分 should 中的語

    2023年04月20日
    瀏覽(17)
  • ElasticSearch系列 - SpringBoot整合ES:組合多個查詢條件 bool 查詢

    01. ElasticSearch 布爾查詢是什么? 在實際應用中,我們很有可能會查詢多個值或字段。 一個 bool 查詢由三部分組成: must:所有的語句都必須(must) 匹配,與 AND 等價。 must_not:所有的語句都不能(must not)匹配,與 NOT 等價。 should:至少有一個語句要匹配,與 OR 等價。 02.

    2023年04月08日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包