Artifactoryのパフォーマンスチューニング方法
Artifactoryの使用量が増えると使用できるリソースが徐々に減るため、パフォーマンスの低下につながります。使用量が増えた際には、システムの状況と履歴情報を監視することがより重要になります。Artifactoryを最適化し、安定性を確保するには使用パターンの監視が欠かせない重要な最初のステップです。ここでは、Artifactoryと周囲の環境監視と調整のためのガイドラインとヒントをいくつか紹介します。まず、Apache Tomcat、HTTPコネクション、データベース、Java仮想マシン(JVM)およびストレージなど監視や調整が必要になる重要なリソースについて説明します。
Apache Tomcat
Artifactoryは、Apache HTTPクライアントを使用するTomcat上で動作します。Tomcatはスレッドプールから割り当てリクエストを処理します。スレッドプールが使い果たされると、Tomcatは追加リクエストを処理するため、さらにmaxThreads属性で指定された最大数まで作成します。リクエスト数がmaxThreads値を超えると、リクエストはacceptCount属性で指定された最大数までキューに入ります。このパラメータが大きすぎると、スレッドが空くのを待機しているリクエストは処理できるようになるまで処理待ちとなり、遅延が発生することになります。さらにacceptCount制限にも達すると、Tomcatは必要なリソースが最終的に解放されるまで、追加リクエストに対して接続拒否エラーを返します。その結果、スレッドを取得できなかった新しいリクエスト、アップロード、ダウンロード、更新などは失敗します。このようなパフォーマンスの低下やエラーを回避するため、Tomcatのserver.xmlファイルで属性の値を増やすことができます。maxThreadsのデフォルト値は200で、acceptCountは100に設定されています。以下のサンプルのserver.xmlファイルでは、これらの値が増えていることに注目してください。
<Connector port="8081" acceptCount="200" compression="off" connectionLinger="-1" connectionTimeout="60000" maxThreads="600" acceptorThreadCount="2" enableLookups="false"/>
モニタリング
Netstat: 監視ツールが設定されていない場合は、下記のnetstatコマンド(TOMCAT_PORT変数はArtifactoryのTomcatポートに置き換えてください)を実行することで、HTTPコネクションの使用状況を簡単に監視できます。
while sleep 5; do printf "$(date) HTTP Connections: $(netstat -latuen | grep TOMCAT_PORT | wc -l)"; echo; done
カウントしたいステートを指定することもできます。たとえば、次のコマンドを実行してESTABLISHEDステートをカウントすることができます(TOMCAT_PORT変数はをArtifactoryのTomcatポートに置き換えてください)。
while sleep 5; do printf "$(date) HTTP Connections : $(netstat -latuen | grep TOMCAT_PORT | grep ESTABLISHED | wc -l)"; echo; done
HTTPコネクション用のMBean: バージョン4.12以降、ArtifactoryはHTTPコネクション用のMBeanを公開して使用状況を追跡できるようにしました。このMBeanは以下の各リポジトリにあります。
org.jfrog.artifactory > Artifactory | HTTPConnectionPool > [Repo Name]: Attributes
詳細については、ArtifactoryとMBeanのインテグレーションに関するブログの投稿を参照ください。
サードパーティ製ツール: サードパーティ製ツールを使って、HTTPコネクション等のさまざまなリソースを監視できます。 JFrogのKnowledge Base には、JConsole、JavaMelody、Nagiosなどの説明があります。Artifactory Dockerコンテナ用にも、HTTPコネクションやJVMの使用状況等を監視するオープンソースのツールがあります。
下のグラフはLogicMonitorというツールで生成されたものです。この例では、Tomcatで使用可能なスレッドの最大数に達したため、Tomcatのserver.xmlファイルでmaxThreads属性を増やす必要があることを示しています。
Artifactory用のHTTPコネクション
リポジトリごとに許可されるHTTPコネクション数はデフォルトで50に設定されています。使用されるコネクション数が常にこの値に近い場合は、以下のパラメーターを使用して増加できます。
$ARTIFACTORY_HOME/etc/artifactory.system.properties
artifactory.http.client.max.total.connections = {value}
S3を使用している場合のHTTPコネクション
ファイルストアの管理にS3 Object Storeを使用している場合、ArtifactoryのS3バイナリプロバイダはJets3tライブラリを使用してデフォルトで許可される最大同時コネクション数を100に設定しています。S3オブジェクトストアへのコネクションが集中した場合、JetS3tコネクションプールからの接続を待っている間にリクエストがフリーズする可能性があります。これを回避するには、$ARTIFACTORY_HOME/etc/binarystore.xmlファイルにS3バイナリプロバイダーのhttpclient.max-connectionsプロパティを追加してください。以下のコードスニペットは、設定方法を示すArtifactoryユーザガイドからのサンプルCleversafeテンプレート です。
<config version="v1"> <chain template="s3"/> <provider id="s3" type="s3"> <identity>XXXXXXXXX</identity> <credential>XXXXXXXX</credential> <endpoint>[My CleverSafe Server]</endpoint> <bucketName>[My CleverSafe Bucket]</bucketName> <property name="httpclient.max-connections" value="300"/> <httpsOnly>false</httpsOnly> <property name="s3service.disable-dns-buckets" value="true"></property> </provider> </config>
Tomcatのチューニングについて詳細を知りたい場合は、Netflixのブログ「Tuning Tomcat For A High Throughput, Fail Fast System」が参考となります。
リバースプロキシのHTTPコネクション
Artifactoryの前でリバースプロキシを使用している場合、HTTPコネクションの数が最大値に達してArtifactoryに到達できないことがあります。このような場合は、より多くのコネクションをリバースプロキシに割り当ててください。詳細な手順はリバースプロキシサーバーのマニュアルを参照してください。NGINXのパフォーマンスチューニングや Apacheのパフォーマンスチューニング を参照できます。 同様にApache ドキュメントのApache HTTPDリバースプロキシも参照してください。
データベース
データベース接続数は、Artifactoryを最適化するときに監視すべきもう1つの重要なリソースです。管理者は、利用可能なデータベース接続数に余裕があることを確認してください。そうしないと、空き接続を待っているリクエストがフリーズする可能性があります。利用可能なデータベース接続数は、現在の使用状況に基づいて調整する必要がありますが、この値はデータベースに設定した最大接続数を超えないようにしてください。
モニタリング
ArtifactoryはDB接続用のMBeanも公開していますので、JMX準拠のツールを使用して監視できます。JConsoleを使用している場合は、このMBeanはorg.jfrog.artifactory > Artifactory > Storage: Data Sourceにあります。他にもデータベース接続を監視できる多くのツールがあります。たとえば以下のグラフは、RDSデータベースのAWSモニタリングツール によって記録されたデータベース使用率が急上昇している状況を示しています。
ここでNetstatを使ってアクティブなDB接続を監視することもできます(DB_PORT変数をArtifactoryデータベースのポート番号に置き換えてください)。
while sleep 5; do printf "$(date) DB Connections: $(netstat -latuen | grep DB_PORT | wc -l)"; echo; done
カウントしたいステートを指定することもできます。たとえば、次のコマンドを実行してLISTENステートをカウントすることができます(DB_PORT変数はArtifactoryデータベースのポート番号に置き換えてください)。
while sleep 5; do printf "$(date) DB Connections: $(netstat -latuen | grep DB_PORT | grep LISTEN| wc -l)"; echo; done
データベース接続が常に最大値に近い場合は増やす必要があります。アクティブなデータベース接続数が最大値に達しているのに、さらにデータベース接続が要求されると、Artifactoryサーバーログ($ARTIFACTORY_HOME/logs/artifactory.log)から次の例外が発生します。
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is org.apache.tomcat.jdbc.pool.PoolExhaustedException: [art-exec-672866] Timeout: Pool empty. Unable to fetch a connection in 120 seconds, none available[size:100; busy:100; idle:0; lastwait:120000].
また、アイドルキュー(次のセクションで説明されているpool.max.idle)に配置されるのを待機するデータベース接続数が増加するため、パフォーマンスが低下することもあります。スレッドダンプを実行して、
org.apache.tomcat.jdbc.pool.ConnectionPool.returnConnectionにパークされているスレッドの数を確認してください。
チューニング
Artifactoryの場合: Artifactoryのデータベース接続は、$ARTIFACTORY_HOME/etc/db.propertiesファイルにある以下のパラメーターを設定してください。
- pool.max.active: 同時に接続可能な最大データベース接続数(デフォルトは100)
- pool.max.idle: Artifactoryが保持するアイドル状態の最大データベース接続数(デフォルトは10)
データベースの場合: 使用しているデータベースの資料を参照して、データベース自体の接続数を増やしてください。データベースのパフォーマンスに関しては、データベース接続の監視と変更だけでなく他にも設定があります。例えば MySQLのマニュアル にはmy.cnfファイルを最適に設定してパフォーマンスチューニングが可能であることが記載されています。PostgreSQLの場合、PostgreSQLのwikiでmax_connectionsの値を増やす方法についての詳細を参照できます。
JVMメモリ
Artifactoryを最適化するときはメモリも考慮する必要があります。Artifactoryに割り当てられたメモリが少ないと動作が遅くなったり、応答が遅くなったり、最悪の場合はArtifactoryがまったく応答しなくなるなど問題が発生します。ArtifactoryのJVM設定を変更して最適化を行ってください。
モニタリング
JVM使用量の履歴データを監視するときは、初期ヒープサイズ(Xms)を最大ヒープサイズ(Xmx)より小さくすることが重要です。そうしないと、グラフで使用パターンを確認するのが難しくなります。
前節で説明したツール(JConsole、JVisualVM、Javamelodyなど)でもJVMの使用状況を監視できます。
チューニング
ユーザー数やレポートサイズはメモリ使用量とパフォーマンスに直接影響します。Artifactoryを最適化する際には、Artifactoryユーザーガイドにある推奨ハードウェア のガイドラインを参照してください。JVMのメモリ割り当てを変更するためにJVMパラメータを設定する場合には、Linux、Solaris、MacまたはWindowsにそれぞれ対応する指示に従ってください。
ストレージ
ストレージ不足はパフォーマンスと安定性に影響を与えるため、監視が不可欠なリソースです。
モニタリング
ディスクI/O率: ディスクI/O率が遅いと著しいパフォーマンス低下を引き起こす場合がありますが、さまざまなツールで監視できます。以下の例では、iostatを使用してI/O率を監視しています。Artifactoryインスタンスのインストールや設定を行う前にこのテストを実行してください。デバイス情報ページのみ表示する場合には-dフラグを追加し、詳細情報(個別の読み取り/書き込み)も表示する場合には-xを追加します。連続出力の場合は1を加算します。出力サンプルは以下の通りです。
$ iostat -dx 1 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util xvdb 0.00 0.00 649.00 0.00 55808.00 0.00 171.98 8.13 12.44 12.44 0.00 1.54 100.00
ディスク容量: Artifactoryはストレージ監視用のMBeanを公開しました。org.jfrog.artifactory> Artifactory> Storageで確認できます。エンタープライズ版の場合は、JFrog Mission Controlにある中央のダッシュボードからすべてのグローバルArtifactoryインスタンスのストレージを1か所で監視できます。Mission Controlを使用してストレージの使用量を追跡する方法については、こちらのブログ記事で詳しく説明してあります。
チューニング
S3、NFSなど既存のファイルストアが遅く、より高速で小さいローカルファイルストア(SSDなど)がある場合は、Artifactoryのcache-fsコマンドを使います。Cachefsはファイルシステムのように機能しますが、アップロードおよびダウンロードリクエスト用のバイナリLRU(Least Recently Used)キャッシュも持っています。Cachefsを有効にすると、高いIOPS(I/O操作)やNFSアクセスが遅いインスタンスのパフォーマンスが大幅に向上します。詳細は、ArtifactoryユーザガイドのCached Filesystem Binary Providerを参照してください。
ディスクの空き容量が不足している場合は、現在のファイルストアを新しいストレージに移動できます。非常にスケーラブルなクラウドストレージプロバイダー (S3、GCSまたはAzure) を使用してください。また、ArtifactoryのFilestore Sharding機能を使用してストレージを追加することもできます。この場合、安定した信頼性の高いスケーラブルなファイルストアを実現するため冗長化の有無をセットアップ時に選択できます。Artifactoryのディスクスペース使用方法に関してはユーザーガイドをご覧ください。
利用される環境に依存するケースが多いため、Artifactoryの最適化は一度でうまくいくとは限りません。設定をモニタリングすることにより、Artifactoryインスタンスが最適なパフォーマンスを出すようにシステムと設定をお使いの環境や方法に合わせ適切に調整していくことが可能です。また、チューニングの参考になるようストレステストを実行してください。同時アップロードとダウンロードのロードテストには、Artifactory Query Language (AQL)やJFrog CLIを使用します。マルチスレッドのアップロードとダウンロードをテストするには、CLIの- threadオプションを使用してください。