ページがクエリを待機してハングし、メモリを消費し、失敗するまでに 2 時間かかります

ページがクエリを待機してハングし、メモリを消費し、失敗するまでに 2 時間かかります

添付の Fusion Reactor の画像をご覧ください。ページがずっと実行され続けているのがわかります。時間は数百万にまで達し、完了するかどうか確認するために放置しましたが、それは 2 ~ 3 ページしかなかったときでした。

今では、何十ページも完了しません。クエリも異なるため、7 つのデータベースのうち 3 つにのみ適用されるように見えることを除いて、大きなパターンは見当たりません。

topショーコールドフュージョンCPU 使用率は約 70 ~ 120% で、Fusion Reactor の詳細ページをさらに詳しく調べると、蓄積された時間はすべて Mysql クエリのみに費やされていることがわかります。

show processlist10~20の接続を除いて異常は何も返されません。寝る州。

この間に多くのページが完了しますが、ハングしているページ数が増えて、ページがまったく完了しないため、サーバーは最終的に白いページを返すだけです。

唯一の短期的な解決策は Coldfusion を再起動することのようですが、これは理想的とは言えません。

最近、5 分ごとに実行され、処理するバッチ csv ファイルをチェックする Node.js スクリプトが追加されました。これがすべての MySQL 接続を盗む問題を引き起こしているのではないかと考えたため、これを無効にしました (スクリプトには connection.end() メソッドがありません)。ただし、これは単なる推測です。

どこから始めればいいのか分かりません。誰か助けてくれませんか?

最悪なのは、ページが決してタイムアウトしないことです。タイムアウトしてもそれほど悪くはありませんが、しばらくすると何も提供されなくなります。

私は主なスクリプト言語としてColdfusionとNodeJSを使用してCentOS LAMPスタックを実行しています。

決して失敗しない非常に長いリクエスト

実際に投稿する前に更新してください

Node スクリプトを無効にして Coldfusion を再起動してからこの投稿を書き始めたのですが、その間に問題は解消されたようです。

しかし、ページがタイムアウトしない理由を正確に特定し、Nodeスクリプトに次のようなものが必要であることを確認するための助けがまだ必要です。connection.end()

また、負荷がかかったときにのみ発生する可能性があるため、完全に解消されたとは言い切れません。

アップデート

まだ問題が残っていますが、Fusion Reactor で現在最大 70 秒かかるクエリの 1 つをコピーし、データベースで手動で実行したところ、数ミリ秒で完了しました。クエリ自体には問題はないようです。

もう一つのアップデート

ページの 1 つのスタック トレースはまだ実行中です。サーバーはしばらくページの提供を停止していません。現在、すべての Node スクリプトは無効になっています。

http://pastebin.com/D6ycJf3X

さらなるアップデート

今日はこのようなことがいくつかありました。実際に完了したところ、FusionReactor で次のエラーを発見しました。

Error Executing Database Query. The last packet successfully received from the server was 7,200,045 milliseconds ago. The last packet sent successfully to the server was 7,200,041 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.

さらなるアップデート

コードを詳しく調べて、「2 h」、「120」、「7200」を探してみました。7200000ms のタイムアウトは偶然すぎると感じたからです。

このコードを見つけました:

// 3 occurrences of this
createObject( "java", "coldfusion.tagext.lang.SettingTag" ).setRequestTimeout( javaCast( "double", 7200 ) );

// 1 occurrence of this 
<cfsetting requestTimeOut="7200">

これらのコード行を参照する 4 つのページは、めったに実行されず、2 時間以上のタイムアウトでログに表示されたことはなく、パスワードで保護された領域にあるためスクレイピングできません (これらはファイルのアップロードと CSV 処理用でしたが、現在は nodejs に移動されています)。

これらの設定が 1 つのページで設定され、サーバーに存在して他のリクエストに影響を与える可能性はありますか?

答え1

1) スタックトレースを投稿します。

Socket.read() (または同様のもの) でハングすることを保証します

発生しているのは、DB への TCP 接続の半分が閉じられ、CF が決して得られない応答を待機している状態です。

cf ボックスと db の間にネットワークの問題が発生しています。

Java DBドライバは一般的にこれに対処するのが苦手である


スタックトレースをありがとう

これは、TCP 接続の半分が閉じているという私の仮説を裏付けています。

次のいずれかが疑われます。1) mysql が Linux 上にあり、TCP スタックにバグがあるため、そのボックスの Linux をアップグレードする必要があります。はい、これは以前にも見たことがあります。2) coldfusion は Linux 上にあり、1) のとおりです。3) いずれかのボックス上またはボックス間のケーブル/ハードウェアに障害があります。4) Windows を実行している場合は、TCP オフロードを無効にしてください。

3) は難しいです。両方のボックスで Wireshark を実行し、パケット損失を証明する必要があります。より簡単な解決策は、Rackspace VM を別の物理ホストに移動して、問題が解決するかどうか確認することです。(まれに、コードが非常に悪く、CF ボックスと MySQL ボックス間のネットワークが飽和状態になっている可能性がありますが、それほど悪いコードを書くことができるかどうかはわかりません)

答え2

私はこれについてさらに時間をかけて調査し、ネットワークの問題の具体的な原因と、Charlie Arehart の助けを借りて見つけた回避策について、さらに詳しい情報を追加しました。

まず、ネットワーク接続が自動スクリプトのトリガーによって中断されていましたiptables restart。これにより、サーバーにアクセスできる IP アドレスのリストが更新されましたが、アプリケーションと DB サーバー間の接続も切断されました。

これは、より遅いページやより頻繁に実行されるページで発生する可能性が高く、iptables restartコードと一致するものはすべて切り捨てられます。

Rackspace がこれを見つけて、次のコードを変更することを提案しました:

/sbin/service iptables restart

/sbin/iptables-restore < /etc/sysconfig/iptables

これにより、サービスの再起動が停止され、新しい接続にのみ適用されます。

これが問題の根本的な原因でしたが、実際の問題は、Coldfusion、または実際にはその下の JDBC が DB サーバーからの応答を待機し続けるという事実です。

2 時間のタイムアウトがどこから来たのかはわかりませんが (デフォルトだと仮定)、Charlie は CFIDE 接続文字列でより短いタイムアウトを設定する方法を示しました。これにより、CF は DB をあきらめる前に最大時間待機するように指示されます。

したがって、接続文字列は次のようになります。

__fusionreactor_name=datasourcename;connectTimeout=600000;socketTimeout=600000;

これら 2 つの詳細は覚えていませんが、待機時間をミリ秒単位で設定し、その後 DB 接続を放棄します。

  • 接続タイムアウト=600000;
  • ソケットタイムアウト=600000;

これは、Fusion Reactor のデータ ソースにラベルを付けるだけです。Fusion Reactor をお持ちの場合は、CF アプリケーションの問題を見つけるのに非常に役立ちます。Fusion Reactor をお持ちでない場合は、この部分を省略してください。

  • __fusionreactor_name=dsnapi;

これをCFIDEの各データソースに適用する必要があります。

接続文字列を表示する CFIDE データソース パネル

関連情報