はじめに
Webシステムの性能を改善するとき、TomcatのmaxThreadsやmaxConnectionsを大きくすれば、より多くのRequestを処理できるように思えるかもしれません。
しかし、設定値を増やしても、CPUやDBの処理能力が増えるわけではありません。受け入れるRequestが増えた結果、待ち時間やMemory使用量が増え、かえって性能が悪化することもあります。
Tomcatのパフォーマンス設計で重要なのは、「接続を受け入れる数」「同時に処理する数」「待たせる量」「待てる時間」を、システムの処理能力に合わせることです。
本記事では、Connection、Thread Pool、Queue、Timeoutの関係を図解しながら、設定値を決める考え方を解説します。
本記事の前提:主にTomcat 10.1のHTTP/1.1 Connectorと、Platform Threadを使用する同期Servlet処理を想定しています。設定値は説明用です。HTTP/2、Servlet非同期処理、Virtual Threadでは、Connection・Request・Threadの対応関係が異なります。HeapやGCなどのJVM内部設計は、Chapter 8で扱います。
Tomcatのパフォーマンス設計とは
Tomcatは、JavaのWeb Applicationを実行するServlet Containerです。
Apache HTTP ServerやNginxを前段に配置する構成では、Tomcatは転送されたRequestを受け取り、Applicationを実行してResponseを返します。

各層には、それぞれ処理能力の上限があります。
| 層 | 主な役割 | 性能に関わる要素 |
|---|---|---|
| Apache / Nginx | 接続受付、転送、負荷分散 | 接続数、転送量、Timeout |
| Tomcat | HTTP処理、Applicationの実行管理 | Thread、Connection、Queue |
| Application | 業務ロジックの実行 | 計算量、SQL、外部通信 |
| Database / 外部API | データ処理、連携処理 | 同時実行数、応答時間 |
Tomcatの性能設計では、最初に次の問いを整理します。
- 毎秒何件のRequestを処理したいか
- 何ms以内にResponseを返したいか
- 同時に何件まで処理できるか
- 一時的な負荷増加をどこまで待たせるか
- 処理できないときに、どこで打ち切るか
- Nodeが停止しても必要な性能を維持できるか
設定値を決める前に、必要な処理量と応答時間を明確にすることが出発点です。
TomcatのRequest処理の全体像
Tomcatの動作を理解するには、ConnectionとThreadを分けて考える必要があります。ConnectionはHTTP通信を維持するための経路であり、Threadは実際にRequestを処理する単位です。TomcatのNIO Connectorでは、接続を保持している間ずっとWorker Threadを占有するわけではありません。

Tomcat 10.1の標準的なHTTP/1.1 NIO Connectorでは、Acceptorが接続を受け入れ、PollerがSocketのI/Oイベントを監視し、処理が必要になったRequestをWorker Threadへ渡します。通常の同期Servletでは、Worker ThreadがApplication処理を担当します。
また、Tomcatが受け付けるHTTP接続と、Applicationが使うDB接続は別のものです。
Web Server ←─ HTTP接続 ─→ Tomcat
Application ←─ DB接続 ─→ Database
この二つを混同すると、接続数の設計を誤りやすくなります。たとえば、HTTP接続が1,000本あっても、DB接続を1,000本用意する必要はありません。
Connectorの仕組み
Connectorは、Tomcatの通信の入口です。
指定したPortで接続を受け付け、HTTP通信を処理し、RequestをServlet Container側へ渡します。NIO Connectorでは、Acceptor、Poller、Worker Threadが役割を分担します。Applicationの処理結果は、Connectorを通じてResponseとして返されます。

server.xmlに記述する設定例は、次のとおりです。
<Connector
port="8080"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="200"
maxConnections="2000"
acceptCount="100"
connectionTimeout="20000"
keepAliveTimeout="10000"
maxKeepAliveRequests="100"
/>各設定の役割を、まず大まかに押さえましょう。
| 設定 | 制御する対象 |
|---|---|
maxThreads | Request処理用Threadの上限 |
maxConnections | Tomcatが同時に受け入れて保持する接続数の上限 |
acceptCount | OS側の接続受付待ち行列の長さに関係する設定 |
connectionTimeout | 接続後のRequest受信待ちに関わる時間 |
keepAliveTimeout | 次のRequestを待つ時間 |
maxKeepAliveRequests | 1接続で処理するRequest数の上限 |
これらは、それぞれ異なるResourceや待ち時間を制御するため、数値をそろえる必要はありません。特に重要なのは、maxConnectionsとmaxThreadsが別の上限を表すことです。maxConnectionsはTomcatが同時に受け入れて保持するConnection数、maxThreadsは通常の同期処理で同時にRequestを処理するWorker Thread数の上限です。

参考:Tomcat HTTP Connector公式ドキュメント
なお、Spring Bootなどの組み込みTomcatでは、設定の入口が異なります。ここではTomcatの設定名を使って説明します。
Connector方式の選択
Tomcat 10.1では、HTTP ConnectorとしてNIOとNIO2を利用できます。
| 方式 | Protocolクラス |
|---|---|
| NIO | org.apache.coyote.http11.Http11NioProtocol |
| NIO2 | org.apache.coyote.http11.Http11Nio2Protocol |
NIOはSelectorなどを使って通信の準備ができた接続を扱い、NIO2は非同期I/Oの仕組みを利用します。
どちらも、KeepAliveで次のRequestを待っている接続に対して、処理用Threadを1本ずつ割り当て続ける必要はありません。
ただし、Connectorの通信方式と、Applicationの実行方式は別です。ApplicationのDB処理まで自動的に非同期になるわけではありません。
通常の同期ServletでDB応答を待っていれば、そのRequestを担当するThreadは待機したままです。
参考:Tomcat HTTP Connector公式ドキュメント
方式を選ぶ際は、名前だけで性能を判断せず、同じ負荷条件で比較します。確認するのは、Throughput、応答時間、CPU使用量、接続の増減に対する安定性です。
方式の変更だけで大きな改善を期待する前に、ApplicationやDBの待ち時間も調べましょう。
Thread Poolの仕組み
Thread Poolは、Requestを処理するThreadを管理する仕組みです。

ここで大切なのは、処理中ThreadのすべてがCPUを使っているわけではないという点です。
同期処理では、DB接続の取得待ち、SQLの応答待ち、外部APIの応答待ちも、Threadの占有時間に含まれます。
CPU使用率は低い + 使用中Threadは上限に近い + Response Timeが長い
この場合は、CPU不足よりも、何かを待っている可能性を考えます。
TomcatはConnector内部のThread Poolを使用できます。また、複数のConnectorで共有するExecutorも設定できます。
共有Executorを使う場合、Thread数はExecutor側で管理します。複数の入口が同じPoolを使うため、一方の負荷がもう一方に影響する点も考慮します。
maxThreadsの設計
maxThreadsは、同時に動かせる処理用Thread数の上限です。ただし、共有Executorを指定している場合は、Connector側の値ではなくExecutor側の設定が使われます。
Thread数の初期検討には、次の関係が役立ちます。
平均使用中Thread数 ≒ Throughput × 平均Thread占有時間たとえば、500 RPSを処理し、平均Thread占有時間が0.2秒なら、次のようになります。RPSは、1秒あたりのRequest数です。
500 Request/秒 × 0.2秒 = 平均100 Threadこれは安定した状態での平均値の概算です。100本あれば十分という意味ではありません。
実際には、処理時間のばらつき、瞬間的な流入、遅いRequestの混在を考慮する必要があります。また、ここで使う時間は、入口での待ちを含むResponse Time全体ではなく、Threadを占有する時間です。
Threadを増やすと効果がある場合
DBなどの待ち時間があり、CPUやBackendに余裕がある場合は、並列度を増やすことで処理量が伸びる可能性があります。
Threadを増やすと悪化する場合
CPUがすでに飽和している場合や、DBへの同時アクセスが多すぎる場合は、競合や待ち時間が増えます。

Thread数は、CPU・Memory・Backendの余裕を確認しながら、段階的に変更して評価します。
maxConnectionsの設計
maxConnectionsは、Tomcatが受け入れて扱う接続数を制限する設定です。
接続には、Request処理中のものだけでなく、KeepAliveで次のRequestを待っているものもあります。

そのため、接続数と使用中Thread数は一致しません。NIO Connectorでは、KeepAlive中など処理が不要なConnectionをPollerが監視し、Request処理が必要になったときにWorker Threadへ渡します。maxConnectionsに達すると、新しいConnectionはすぐにはTomcatへ取り込まれず、OS側のAccept Queueで待機することがあります。この受付待ちの長さに関係するTomcatの設定がacceptCountです。
| 確認する情報 | 理由 |
|---|---|
| 前段Serverの台数 | 接続元が増えると接続総数も増え得る |
| 接続Poolの構成 | WorkerやProcessごとに接続を持つ場合がある |
| KeepAlive待機数 | 処理していない接続も枠を使う |
| 接続の作成・切断頻度 | 再接続の負担を確認する |
| OSのResource上限 | File Descriptorなどが必要になる |
HTTP/2を使う場合は、1接続で複数のRequestを並行して扱えるため、Connection数に加えてStream数や同時Request数も確認します。
接続数の上限は、同時業務処理数の上限をそのまま表すものではありません。
acceptCountとQueueの設計
Tomcatの待ち行列を考えるときは、どこで待っているのかを区別します。

acceptCountは、主にmaxConnectionsに達した際の、OS側の接続受付待ち行列の長さに関係する設定です。ただし、実際に保持できる接続数はOS側のbacklog上限などにも影響されます。
「Threadが空くまで待つHTTP Requestを何件保持するか」という設定ではありません。
受付待ち行列の上限を超えると、接続が拒否されたりTimeoutしたりする可能性があります。
参考:Tomcat HTTP Connector公式ドキュメント
一方、共有のStandardThreadExecutorには、実行待ちTask数を制限するmaxQueueSizeがあります。これはOSの接続受付待ちとは別のQueueです。
Queueを大きくしても処理能力は増えない
処理能力が500 RPSなのに、700 RPSが流入し続ける場合を考えます。
流入:700件/秒
処理:500件/秒
差分:200件/秒拒否やTimeoutがなければ、待ちが毎秒200件ずつ増えます。
Queueは短時間の負荷増加を吸収するために有効ですが、継続する過負荷は解消できません。
待てる時間から考える
仮に、あるRequest Queueの前に100件が並び、毎秒500件を安定して処理できるなら、単純化した待ち時間は約0.2秒です。
100件 ÷ 500件/秒 = 0.2秒
実際には処理時間のばらつきがあるため、これより長くなる場合もあります。
なお、この計算をacceptCountにそのまま当てはめることはできません。接続数とRequest数は異なるためです。
Queueは、許容される待ち時間と回復時間を基に設計します。
KeepAliveの設計
KeepAliveは、同じConnectionを複数のRequestで再利用する仕組みです。

接続の再利用により、接続確立の回数を減らせます。一方で、次のRequestを待つConnectionが残ります。
| 設定の方向 | 得られる効果 | 確認する影響 |
|---|---|---|
| 保持時間を長くする | 再利用しやすい | 待機接続が増える |
| 保持時間を短くする | 待機接続を減らせる | 再接続が増える |
| 再利用回数を増やす | 接続作成を減らせる | 接続が長く維持される |
前段にApacheやNginxがある場合は、利用者とWeb Server間、Web ServerとTomcat間を分けて考えます。
Client ←─ Connection A ─→ Web Server
Web Server ←─ Connection B ─→ Tomcat二つの接続は独立しています。利用者数からTomcatの接続数を直接決めず、前段の接続再利用も含めて測定しましょう。
Timeoutの設計
Timeoutは、処理が進まない状態でResourceを占有し続けることを防ぐための仕組みです。ただし、Timeoutごとに対象が異なります。
| 種類 | 主に待つもの |
|---|---|
| 接続確立Timeout | 通信先への接続 |
connectionTimeout | 接続後のRequest行の受信など |
keepAliveTimeout | 同じ接続での次のRequest |
| DB接続取得Timeout | Poolからの接続貸し出し |
| SQL実行Timeout | Queryの完了 |
| 外部APIのTimeout | 接続や読み取り、処理全体 |
| Request全体の期限 | 利用者へ応答するまでの全体時間 |
TomcatのconnectionTimeoutは、業務処理全体を指定時間で停止する設定ではありません。Request Bodyの読み取りへの適用は、Upload関連設定にも関係します。
参考:Tomcat HTTP Connector公式ドキュメント
Application全体の処理時間を設計する
たとえば、Applicationが2秒以内に処理を終える必要があるなら、次のように時間を分配して考えます。
Application全体の目標処理時間:2,000ms
DB接続取得+SQL 700ms
外部API呼び出し 800ms
その他の処理・余裕 500msこれは直列処理を単純化した例です。
SQLや外部APIを複数回呼ぶ場合、1回あたりのTimeoutを守っても、合計では全体の期限を超えることがあります。残り時間に応じて、次の処理に使える時間を制限する考え方が必要です。
Timeout後の動作も確認する
Web ServerがTimeoutしても、TomcatやDBの処理が停止するとは限りません。
そのため、Timeout値だけでなく、処理の中断、Transactionの終了、接続の返却、Retry時の重複実行まで確認します。
DB Connection Poolの設計
DB Connection Poolは、Databaseへの接続をあらかじめ保持し、Applicationから再利用する仕組みです。Requestごとに物理接続を作成・切断するのではなく、PoolからConnectionを取得し、処理後に返却します。

TomcatのThread数が200本、DB Poolが30接続の場合、すべてのThreadが同時にDB接続を取得できるわけではありません。多くのRequestがDBアクセスを必要とする場合、DB Connection Poolが実質的な同時処理数の制約になります。
一方で、Poolを大きくすれば必ず性能が上がるわけではありません。DBへの同時SQLが増えることで、CPU、I/O、Lock競合などが増え、1件あたりの処理時間が延びることがあります。
JDBC・DataSource・JNDIの関係
Tomcat上のWeb ApplicationからDatabaseへアクセスする場合、一般的にJDBCを利用します。TomcatではJNDIを利用してDataSourceをApplicationから参照する構成も取れます。

DataSourceを利用すると、Application側からDatabaseの接続先やPool設定を分離し、Tomcat側で管理できます。
DB Connection Poolの主なパラメータ
| パラメータ | 役割 | 設計時のポイント |
|---|---|---|
| maxTotal | 同時に利用できるConnection数の上限 | 小さすぎると取得待ち、大きすぎるとDB負荷増加 |
| maxIdle | Idle状態で保持するConnection数の上限 | 再利用性とDB側Resource消費のバランス |
| maxWaitMillis | Connection取得を待つ最大時間 | Application全体のTimeoutとの整合が必要 |

Poolが上限に達するとThreadが待つ
maxTotalまでConnectionが使用されている状態では、新しいRequestは空きConnectionが返却されるまで待機します。同期Servletでは、この待ち時間もWorker Threadを占有します。

このため、TomcatのmaxThreadsとDB PoolのmaxTotalは別々に決めるのではなく、ApplicationのDB利用率とDatabase側の処理能力を含めて設計します。
maxWaitMillisはTimeout設計の一部として考える
maxWaitMillisを長くすると、一時的にPoolが上限へ達してもConnectionの返却を待てます。一方、長すぎるとWorker Threadが長時間滞留します。短すぎれば、一時的な負荷増加でもConnection取得に失敗しやすくなります。
そのため、DB Connectionの取得待ちだけで許容時間を使い切らないよう、Web Server、Tomcat、DB、外部APIを含めたApplication全体の目標処理時間やTimeoutと整合させます。
Connectionは確実に返却する
ApplicationがConnectionを取得したまま返却しない状態が続くと、利用可能なConnectionが減少し、最終的にPool枯渇につながります。Javaではtry-with-resourcesなどを利用し、処理終了時にConnectionを確実にclose()します。
Connection Pool利用時のclose()は、通常、物理的なDB接続を毎回切断するのではなく、ConnectionをPoolへ返却して再利用可能な状態にします。
全Nodeの合計で考える
Tomcat 4台 × DB Pool 30接続
= 最大120接続DatabaseにはBatch、運用接続、別Applicationなども接続します。Auto ScalingやRolling DeployでNodeが一時的に増える場合も含め、Database全体で許容する接続数を設計します。
Apache / Nginxとの処理能力の整合
前段のWeb Serverが大量の接続を扱えても、Tomcatが同じ数のRequestを同時に処理できるとは限りません。

ここでは、毎秒のRequest数と同時Request数を分けて考えます。
たとえば、500 RPSでも、平均処理時間が50msなら平均同時処理数は約25件です。500msなら約250件になります。
RPSが同じでも、Backendが遅くなると必要な同時処理数は増えます。
| 項目 | 確認内容 |
|---|---|
| 転送先の接続数 | Tomcatの接続枠を圧迫しないか |
| 同時Request数 | TomcatとDBが安定して処理できるか |
| Timeout | Application全体の目標処理時間と合うか |
| Retry | 遅延や障害を増幅しないか |
| 負荷分散 | 一部Nodeに処理が偏らないか |
| 待ち行列 | 複数の層で長く待たせていないか |
設定によっては、接続PoolがWorkerやProcess単位で存在します。個々の設定値だけでなく、全体として何接続・何Requestになるかを確認します。
CPUの性能設計
Thread数を増やしても、CPUの計算能力は増えません。CPUを設計する際は、Requestの経過時間とCPU時間を区別します。
Requestの経過時間:100ms
CPU処理 10ms
DB待ち 70ms
外部API待ち 20msこのRequestは100msかかっていますが、CPUを使用しているのは10msです。
仮に1RequestあたりのCPU時間が10msで、500 RPSを処理するなら、Application処理だけで必要なCPU量は次のようになります。
500 Request/秒 × 0.01 CPU秒/Request
= 毎秒5 CPU秒概算では、5 Coreを常時使用する量に相当します。実際には周辺処理や負荷変動に備える余裕も必要です。
CPU負荷が高い場合
計算量、変換処理、圧縮、暗号化などを調べます。CPUが飽和した状態でThreadを増やすと、実行待ちやContext Switchが増える可能性があります。
CPU負荷が低いのに遅い場合
DB、外部API、Lock、接続Poolなどの待ちを調べます。
Container環境では、Hostに余裕があってもCPU制限によるThrottlingが発生する場合があります。CPU使用率と制限値を合わせて確認しましょう。
Memoryの性能設計
TomcatはJava Processとして動作します。本章では、そのProcessが必要とするMemoryを、処理量との関係で考えます。

同時処理数が増えると、処理途中のデータも増えます。
たとえば、1Requestにつき平均500KiBのデータを処理中に保持するなら、同時200件で約100MiB、同時1,000件で約500MiBに相当します。これはRequest関連データだけの概算であり、Process全体の必要量ではありません。
| 処理 | 確認する点 |
|---|---|
| 大量検索 | 検索結果を一括保持していないか |
| File Upload | 同時Upload時のMemoryや一時File |
| 大きなResponse | Bufferや変換中データの量 |
| Session | 件数と1Sessionあたりの保持量 |
| Queue | 待ちTaskや関連データの保持量 |
負荷を下げたあと、Memory使用量がどのように推移するかも観測します。ただし、OS上の使用量が直ちに下がらないことだけでMemory Leakとは判断できません。
過負荷時のTomcat
過負荷は、Requestの増加だけでなく、処理時間の増加によっても発生します。

Tomcat内部では、後段の処理が遅くなると、その影響が前段へ波及します。たとえばWorker Threadが使い切られるとRequestをすぐに処理できなくなり、Connectionの滞留が増えます。さらにmaxConnectionsに達すると、新しい接続はOS側のAccept Queueで待つようになります。

通常時:500 × 0.1 = 50
遅延時:500 × 0.5 = 250流入量が変わらなくても、必要な同時処理数は5倍になります。
ただし、すべての過負荷がこの順番で発生するわけではありません。Connection上限、CPU、DB Poolなどが先に制約になる場合もあります。
過負荷時に必要な設計
重要なのは、無制限に受け入れ続けないことです。
待ち時間に上限を設け、Backendへの同時アクセスを抑え、必要に応じて入口で流量制限や明示的な拒否を行います。
Tomcatの接続受付上限に達しただけでは、必ず分かりやすいHTTPエラーを返せるわけではありません。過負荷時の応答を制御したい場合は、前段やApplicationの仕組みも含めて設計します。
負荷が下がったあとに待ちが解消し、通常状態へ戻れるかまで確認しましょう。
障害・縮退時の性能設計
Nodeが停止すると、残ったNodeへ負荷が集中します。

均等分散を仮定すると、1台停止時の負荷倍率は次の式で表せます。
Node数 ÷(Node数 − 1)| 通常時のNode数 | 1台停止後の1台あたりの負荷 |
|---|---|
| 2台 | 2倍 |
| 3台 | 1.5倍 |
| 4台 | 約1.33倍 |
ただし、実際にはSessionの偏り、Retry、Cache Miss、接続の張り直しも発生します。
縮退時には、Thread数だけでなく、残存NodeのDB Pool容量やMemoryの余裕も確認します。
また、復旧Nodeへ一度に大量のRequestを流すと、初期化やCacheの準備が追いつかない場合があります。負荷分散への復帰方法も試験対象です。
通常時の合格条件とは別に、障害時に維持するResponse TimeとError率を決めておきましょう。
Tomcatの性能試験
性能試験の目的は、最大RPSを記録することだけではありません。目標のResponse TimeとError率を維持できる処理範囲を確認することが重要です。
合格条件を決める
説明用の条件として、次のように設定できます。
| 状態 | 合格条件の例 |
|---|---|
| 通常負荷 | 800 RPS、p95が300ms以下 |
| ピーク負荷 | 1,200 RPS、p99が1秒以下 |
| Error率 | 0.1%未満 |
| 1台停止 | 必要な流入量で縮退時の目標を維持 |
| 負荷減少後 | 待ちが解消して通常状態に復帰 |
p95は95%のRequestがその時間以内に完了する値、p99は99%がその時間以内に完了する値です。
試験を分ける
| 試験 | 確認すること |
|---|---|
| 低負荷試験 | 基本的な処理時間 |
| 段階的な負荷増加 | 性能が悪化し始める境界 |
| ピーク負荷試験 | 想定最大負荷への対応 |
| 突発負荷試験 | Queueの増加と回復 |
| 長時間試験 | Resourceの増加傾向 |
| Backend遅延試験 | DBや外部APIが遅い場合の動作 |
| Node停止試験 | 残存Nodeの処理能力 |
実際の利用に近い条件を作る
参照と更新の割合、Requestサイズ、データ量、認証、Session、KeepAliveを、本番の利用に近づけます。
また、応答が遅くなると送信量も減る負荷方式では、過負荷を過小評価する場合があります。一定RPSを流す試験と、一定の同時利用者数で実行する試験を、目的に応じて使い分けます。
変更する設定は絞り、結果を比較できる形で記録しましょう。
Tomcatの性能設計を確認する
設計値が妥当かどうかは、実行時の状態を観測して確認します。
JMXで状態を把握する
JMXでは、Tomcatが公開する管理情報を取得できます。代表的な確認対象は、Thread PoolやRequest処理の統計です。
| 観測対象 | 主な確認内容 |
|---|---|
| Thread数 | 現在数と上限 |
| 使用中Thread数 | 上限に張り付いていないか |
| Request統計 | 処理件数、Error、処理時間 |
| Connection数 | 接続枠に余裕があるか |
| Executor | 実行中TaskやQueueの状態 |
取得できる属性やMBean名は、ConnectorやExecutorの構成によって異なります。
また、Queueは一つではありません。OSの受付待ち、Executorの待ち、DB Poolの待ちを、それぞれの観測手段で確認します。
JMXを有効にする方法は以下で紹介していますので、合わせて参照ください。
TomcatでJMXを有効化する方法|SSL・認証・jConsole・JMXTermまで解説
Access LogでRequest単位の傾向を見る
Access Logでは、URI、Status、処理時間などを記録します。
Tomcat 10.1のAccessLogValveでは、%Dで処理時間をミリ秒単位で記録できます。
<Valve
className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="access"
suffix=".log"
pattern="%t %a "%r" %s %b %D"
/>この例では、時刻、接続元、Request、Status、Responseサイズ、処理時間を記録します。
参考:Tomcat Access Log Valve公式ドキュメント
TomcatのLog時間と利用者が観測するResponse Timeは、測定範囲が異なります。前段の待ちや通信時間を含めて調べるには、Web ServerのLogや負荷試験結果と時刻を合わせます。
Thread状態から待ちの原因を探す
Thread Dumpでは、Threadが実行している処理や、待っている場所を確認します。
同じDB接続取得処理にThreadが集中していれば、Poolの待ちを疑います。同じ外部API呼び出しに集中していれば、接続先の遅延を調べます。
Threadの状態名だけで判断せず、Stack Traceの内容を読みます。RUNNABLEでも、必ずCPUを使い続けているとは限りません。
複数の指標を組み合わせる
| 観測した状態 | 主な調査先 |
|---|---|
| 使用中Threadが多く、CPUも高い | CPU処理量、実行待ち |
| 使用中Threadが多く、CPUは低い | DB、外部API、Lock待ち |
| DB Poolの取得待ちが増える | 接続保持時間、SQL、Pool設計 |
| 接続数が多く、Threadは空いている | KeepAlive、低速通信、接続元 |
| 負荷増加中に待ちだけが増える | 処理能力と受付量の不一致 |
これらは原因を絞るための手がかりです。一つの指標だけで断定せず、同じ時間帯の情報を重ねて確認します。
まとめ
Tomcatのパフォーマンス設計は、Connection、Thread、Queue、Timeoutを、前後の処理能力と整合させる設計です。

各段階の待ち時間を制限し、処理できる量を超えたときの動作まで決めておくことが重要です。
| 設計項目 | 確認するポイント |
|---|---|
| Connector | 通信方式とApplicationの処理方式を区別する |
| Thread Pool | Thread占有時間とCPU・Backend能力に合わせる |
| Connection | KeepAliveを含む接続総数を見積もる |
| Queue | 待ち場所と許容時間を明確にする |
| Timeout | 対象となる待ちと、Timeout後の動作を決める |
| DB Pool | 全Node合計の接続数とDB能力を合わせる |
| CPU / Memory | 同時処理数の増加に伴う使用量を確認する |
| 障害時 | 残存Nodeで必要な性能を維持できるか検証する |
| 性能試験 | 応答時間、Error、Resource、回復を測定する |
maxThreadsを増やす前にThreadが何を待っているのかを調べ、Queueを増やす前に利用者が待てる時間を確認する。こうした検証が、設定値の根拠になります。


コメント