世論調査:PHPで並列リクエストを同期する問題をどのように解決しますか?

長い間、私は平均的なPHPプログラマーの日常の実践において、コード実行の並列性と競争力の問題にどれだけのスペースが費やされているかを理解しようとしてきました。 一方では、サーバーアプリケーションを開発するとき、プログラマーは自動的に並行して実行されるコードを記述します。 一方、PHPの実際には、この分野のすべての問題は、誰もが使用したツール(Webサーバー、セッション、DBMS)によって解決されました。



プロジェクトは、同時に処理されるHTTPリクエストの同期の問題に注意を払っていますか? それらはトランザクション、ロックを通じて解決されますか? どのようなブロック方法を使用していますか? とにかく、あなたはそれについて入浴する必要がありますか、またはトピックは役に立たないのですか? 観客の意見を学びます。 この投稿は質問への回答を提供していません。 インテリジェンスはここで進行中です。





***



PHPの世界では、コードの並列実行にあまり注意を払わないことが歴史的に慣習となっています。 PHP自体はマルチスレッド用に強化されていません(エンジン内にスレッドセーフはありません)。 私は、 pthreadを使用したプロジェクトやプログラマに会ったことはありません(会ったことがありますか?それからコメントで教えてください) また、Webアプリケーションでは、実際にはそれほど多くのマルチスレッドは必要ありません。Webアプリケーションでは、主にリクエストを実行する必要があり、単一のリクエスト内でコードの一部を分離する必要はありません。 また、個別のプロセスでの着信要求の並列実行はアプリケーションサーバー(php-fpmまたはapache)によって編成されるため、プログラマーはそれについて考える必要がありません-すべてがそのまま動作します。



PHPには、ほとんどの場合に使用されるセッションメカニズムがあります。 デフォルト設定のセッションは、単一セッション内のリクエストの並列実行をブロックします。 これはいくつかの穴を「カバー」し、実際には明らかな問題に遭遇することは決してないという事実につながります。 つまり ユーザーがハッキングを開始して、たとえば2つのブラウザーで同時に作業するまで、ロックとトランザクションがないため、何も壊れません。



さらに、要求のピーク数が1秒あたり2未満のサイトでは、並列処理による衝突の可能性は非常に小さくなります(応答生成時間が1秒を超えないと仮定します)。



最後に、いくつかの並列処理の問題が引き続き発生する場合、それらを解決する最も簡単な方法は、十分なレベルの分離を備えたデータベース内のトランザクションです。 PHPで開発されたほとんどすべてのサイトは、ストレージとしてトランザクションDBMSを使用しているため、トランザクションの使用を開始して、データの不整合につながるクエリ実行の競合問題を解決するだけで十分です。 トランザクションを使用するだけで、プロセス同期のトピックを深く掘り下げることなく、問題を解決できます。



これはすべて、実際には平均的なPHPプログラマーが並列コード実行の問題に遭遇することはほとんどないという事実につながります。 最も一般的には、並行プログラミング、同期、およびロックについてほとんど知りません。 これはインタビューで明確に見られます。 そして、これがどれほど需要があるのか​​、この調査で知りたい。



部分的には、これはすべて良好です-PHPの主な利点の1つである低いエントリしきい値。 すべてのボトルネックを処理する時間を節約することにより、迅速な開発。 しかし、遅かれ早かれ、多くの人がプロセスを直接同期する問題に直面し始めます。 また、信頼性が高く、状況に合わせて設計されていないアプリケーションの開発では、この問題をある程度調査する必要があります。



トランザクションが役に立たない最も簡単な例は、キャッシュのウォームアップです。 キャッシュされているデータが並行して生成されるのを防ぐには、競合する要求をブロックして、最初に要求が満たされ、キャッシュが満たされるようにする必要があります。 ブロックせずにはできません。 さらに、複数のサーバーがある場合は、ロックを集中化する必要があります。 別の例は、ファイルホスティングです。 ユーザーがアップロードできるファイルの数は限られています。 ファイルを追加するとき、ダウンロードしたファイルの数を制限と比較し、制限を使い果たしていない場合はファイルを受け入れる必要があります。 ここでは耳でフェイントを行い、ロックなしで行うことができますが、ユーザーがチェックする前にブロックし、カウンターをチェックし、ファイルスロットを占有し、ロックを解除してからファイル本体を取得するのが最も簡単です。



また、トランザクションの使用にも問題があります。 競合状態があり、衝突によりトランザクションがロールバックされた場合、少なくとも数回それらを再起動する必要があります。 データベースの外部リソース(ファイル、キャッシュ、リモートAPIへのリクエスト)を操作する際に質問があります。



***



実際、すべてのPHPプログラマーは、競争の激しい環境で機能するコードを作成します。 多くの場合、非常に競争が激しい場合でもです。 また、並列プロセスから共有リソースへのアクセスを同期する必要があります。 私のような多くの人が、同僚がこの問題をどのように見ているかを知りたいと思うでしょう。 プロジェクトは、共有リソースへのアクセスを同期する問題をどのように解決しますか?



この問題はどのように解決されますか?
トランザクションとロックを使用します。 トランザクションは、タスクがデータベース内の一連のクエリに削減される場合、データの一貫性を維持するのに役立ちます。 データベースと連携するだけでなく、まったく連携しないコードを同期する必要がある場合、ロックのメソッドではなく抽象化ライブラリを介してロックを使用します。 バックエンドが同じサーバーで実行されている場合、flock()のドライバーを使用するだけで十分です。分散をブロックする必要がある場合は、RedisまたはMemcacheのドライバーを使用できます。





このトピックに関する適切な資料がある場合は、コメント内のリンクを共有してください。



PS他のプログラミング言語の愛好家に:あなたの言語/フレームワークで問題がどのようにうまく解決されたかを伝えたいなら、あなたは歓迎されています。 それ以外の場合は、パブリケーションが投稿されているハブに注意してください。



All Articles