日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

目錄
  • 如何給 tomcat 配置合適的線程池
  • 如何監(jiān)控 tomcat 線程池的工作情況
  • tomcat 線程池擴縮容
  • tomcat 是如何避免原生線程池的缺陷的

如何給 tomcat 配置合適的線程池

任務分為 CPU 密集型和 IO 密集型

對于 CPU 密集型的應用來說,需要大量 CPU 計算速度很快,線程池如果過多,則保存和切換上下文開銷過高反而會影響性能,可以適當將線程數量調小一些

對于 IO 密集型應用來說常見于普通的業(yè)務系統,比如會去查詢 mysql、redis 等然后在內存中做簡單的數據組裝和邏輯判斷,此時由于有 epoll、dma 等支持,消耗較長時間的線程不會長時間占據 CPU 時間,所以可以適當將線程數量調大一些

對于線程數到底該設置多大,網上有很多的方案

tomcat?集群監(jiān)控與彈性伸縮詳解

我們在實際情況中基于 wrk 等壓測工具進行壓測,壓測邏輯相對復雜請求量相對較高的接口先配置一個相對保守的值

先預估假設當前接口處理平均耗時 300MS,1S 一個線程平均處理 3 個請求,最大 100 個線程 1S 能處理 300 TPS

粗略估算每個請求會消耗多大的內容空間,假如是 2KB,那么每秒會消耗 600KB 以此來估算 YGC 多久會觸發(fā)一次,假設年輕代為 1GB 那么大約 29 分鐘觸發(fā)一次 YGC

然后再看 100 個線程持續(xù)處理 300TPS 的時候 CPU 消耗情況

觀察內存幾分鐘 GC 一次,或者 CPU 使用率穩(wěn)定在 50% 左右就好,假設此時線程池 70 個線程都在運作

那么監(jiān)控系統采集到線程池線程使用率達到了 80% 就開始擴容,因為擴容拉起新的服務器到提供服務可能也需要1-2分鐘的時間,所以需要預留服務器資源能夠處理彈性擴容期間的流量

實際場景中是相對比較復雜的,前期最好設置一個相對保守的擴容閾值,如果發(fā)現在達到這個閾值前服務器已經頂不住了就可以實時的縮小閾值

同時還可以根據在達到擴容閾值擴容的時候,觀察線上真實的 CPU 和內存使用情況,可以基于 promethues + grafana 來進行監(jiān)控,如果發(fā)現擴容時候 CPU 使用率和內存使用率 GC 評率比較低,那么可以再配置中心動態(tài)的調整線程池的大小

所以說與其尋找一個準確的計算線程池數量的配置方式,不如提供一個可以動態(tài)調整的線程池作為 tomcat 的線程池

如何監(jiān)控 tomcat 線程池的工作情況

spring boot 在啟動過程中會調用 TomcatProtocolHandlerCustomizer 的實現類,此處可以自定化 tomcat 線程池,也可以獲取到 tomcat 線程池

public class MyTomcatProtocolHandlerCustomizer implements TomcatProtocolHandlerCustomizer<ProtocolHandler> {
    private final ThreadPoolExecutor tomcatThreadPoolExecutor;
    public TomcatProtocolHandlerCustomizer(ThreadPoolExecutor tomcatThreadPoolExecutor) {
        this.tomcatThreadPoolExecutor = tomcatThreadPoolExecutor;
    }
    @Override
    public void customize(ProtocolHandler protocolHandler) {
        protocolHandler.setExecutor(tomcatThreadPoolExecutor);
    }
    public ThreadPoolExecutor getThreadPoolExecutor() {
        return tomcatThreadPoolExecutor;
    }
}

然后將線程池裝入一個容器 bean 中注冊到 promethues 監(jiān)控中,當每秒進行采集的時候通過回調的方法去獲取線程池的最新指標

promethues 每秒采集一次容器的線程池運行指標、服務器測 CPU 使用率當滿足定義的擴容閾值時就拉起新的 POD

grafana 每秒采集一次 promethues 的數據匯聚圖標展示

@Bean
public AllServersThreadPoolCollector allServersThreadPoolCollector(@Qualifier(value = "GrpcThreadPoolExecutor") ThreadPoolExecutor GrpcThreadPoolExecutor,
                                                                   @Qualifier(value = "jdTomcatThreadPoolExecutor") org.apache.tomcat.util.threads.ThreadPoolExecutor TomcatThreadPoolExecutor,
                                                                   MeterRegistry registry) {
    return new AllServersThreadPoolCollector(GrpcThreadPoolExecutor, jdTomcatThreadPoolExecutor, registry);
}
public void init() {
    try {
        createGauge(this, "grpc_tomcat_core_pool_size", pool -&gt; this.getCorePoolSize());
        createGauge(this, "grpc_tomcat_maximum_pool_size", pool -&gt; this.getMaximumPoolSize());
        createGauge(this, "grpc_tomcat_busy_pool_size", pool -&gt; this.getActiveCount());
        createGauge(this, "grpc_tomcat_wait_queue_size", pool -&gt; this.getWaitQueueSize());
    } catch (Exception e) {
        log.error("注冊 all servers 監(jiān)控失敗", e);
    }
}
private void createGauge(AllServersThreadPoolCollector weakRef, String metric, ToDoubleFunction&lt;AllServersThreadPoolCollector&gt; measure) {
    Gauge.builder(metric, weakRef, measure)
            .register(this.registry);
}
public int getWaitQueueSize() {
    return grpcThreadPoolExecutor.getQueue().size() + tomcatThreadPoolExecutor.getQueue().size();
}

tomcat 線程池擴縮容

Java 線程池是支持直接修改 corePoolSize、maximumPoolSize 的

  • 修改 corePoolSize

(1)數量小于 maximumPoolSize 拋異常

(2)如果 corePoolSize – 原來的 = delta,delta 大于 0 那么創(chuàng)建等待隊列任務數量和 delta 個線程來處理等待處理的任務

(3)如果正在運行的線程數量 > corePoolSize 那么就中斷多余的線程

  • 修改 maximumPoolSize

(1)maximumPoolSize 小于 corePoolSize 拋錯

(2)如果運行的線程大于 maximumPoolSize 中斷掉一些空閑的線程

基于這些機制就能在運行期間動態(tài)調整線程池內容

無需擔心會中斷掉正在運行的任務,因為線程池 worker 線程每執(zhí)行一個任務的時候

tomcat 是如何避免原生線程池的缺陷的

原生線程池的工作原理

(1)運行的線程數小于核心線程,就創(chuàng)建一個 worker 線程去執(zhí)行任務

(2)運行的線程數 >= 核心線程了,將任務全部積壓到隊列中

(3)隊列如果滿了繼續(xù)創(chuàng)建非核心線程 worker 去執(zhí)行任務

假如 tomcat 采用了原生線程池,核心線程為 10 個,最大線程為 100,隊列為 200,并發(fā)來了 100 個請求,那么同時系統只能處理 10 個,剩下 90 個都得放入隊列中讓 10 個核心線程慢慢排隊處理,延時必然非常高

tomcat 如何優(yōu)化線程池,核心在于阻塞隊列的實現,因為阻塞隊列滿了才會繼續(xù)創(chuàng)建非核心 worker 線程處理任務

(1)運行的線程數小于核心線程,就創(chuàng)建一個 worker 線程去執(zhí)行任務

(2)當前已經創(chuàng)建的核心+非核心線程數等于最大線程數,任務壓入隊列

(3)正在處理的請求數量小于核心+非核心線程數,任務壓入隊列

(4)當前已經創(chuàng)建的核心+非核心線程數小于最大線程數,創(chuàng)建 worker 線程處理請求

總結就是一句話當高并發(fā)流量過來的時候,會去創(chuàng)建最大線程數的 worker 去處理請求用以降低尾延遲,超過最大線程后,任務將被壓入隊列中進行處理

以上就是tomcat 集群監(jiān)控與彈性伸縮詳解的詳細內容,更多關于tomcat 集群監(jiān)控彈性伸縮的資料請關注其它相關文章!

分享到:
標簽:伸縮 彈性 監(jiān)控 詳解 集群
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰(zhàn)2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定