SlideShare a Scribd company logo
Javaアプリケーションサーバ
構築・運用の勘所
Takahiro YAMADA
@yamadamn
2013/11/9
自己紹介
• 某SIer勤務
• Javaをベースとしたミドルウェア製品の構築・サポート
• Oracle ACE (Middleware & SOA)
• ミドルウェア分野では日本で実質的に一人
おことわり
• 発表する内容は個人の見解であり、所属する組織の公式な見解
ではありません。
• 基本的にアプリケーションサーバの種類によらない内容ですが
一部製品でしか利用できないこともあります。
• HotSpot JVMやLinuxをベースとして説明しますが、他のJVM
やプラットフォームにも応用できる内容です。
アプリケーションサーバの特性
• 長時間の実行
• 複数ユーザからの同時アクセス
• アプリとインフラの中間
アジェンダ
• ログ管理
• 監視・統計
• チューニング
ログ管理
• トラブルシューティングの基本
• ログをきちんと取得していないシステムは、
スピードメーターが壊れている車と同じ
GCログ
オプション 説明
-verbose:gc GC情報を出力(基本)
-Xloggc:<file> GC情報を指定されたファイルに出力
-XX:+PrintGCDateStamps
タイムスタンプ(日時)を出力
6u3までは -XX:+PrintGCTimeStamps(起動時からの
経過時間)のみ
-XX:+PrintGCDetails GCの詳細情報を出力
-XX:+UseGCLogFileRotation
GCログのローテーションを有効化 (7u2, 6u34以降)
-XX:NumberOfGCLogFiles=n
-XX:GCLogFileSize=size も指定
GCチューニング、メモリリークやOutOfMemoryError分析に必要
GCログの表示例(GCViewer)
GCログ運用時の注意点
• GCログの上書きに注意
• 再起動前に退避
• -Xloggc:gc-`date +%Y%m%d%H%M%S`.log
• OSコマンドでの強制ローテーションは大抵正常動作しない
• 例: Linuxのlogrotateによるcopytruncate
• ファイルポジションが戻らず、先頭がNUL文字になるだけ
GC統計
• jstat
• 統計情報として取得するには役に立つ
• GCフェーズや詳細なタイミングが不明
• 障害解析にはあまり役に立たない
Timestamp S0 S1 E O P YGC YGCT FGC FGCT GCT
8.2 0.00 99.87 64.05 15.29 99.22 3 0.112 0 0.000 0.112
18.2 33.62 0.00 1.08 55.63 99.31 14 0.623 0 0.000 0.623
28.2 0.00 0.00 3.75 46.79 49.93 15 0.660 1 0.991 1.651
38.2 0.00 0.00 4.26 46.79 49.93 15 0.660 1 0.991 1.651
48.2 0.00 0.00 3.08 23.83 44.40 16 0.678 2 1.372 2.050
例: jstat -gcutil -t <PID> 10s
ヒープの詳細な解析
• ヒープダンプは最低2回取得して、差分を解析
• 通常時
• jmap -dump:format=b,file=heap.bin <PID>
• jcmd <PID> GC.heap_dump heap.bin (7u4~)
• OutOfMemoryError(OOME)発生時
• -XX:+HeapDumpOnOutOfMemoryError
• OOME発生後はJVMとしての動作が保証されないので、
必ず再起動
標準出力・エラー出力ログ
• スレッドダンプやOOMEなど、JVMとしての出力を捉えるため
にあったほうがよい
• スレッドダンプ(kill -3 <PID>)は以下で代用も可能
• jstack <PID>
• jcmd <PID> Thread.print (7u4~)
• 環境によっては以下オプションを利用
-XX:+UnlockDiagnosticVMOptions -XX:+LogVMOutput -XX:LogFile=<file>
• System.out.println, System.err.println ダメ。ゼッタイ。
スレッドダンプの解析例(ThreadLogic)
標準出力・エラー出力ログのローテーション
• Apache付属のrotatelogsなどを利用
• java ∼ 2>&1 | rotatelogs -l console.log.%Y%m%d 86400
• ログの削除も別途検討
• GCログがローテーションできないJVMを利用している場合、
標準出力・エラー出力ログに出力するのもあり
• java ∼ >/dev/null 2>&1 ダメ。ゼッタイ。
アクセスログ
• 主にHTTP経由のアクセスを出力
• デフォルトで無効になっている製品もあるが有効化すべき
• Webサーバ・アプリケーションサーバどちら側の問題か判別
• レスポンス時間も取得
• セキュリティ・監査目的でも利用
サーバログ
• 製品固有のログ
• ログレベルは通常INFO以上にすべき
• 監視にも利用
• 製品としての障害解析には最も利用する
• 起動時からのログが必要なケースが多い
監視・統計
• 監視
• トラブルを未然に防ぐ
• トラブルを早期に見つける
• 統計
• 傾向分析
• サイジングの礎
OS関連
• CPU
• 使用率、キュー長
• メモリ
• 使用量、ページング
• ネットワーク
• ソケット状況、I/O発生量
• プロセス
• 上記をプロセス単位に、サーバ名を識別可能に
vmstatの実行例
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free inact active si so bi bo in cs us sy id wa st
1 0 0 5772388 548932 888980 0 0 0 48 17 17 4 1 94 0 0
0 0 0 5770884 548932 890680 0 0 0 0 45 41 1 0 99 0 0
3 0 0 5732472 548964 928772 0 0 0 4 848 563 56 11 34 0 0
0 0 0 5770768 548928 890304 0 0 0 88 418 226 38 5 57 1 0
0 0 0 5770908 548928 890304 0 0 0 0 18 27 0 0 100 0 0
CPU割当やI/O待ちとなっているプロセス
スワップイン・スワップアウトしているメモリ量
CPU使用率
Linuxでは、“top -H”や “ps auxwww -L”コマンドを利用して、
スレッドごとのCPU使用率を取得するのも便利
ログ監視・統計
• ログ
• ERRORレベル以上を基本は監視
• サーバログではなく、標準出力・エラー出力ログを監視する
のもあり
• GCログやアクセスログから統計
• GC回数、平均所要時間など
• ステータスごとの件数、平均レスポンス時間など
死活監視、リソース監視・統計
• 死活監視
• 実際にリクエストを投げて応答を確認
• Full GCを考慮してタイムアウトやリトライを実装
• JMXによるリソース監視・統計
• ヒープ使用量、GC回数
• 実行中のスレッド数、リクエストキュー長
• コネクションプールの使用数、空き待ち数
Java Mission Control (7u40~) の例
チューニング
• 限られたリソースで最大限の効果を発揮させる
• 計測し、ボトルネックを見つける
• パフォーマンスだけではなく、
適正な値に近づける
よくある3層構造
Webサーバ
アプリケーション
アプリケーション
サーバ
JVM
OS
H/W
DBサーバ
サーバ分割・分散配置
• 複数プロセス・OSによって処理
• スレッド間のロック競合、アプリケーション間の影響低減
• パッチ適用・設定変更など再起動が必要なとき
• 計画的に再起動することで、リーク解消にもなる
アプリケーション
アプリケーション
サーバ
JVM
OS
H/W
アプリケーション
アプリケーション
サーバ
JVM
OS
H/W
アプリケーション
アプリケーション
サーバ
JVM
アプリケーション
アプリケーション
サーバ
JVM
OS
OS環境設定
• 最低限行うべきもの(Unix)
• ファイルディスクリプタ(FD)
• ulimit -n 8192
• 大量のjar読込、ソケット、ファイル
• コアファイルサイズ
• ulimit -c unlimited
• 出力場所にも注意、コマンドを利用して解析
ネットワーク関連設定
• TCP
• 接続開始: connectのタイムアウト
• 接続中: KeepAlive
• 接続終了: TIME_WAITのタイムアウト
• 接続バックログ
• IPv4を優先
• -Djava.net.preferIPv4Stack=true
JVMメモリの使われ方
アプリケーションサーバでの利用イメージ
New Old Permanent + Native
アプリケー
ションサーバ
本体で利用
アプリケー
ションで固
定的に利用
HttpSession
として利用
リクエスト
で利用
アプリケーション
サーバ本体
アプリケーション
実際には計測してみないと分からないが
イメージを持つのは大事
JVMメモリ・GCのチューニング
• ヒープサイズ
• 最小容量(-Xms)=最大容量(-Xmx)
• 大きい場合、GC回数は減少・GC時間は増加
• 小さい場合、GC回数は増加・GC時間は減少
• GC方式
• レスポンス重視(-XX:+UseConcMarkSweepGC)
• スループット重視(-XX:+UseParallelOldGC)
ヒープレイアウトとして、1世代・2世代を選ぶケースもあり
アプリケーションサーバのよくある構造
スレッドプール
接続プール
リクエストキュー
リクエスト
実行スレッド
DB接続
スレッドのチューニング
• スレッドプールによって再利用するのが一般的
• スレッド数は、TPS×レスポンス時間(秒)を目安
• リクエストキュー長も制限
例: 1秒に5トランザクション、レスポンス時間は2秒
0 1 2 3 5秒
4
[参考] スレッド利用時の注意点
• ThreadLocalは注意して利用
• 再デプロイ時にメモリリークの原因になる
• 再利用前提のスレッドに紐づくため、アプリで明示的に破棄
• スレッドの自前での作成は原則行わない
• Java EEではスレッドに紐づけて、リソースが管理される
• Java EE 7では、Concurrency Utilities for EE
• 新規コネクションを張る際のオーバーヘッドを減らす
• 基本は、初期容量=最大容量、スレッド数≧容量
• ステートメントキャッシュも利用
• ファイアウォールがある場合、
定期的にポーリング
• コネクションリークに注意
• アプリケーションサーバ機能
によって確認
接続プール
コネクションプールのチューニング
DB
タイムアウトのチューニング
• Javaの特性上、実行タイムアウトを直接的に指定できない
• 以下のような部分で間接的にタイムアウトを指定
• JDBCでのSQL実行
• 外部HTTPアクセス (HttpClient)
• トランザクションタイムアウト
etc.
まとめ
• 古いバージョンを利用している方は、アプリケーションサーバ
だけでもバージョンアップを
• Java SE・Java EEとも互換性を重視
• パフォーマンスの向上、より便利なツールの利用
• アプリケーションサーバの特性を知る
• 長時間の実行 → ログ管理、監視・統計
• 複数ユーザからの同時アクセス → チューニング
• アプリとインフラの中間 → 総合力が大事
参考書籍
• Oracle WebLogic Server 11g構築・運用ガイド
• JBoss EAP6 構築・運用パーフェクトガイド
• WebSphere Application Server 構築・運用バイブル
• Tomcatハンドブック 第2版
• 絵で見てわかるITインフラの仕組み
• Webアプリケーション・サーバー 設計・構築ノウハウ
ご清聴いただき、ありがとうございました
Takahiro YAMADA
@yamadamn
2013/11/9

More Related Content

Javaアプリケーションサーバ 構築・運用の勘所