ColdFusion MX: リクエストタイムアウトおよび threadWaitTimeout 設定の解説
このテクニカルノートでは、リクエストタイムアウトと threadWaitTimeout 設定とは何か、またそれぞれがどのように機能するのかについて解説しています。
リクエストタイムアウト設定
リクエストタイムアウト設定とは何か?
リクエストタイムアウト設定はColdFusion Administrator の サーバーの設定セクションに配置されています。「リクエストタイムアウト」の隣のチェックボックスが設定に当たります。リクエストタイムアウトの設定は、そこで設定された時間(秒)より処理に時間のかかる実行中のリクエストをタイムアウトするためのものです。デフォルトの設定では、無効にされており、30秒となっています。

推奨
Macromedia では、このリクエストタイムアウトは常に有効にし、30秒に設定しておくことを推奨しています。こうすることにより、妥当であり処理に時間にかかる数個のファイルのために、サーバー全体のパフォーマンスを犠牲にすることがないからです。ColdFusion Administrator で適度なタイムアウト時間を設定し、どうしても処理に時間がかかってしまうページについては、ページ内のコードによってその設定を無効にすることができます。ColdFusion Administrator タイムアウト設定を無効にするには、 cfsetting タグで requestTimeout 属性を使用するか、 cfquery または cfhttp タグを含むページの場合は、それらのタグ内で timeout 属性を使用します。データベースクエリの場合、使用するデータベースがタイムアウトパラメータをサポートしている場合に限り、cfquery タイムアウトが機能します。データベースのドキュメントで、このタイムアウト機能がサポートされているか確認してください。
例:
<!--- ColdFusion Administrator の設定を無効にするには、
このコードはページのトップに挿入します。 -->
<cfsetting requestTimeOut = "120">
ColdFusion 5 から ColdFusion MX へ移行する際の注意事項:
URL で RequestTimeout パラメータを渡す方法は、ColdFusion MX では使用できなくなりました。この方法を適用するには、cfsetting を併用する必要があります。例: <cfsetting requestTimeout = #URL.RequestTimeout#>
例外となるタグ:
ColdFusion Administrator または CFM ページでタイムアウトを設定していても、そのタイムアウト設定が適用されないタグがあります。これらのタグには、cfstoredproc、cfcontent、cfftp、cfexecute および cfobject タグが挙げられます。また、CFX タグについても ColdFusion タイムアウト設定が適用されません。ColdFusion はリクエストタイムアウトの値を確認する前に、これらのタグが実行完了するのを待たなければなりません。そのため、ColdFusion がデータベースまたは cfobject が呼び出すオブジェクトからのレスポンスを受け取らない場合、ハングスレッドが発生し、それを解消するためにColdFusion サービスを再起動する必要が生じます。
例えば:
cfobject がオブジェクトを呼び出す場合、ページの処理には時間がかかります。ColdFusion がレスポンスを受け取り、プロセスが完了すると、初めてタイムアウトが発生するからです。そうでない場合はスレッドはハングしてしまいます。しかし、ページの処理に時間がかかる原因が cfloop である場合、30秒(または ColdFusion Administrator で指定されている値)でタイムアウトエラーが発生し、ページの処理は停止します。
threadWaitTimeout 設定
threadWaitTimeout 設定とは?
threadWaitTimeout 設定は jrun.xml の ProxyService セクション (以下の例を参照)にあります。jrun.xml ファイルは、サーバー構成のインストールの場合、cf_root\CFusionMX\runtime\servers\default\SERVER-INF に、J2EE 構成のインストールの場合、jrun_root\JRun4\servers\cfusion\SERVER-INF にあります。threadWaitTimeout 設定は処理待ちスレッドのタイムアウトを設定するものです。処理待ちスレッドとは実行リクエストとなるのを待っているスレッドを指します。
<service class="jrun.servlet.jrpp.JRunProxyService" name="ProxyService">
<attribute name="activeHandlerThreads">8</attribute>
<attribute name="minHandlerThreads">1</attribute>
<attribute name="maxHandlerThreads">1000</attribute>
<attribute name="mapCheck">0</attribute>
<attribute name="threadWaitTimeout">20</attribute>
<attribute name="backlog">500</attribute>
<attribute name="deactivated">true</attribute>
<attribute name="interface">*</attribute>
<attribute name="port">51010</attribute>
<attribute name="timeout">300</attribute>
<!-- set this to false for multi-hosted sites -->
<attribute name="cacheRealPath">false</attribute>
<!--
<attribute name="keyStore">{jrun.rootdir}/lib/keystore</attribute>
<attribute name="keyStorePassword">changeit</attribute>
<attribute name="trustStore">{jrun.rootdir}/lib/trustStore</attribute>
<attribute name="socketFactoryName">jrun.servlet.jrpp.JRunProxySSLServerSocketFactory</attribute>
-->
</service>
推奨:
ColdFusion MX では、デフォルトは 300 秒に設定されており、ColdFusion MX 6.1 では 20 秒に設定されています。この動作変更は、処理待ちスレッドが時期尚早にタイムアウトし、JRun Closed connection エラーを発生させてしまう可能性があることから、Macromedia 障害 55053 として報告されています。このエラーについては、テクニカルノート 19351 をご覧ください。 threadWaitTimeout の推奨タイムアウト値は、少なくとも、ColdFusion Administrator のリクエストタイムアウトと同等値で、300秒を超えない値です。
例えば:
ColdFusion Administrator で同時リクエスト数が 5 に設定されている際に、10個のリクエストが同時にColdFusionに入ってきたとします。すると、スレッド 1 からスレッド 5 は実行リクエストとなり、スレッド 6 からスレッド 10 は処理待ちスレッドとなります。この際、 threadWaitTimeout 設定が、スレッドをタイムアウトする前に、処理待ちスレッドがどれくらいの時間アクティブリクエストプールの利用可能となるスペースを待つのかを決定しています。
タイムアウトの動作想定
以下の各シナリオでは、共通する4つの状況下で、リクエストタイムアウトとthreadWaitTimeout の各設定がどのように動作するかについて示しています。
シナリオ 1
| サーバーの設定 | |
|---|---|
| 同時リクエスト数 | 5 |
| リクエストタイムアウト | 30 秒 |
| threadWaitTimeout | 30 秒 |
doSomething.cfm というページには、 cfloop およびそのほかのコードが含まれています。ページの実行には45秒かかります。このページが呼び出される時には、サーバーの負荷は低く、4つ以下の実行中のリクエストがあるとします。このページはどうなるでしょうか。
答え: doSomething.cfm ページは30秒後にタイムアウトし、Application.log ファイルには以下のエラーが表示されます。このページの実行には、リクエストタイムアウト値である30秒を超える時間(45秒)がかかるからです。
"Error","jrpp-19","04/14/04","10:34:02",,"The request has exceeded the allowable time limit
Tag: CFLOOP The specific sequence of files included or processed is:
C:\Apache2048\Apache2\htdocs\shaws_ora\doSomething.cfm "
Note: タイムアウト値を増加することでページのタイムアウトを修正することは、修正手段とはいえません。ページの処理に時間がかかる根本的な原因を突き止めることが重要です。例えば、クエリの実行には300ミリ秒を超えるべきではありません。Webの 環境においては、10 から 100 ミリ秒が理想的です。処理に時間のかかるクエリがある場合、データベース管理者と相談し、最適化する必要があります。ページ内のどの部分のコードの処理に一番時間がかかっているのかを見極めるには、gettickcount() をコードセクションに使用することができます。ページパフォーマンスの改善に関する情報については、以下にリストされているパフォーマンス関連テクニカルノートを参照してください。妥当な理由により処理に時間がかかっている場合は、その特定のページに対する(延長された)タイムアウト値を cfsetting を使用して設定します。
シナリオ 2
| サーバーの設定 | |
|---|---|
| 同時リクエスト数 | 5 |
| リクエストタイムアウト | 30 秒 |
| threadWaitTimeout | 30 秒 |
doSomething.cfm というファイルには、 timeout 属性が120 に設定されたcfquery が含まれています。ページの実行には80秒かかります。このページが呼び出される時には、サーバーの負荷は低く、4つ以下の実行中のリクエストがあるとします。このページはどうなるでしょうか。
答え: cfquery タグによりColdFusion Administrator のタイムアウトが無効になっているため、doSomething.cfm ページは正常に実行されます。タイムアウトすることはありません。注意: cfquery タグで timeout 属性が機能するには、データベースベンダーがこの機能をサポートしている必要があります。Oracle、Microsoft SQL Server、Sybase といった、ほとんどのエンタープライズデータベースではこの機能がサポートされていますが、必ずデータベースのドキュメントで確認してください。
シナリオ 3
| サーバーの設定 | |
|---|---|
| 同時リクエスト数 | 5 |
| リクエストタイムアウト | 30 秒 |
| threadWaitTimeout | 20 秒 |
doSomething.cfm というページには、 timeout 属性が120に設定された cfquery が含まれています。ページの実行には80秒かかります。マシンには高負荷がかかっている状態で、このページが呼び出される時には、同時リクエストが5つ以上あるものとします。このページリクエストは処理待ち状態となり、待ち時間は平均30秒です。このページはどのように処理されるでしょうか。
答え: threadWaitTimeout 値が20秒で、この場合の平均待ち時間30秒よりも短いため、doSomething.cfm は実行中のリクエストキューになる前にタイムアウトしてしまいます。
ブラウザに JRun Closed Connection エラーが表示されるとともに、以下のようなエラーが default-err.log にも記録されます:
java.lang.RuntimeException: Request timed out waiting for an available thread to run.
You may want to consider increasing the number of active threads in the thread pool.
at jrunx.scheduler.ThreadPool$Throttle.enter(ThreadPool.java:125)
at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:448)
at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:294)
at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)
Note: threadWaitTimeout が短いこと以外にも JRun Closed Connection エラーが発生している理由はあります。この種のエラーをトラブルシュートする方法については、このテクニカルノートの下方に示すテクニカルノートを参照してください。
シナリオ 4
| サーバーの設定 | |
|---|---|
| 同時リクエスト数 | 5 |
| リクエストタイムアウト | 30 秒 |
| threadWaitTimeout | 300 秒 |
doSomething.cfm が呼び出される際には、マシンには高負荷がかかっており、5つ以上の同時リクエストがあります。リクエストの処理待ち平均時間は30秒です。doSomething.cfm の実行には約25秒かかるとします。このページはどのように処理されるでしょうか。
答え: このスレッドは待機リクエストとして30秒しか処理を待つ必要がなく、 threadWaitTimeout は300秒に設定されているので、doSomething.cfm は正常に実行されます。一旦リクエストが実行リクエストキューに移動すると、タイマーが再び作動するので、実行に25秒かかるページは、設定されたリクエストタイムアウト値(30秒)が適用される(タイムアウトする)ことがありません。
関連テクニカルノート
- ColdFusion MX 6.1 (サーバー構成): 「jrun closed connection」エラーのトラブルシューティング
- ColdFusion MX 6.1: 「Request timed out waiting for an available thread to run」 エラー
- ColdFusion Performance Tuning
- ColdFusion MX: パフォーマンスとスケーラビリティのためのヒント
追加情報
このテクニカルノートは、米国 Macromedia, Inc. の ColdFusion MX: Explanation of Request Timeout and threadWaitTimeout settings (TechNote19438) をもとに作成されました。
最終更新日: 2004年7月15日
作成日: 2004年7月15日
