最近、フロントエンド、ajaxなどの急速な成長と複雑さのために -PHPでのサイトの操作中にセッションをブロックする問題は、ますます明らかになってきています。 PHPはデフォルトでセッション用のファイルを作成し、プロセスはそれを排他的にブロックします。 セッションを開こうとする他のプロセス(ajax、ブラウザーのタブ)が並んでいます。 アプリケーションロジックは、特に複雑な場合、必ずしもセッションで競合するプロセスのブロック時間を効果的に制限できるとは限りません。
さらに状況が悪化するのは、このようなクライアントが3人から5人でPHPワーカーによるプロセスの待機とアイドル待機が迅速に行われ、サイトが非常に悪くなったとしても悪くなったためです。
残念ながら、開発者/システム管理者は、セッションをブロックすることであるとすぐに理解できない場合があり、プロジェクトの他の部分の問題を探して時間を浪費します。
記事では、どのツールを使用して問題を迅速に診断できるかを説明します。機能するコードを提供し、生存のための戦闘に関する推奨事項を示します:-)
私は意図的にこの記事を複雑にすることはなく、カスタムPHPセッションハンドラーを記述する理論と実践についても話しません。これは別の興味深いトピックです。 私たちは特定の問題に焦点を当て、それを解決しようとします。
診断
ブラウザで(別のタブで開くことができます)1つの眠っているファイルとセッションを開始するいくつかのスクリプトを同時に開こうとすると、オペレーティングシステム内で何が起こるかを考えます。
<?php session_start(); sleep(30);// ?>
ページは、セッションが解放されるまで(30秒)待機します。これには時間がかかり、Webサーバーのスロットが詰まります。 ajaxがWebクライアントセッションで重いタスクを起動し、残りのajaxおよびその他のインターフェイス要素が保留状態になった場合(または同じ承認の下で複数のタブが開かれた場合)に、ほぼ同じことが起こります。
Webサーバープロセス、この場合はhttpdですが、php-fpmでも同じことが発生します-セッションファイルを排他的にロックしようとします。これはlsofで確認できます。
lsof -n | awk '/ sess_ /' httpd 7079 nobody 52uW REG 8.1 2216 809832 / tmp / sess_f629a13b4b0920a21042c86d17f4a6a6 httpd 10406 nobody 52u REG 8.1 2216 809832 / tmp / sess_f629a13b4b0920a21042c86d17f4a6a6 httpd 10477 nobody 52u REG 8.1 2216 809832 / tmp / sess_f629a13b4b0920a21042c86d17f4a6a6 httpd 10552 nobody 52u REG 8.1 2216 809832 / tmp / sess_f629a13b4b0920a21042c86d17f4a6a6 httpd 11550 nobody 52u REG 8.1 2216 809832 / tmp / sess_f629a13b4b0920a21042c86d17f4a6a6 httpd 11576 nobody 52u REG 8.1 2216 809832 / tmp / sess_f629a13b4b0920a21042c86d17f4a6a6
4列目に注意してください。 番号はプロセス内のファイル記述子の番号であり、次にロックのタイプです。 「UW」-Webサーバーは、記録専用にファイルをロックしました。 残りは傍観者を待って神経質に喫煙しています:-)プロセス7079が作業を完了するとすぐに、別のプロセスがロック「uW」を取得します。 現時点では、もちろん、ラインが構築されており、Webインターフェースは著しく遅いです。 複数のプロセスが数秒間セッションをブロックすると、さらに楽しくなります。通常、インターフェイスが重要になります。
次に、プロセスが行っていることの反対側を見てみましょう。
ps -e -o pid、comm、wchan = WIDE-WCHAN-COLUMN | grep httpd 7079 httpd- 10406 httpd flock_lock_file_wait 10477 httpd flock_lock_file_wait 10552 httpd flock_lock_file_wait 11550 httpd flock_lock_file_wait 11576 httpd flock_lock_file_wait
2番目の列では、関数"flock_lock_file_wait"で1つを除くすべてがビジーであることがわかります。 なんで?
strace -p 10406 プロセス10406が添付されました-中断して中断します 群れ(52、LOCK_EX)
そうです、排他的ロック要求のあるシステムコールで。
LOCK_EX排他ロックを設定します。 保持できるプロセスは1つだけです 特定の時間の特定のファイルの排他ロック。
便利なスクリプト
WebサーバーでPHPワーカーを詰まらせるような「トレイン」の出現を常に監視するために、単純なAWKスクリプトを作成しました。
/sess_/ { load_sessions[$9]++; if (load_sessions[$9]>max_sess_link_count){ max_sess_link_count = load_sessions[$9]; max_sess_link_name = $9; }; if ($4 ~ /.*uW$/ ){ locked_id[$9]=$2 }; } END { print max_sess_link_count, max_sess_link_name,locked_id[max_sess_link_name]; if (locked_id[max_sess_link_name] && max_sess_link_count>3) { # r=system("kill "locked_id[max_sess_link_name]); # if (!r) print "Locking process "locked_id[max_sess_link_name]" killed" system("ls -al "max_sess_link_name); } }
次のように始まります:
lsof -n | awk -f sess_view.awk 5 / tmp / sess_f629a13b4b0920a21042c86d17f4a6a6 24830
「電車」の長さとプロセスを表示します-マッシュを作成します。
そのようなプラグがバトルにあるべきではないことは明らかです-セッションを操作するロジックをやり直すか、カスタムPHPハンドラーを作成する必要があります-クライアントが何も遅くならないようにすべてを行い、システム管理者として、あなたはしっかりと長時間眠ります
それが非常に怠Ifな場合(私は本当に1つだけです)、「キル」のコメントを外し、崩壊を引き起こすWebサーバープロセスを撃ち
すべての人に幸運と成功を!
PS
言語学教育を受けたロシアの教師とプログラマーの要請で、彼は「ロック」という言葉を「ロック」に置き換えました。
当社の大規模プロジェクトをサポートするために、パフォーマンスの問題とその解決策を迅速に分析するためのツールとテクニックを常に作成する必要があります。 GNU / Linuxには多数の便利なツールが含まれていますが、残念なことに、誰もがそれらを使用する方法を知っているわけではありません。 このような実用的な記事が、システム管理者だけでなく、Web開発者にも役立つことを願っています。