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

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

 更新時(shí)間:2022年09月09日 08:37:07   作者:隨風(fēng)21  
這篇文章主要為大家介紹了tomcat?集群監(jiān)控與彈性伸縮詳解,

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

任務(wù)分為 CPU 密集型和 IO 密集型

對(duì)于 CPU 密集型的應(yīng)用來(lái)說(shuō),需要大量 CPU 計(jì)算速度很快,線程池如果過(guò)多,則保存和切換上下文開銷過(guò)高反而會(huì)影響性能,可以適當(dāng)將線程數(shù)量調(diào)小一些

對(duì)于 IO 密集型應(yīng)用來(lái)說(shuō)常見于普通的業(yè)務(wù)系統(tǒng),比如會(huì)去查詢 mysql、redis 等然后在內(nèi)存中做簡(jiǎn)單的數(shù)據(jù)組裝和邏輯判斷,此時(shí)由于有 epoll、dma 等支持,消耗較長(zhǎng)時(shí)間的線程不會(huì)長(zhǎng)時(shí)間占據(jù) CPU 時(shí)間,所以可以適當(dāng)將線程數(shù)量調(diào)大一些

對(duì)于線程數(shù)到底該設(shè)置多大,網(wǎng)上有很多的方案

我們?cè)趯?shí)際情況中基于 wrk 等壓測(cè)工具進(jìn)行壓測(cè),壓測(cè)邏輯相對(duì)復(fù)雜請(qǐng)求量相對(duì)較高的接口先配置一個(gè)相對(duì)保守的值

先預(yù)估假設(shè)當(dāng)前接口處理平均耗時(shí) 300MS,1S 一個(gè)線程平均處理 3 個(gè)請(qǐng)求,最大 100 個(gè)線程 1S 能處理 300 TPS

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

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

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

那么監(jiān)控系統(tǒng)采集到線程池線程使用率達(dá)到了 80% 就開始擴(kuò)容,因?yàn)閿U(kuò)容拉起新的服務(wù)器到提供服務(wù)可能也需要1-2分鐘的時(shí)間,所以需要預(yù)留服務(wù)器資源能夠處理彈性擴(kuò)容期間的流量

實(shí)際場(chǎng)景中是相對(duì)比較復(fù)雜的,前期最好設(shè)置一個(gè)相對(duì)保守的擴(kuò)容閾值,如果發(fā)現(xiàn)在達(dá)到這個(gè)閾值前服務(wù)器已經(jīng)頂不住了就可以實(shí)時(shí)的縮小閾值

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

所以說(shuō)與其尋找一個(gè)準(zhǔn)確的計(jì)算線程池?cái)?shù)量的配置方式,不如提供一個(gè)可以動(dòng)態(tài)調(diào)整的線程池作為 tomcat 的線程池

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

spring boot 在啟動(dòng)過(guò)程中會(huì)調(diào)用 TomcatProtocolHandlerCustomizer 的實(shí)現(xiàn)類,此處可以自定化 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;
    }
}

然后將線程池裝入一個(gè)容器 bean 中注冊(cè)到 promethues 監(jiān)控中,當(dāng)每秒進(jìn)行采集的時(shí)候通過(guò)回調(diào)的方法去獲取線程池的最新指標(biāo)

promethues 每秒采集一次容器的線程池運(yùn)行指標(biāo)、服務(wù)器測(cè) CPU 使用率當(dāng)滿足定義的擴(kuò)容閾值時(shí)就拉起新的 POD

grafana 每秒采集一次 promethues 的數(shù)據(jù)匯聚圖標(biāo)展示

@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("注冊(cè) 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 線程池?cái)U(kuò)縮容

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

  • 修改 corePoolSize

(1)數(shù)量小于 maximumPoolSize 拋異常

(2)如果 corePoolSize - 原來(lái)的 = delta,delta 大于 0 那么創(chuàng)建等待隊(duì)列任務(wù)數(shù)量和 delta 個(gè)線程來(lái)處理等待處理的任務(wù)

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

  • 修改 maximumPoolSize

(1)maximumPoolSize 小于 corePoolSize 拋錯(cuò)

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

基于這些機(jī)制就能在運(yùn)行期間動(dòng)態(tài)調(diào)整線程池內(nèi)容

無(wú)需擔(dān)心會(huì)中斷掉正在運(yùn)行的任務(wù),因?yàn)榫€程池 worker 線程每執(zhí)行一個(gè)任務(wù)的時(shí)候

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

原生線程池的工作原理

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

(2)運(yùn)行的線程數(shù) >= 核心線程了,將任務(wù)全部積壓到隊(duì)列中

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

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

tomcat 如何優(yōu)化線程池,核心在于阻塞隊(duì)列的實(shí)現(xiàn),因?yàn)樽枞?duì)列滿了才會(huì)繼續(xù)創(chuàng)建非核心 worker 線程處理任務(wù)

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

(2)當(dāng)前已經(jīng)創(chuàng)建的核心+非核心線程數(shù)等于最大線程數(shù),任務(wù)壓入隊(duì)列

(3)正在處理的請(qǐng)求數(shù)量小于核心+非核心線程數(shù),任務(wù)壓入隊(duì)列

(4)當(dāng)前已經(jīng)創(chuàng)建的核心+非核心線程數(shù)小于最大線程數(shù),創(chuàng)建 worker 線程處理請(qǐng)求

總結(jié)就是一句話當(dāng)高并發(fā)流量過(guò)來(lái)的時(shí)候,會(huì)去創(chuàng)建最大線程數(shù)的 worker 去處理請(qǐng)求用以降低尾延遲,超過(guò)最大線程后,任務(wù)將被壓入隊(duì)列中進(jìn)行處理

以上就是tomcat 集群監(jiān)控與彈性伸縮詳解的詳細(xì)內(nèi)容,更多關(guān)于tomcat 集群監(jiān)控彈性伸縮的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Tomcat在linux環(huán)境中開機(jī)自啟(定時(shí)重啟)的方法

    Tomcat在linux環(huán)境中開機(jī)自啟(定時(shí)重啟)的方法

    我們經(jīng)常會(huì)遇到服務(wù)器斷電或異常,而異常后tomcat中部署的web項(xiàng)目需要我手動(dòng)去啟動(dòng),為此,特別貢獻(xiàn)出Linux環(huán)境中Tomcat開機(jī)自啟的方式供學(xué)習(xí)使用,需要的朋友可以參考下
    2023-10-10
  • 如何解決tomcat管理頁(yè)面403 Access Denied問(wèn)題

    如何解決tomcat管理頁(yè)面403 Access Denied問(wèn)題

    這篇文章主要介紹了如何解決tomcat管理頁(yè)面403 Access Denied問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 詳解關(guān)于tomcat切割catalina.out日志的三種方式

    詳解關(guān)于tomcat切割catalina.out日志的三種方式

    這篇文章主要介紹了詳解關(guān)于tomcat切割catalina.out日志的三種方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • 深度解析Tomcat 線程池與 JDK 線程池的區(qū)別和聯(lián)系

    深度解析Tomcat 線程池與 JDK 線程池的區(qū)別和聯(lián)系

    Tomcat 線程池和 JDK 線程池都是在 Java 開發(fā)中非常有用的工具,用于處理不同類型的并發(fā)任務(wù),本文將深入探討 Tomcat 線程池與JDK 線程池之間的區(qū)別和聯(lián)系,以幫助開發(fā)人員更好地理解它們的工作原理和如何在自己的項(xiàng)目中使用它們
    2023-11-11
  • Tomcat獲取Nginx反向代理的客戶端域名

    Tomcat獲取Nginx反向代理的客戶端域名

    今天小編就為大家分享一篇關(guān)于Tomcat獲取Nginx反向代理的客戶端域名,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • 基于Tomcat 數(shù)據(jù)源的原理、配置、使用介紹

    基于Tomcat 數(shù)據(jù)源的原理、配置、使用介紹

    下面小編就為大家?guī)?lái)一篇基于Tomcat 數(shù)據(jù)源的原理、配置、使用介紹。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 解決tomcat出現(xiàn):java.lang.IllegalStateException:無(wú)輸出目錄問(wèn)題

    解決tomcat出現(xiàn):java.lang.IllegalStateException:無(wú)輸出目錄問(wèn)題

    這篇文章主要介紹了解決tomcat出現(xiàn):java.lang.IllegalStateException:無(wú)輸出目錄問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-01-01
  • tomcat配置虛擬路徑的實(shí)現(xiàn)步驟

    tomcat配置虛擬路徑的實(shí)現(xiàn)步驟

    本文主要介紹了tomcat配置虛擬路徑的實(shí)現(xiàn)步驟,主要是在localhost文件中進(jìn)行配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Windows系統(tǒng)下安裝Tomcat服務(wù)器和配置虛擬目錄的方法

    Windows系統(tǒng)下安裝Tomcat服務(wù)器和配置虛擬目錄的方法

    這篇文章主要介紹了Windows系統(tǒng)下安裝Tomcat服務(wù)器和配置虛擬目錄的方法,Tomcat服務(wù)器用于驅(qū)動(dòng)JSP和Servlet程序,需要的朋友可以參考下
    2015-12-12
  • startup.bat啟動(dòng)Tomcat閃退問(wèn)題原因及解決

    startup.bat啟動(dòng)Tomcat閃退問(wèn)題原因及解決

    本文主要介紹了startup.bat啟動(dòng)Tomcat閃退問(wèn)題原因及解決,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04

最新評(píng)論

江城| 临湘市| 时尚| 长沙市| 屯门区| 天全县| 光山县| 西安市| 汕尾市| 湖口县| 德令哈市| 威远县| 兴文县| 横山县| 罗定市| 舒兰市| 顺昌县| 枣阳市| 天峻县| 广安市| 江城| 江安县| 资源县| 精河县| 临西县| 延长县| 塔河县| 上杭县| 长顺县| 望谟县| 玉田县| 华坪县| 阜阳市| 应用必备| 鹿泉市| 桂平市| 伽师县| 高雄县| 利川市| 山西省| 苏尼特左旗|