最適化の提案には 200 ポイント
問題は次のとおりです:
a -> b -> c
a は、http を介してデータを同期する責任があります。プロトコル。
b は私たちであり、a によってプッシュされたデータを受信し、ビジネス ロジック処理を実行し、整理されたデータをパートナー c (c は多数あります) にプッシュする責任があります。
私のプログラムの全体的な構造は次のとおりです:
1 エントリ ファイルがあります。これは実際には php ファイルであり、a からデータを受信してデータベースに保存する役割を果たします。
2 nohup コマンドを使用して php cli モードを呼び出し、php プロセスを開き、php ファイルを実行してシステムのバックグラウンドで次のことを処理しました。データベースから一度に 10 個のデータを取得し、ループ内の各部分は、ビジネス ロジックに従って、データの各部分は異なり、異なる c に転送されます (実際には、異なる URL にアクセスすることを意味します)。
データを同期すると、1 秒間に 10 個を超えるアイテムがパケットを送信することがあります。私の側では、ウェアハウス後、一度に 10 個のデータを取り出し、ループ内の別の URL アドレスにプッシュします。インターフェースから「ok」応答を受け取った後、それにマークを付けて、次のデータをプッシュします。私が設定した場合、タイムアウト期間が 5 秒経過しても相手からの「OK」が受信されなかった場合、タイムアウト期間は 5 秒のまま、合計 2 秒になります。再送信。これは、1 つのデータが 3 回までプッシュできることを意味します。3 回プッシュできない場合は無視されます。また、各データプッシュの間に 1 秒間のスリープを設定しました。
発生した問題:
通常の状況では、データをプッシュするのに約 2 秒かかりますが、特定の c のインターフェイスがネットワーク上の理由やプログラムの問題の影響を受けている場合、 3 プッシュが完了しない場合でも (つまり、インターフェイスの応答速度が 5 秒を超えるか、まったく応答しない場合)、データ キューが最大 18 秒間滞ります。これにより、プッシュ速度が大幅に低下します。今日確認したところ、データキューが通常より 1 時間ほど遅くなっています。この問題を解決する良い方法はありますか?
php 自体はマルチスレッドをサポートしていないため、異なるスレッドを設定してデータを異なる cs にプッシュすることはできません。したがって、1 つの C のインターフェイスの応答が遅いと、すべての C とデータ キュー全体に影響します。
このようなことをしたことがあり、経験を積んでくれる友人はいないだろうか。 c に加えて、インターフェイスの応答速度を向上させ、スムーズなネットワーク接続を確保する必要があります。自分で問題を解決する方法はありますか?私のパートナーの中には Java を使用し、スレッド プールを作成してマルチスレッド コントラクトを送信できる人もいますが、PHP はもっと無力です。
実際、以前私が使用した方法は同期転送でした。つまり、a からデータを受信した後、すぐにビジネス ロジックを処理し、すぐにデータを c に同期的に転送しました。列に並ばずに。これには上記の問題はありませんが、他の多くの問題が発生するため、現在はこのキュー方式に変更しました。
私は 2 つの解決策を考えましたが、それらが実現可能かどうかはわかりません:
1 PHP 自体はマルチスレッドをサポートしていませんが、Linux での Curll、wget、または Apache での ab をサポートしています。これらはマルチスレッドをサポートしています。PHP を使用してそれらを呼び出して、マルチスレッドを通じてデータをプッシュできますか? 1 つの c がブロックされても他の c に影響を与えないように、異なる c にスレッドを割り当てます。
2 マルチスレッドをサポートしていません。私は異なる c ごとに個別の php プロセスを開きます。これにより、c 間の相互影響も回避できます。しかし、無限ループで実行されている非常に多くのプロセスを開くことがオペレーティング システムにどれだけの影響を与えるかはわかりません。現在、このビジネスには約 10c の従業員がいます。
ご意見やご指導をいただければ幸いです、ありがとうございます!
-----解決策---------
複数のプロセスを開き、各 c に対して個別の PHP プロセスを開きます。
は影響しません。同時に 2 つを開くだけで常に使用します。1 つは他のプロセスを監視し、もう 1 つはファイル操作を実行します。両方とも実行されます。無限ループでは、
いいえ、無限ループ自体が負荷に影響を与えることが判明しました。ファイル操作をスケジュールすると、負荷に確実に影響します。 CPU/ハードディスクは読み書きに十分な強度があるので問題ないはずです。または、それぞれ 2 c に相当する 5 つに減らしてください
------解決策------------------
データベースを頻繁にチェックしますが、ボトルネックがあるのではないかと考えます。データが直接取得されて処理されない場合は、データベースに加えてメモリに配置し、キューを作成して PHP プロセスを解放する方がよいでしょう。それを取得するためにメモリキューに追加します。
------解決策---------
SOAP を使用して解決する
------解決策---------
SOAP を使用して実現可能性を解決します
原則 はい、soap はデータの受信をリッスンします
その後、soap はバックグラウンドで複数のプロセスを開始します
-----解決策---------
ちなみに待たずに戻った方が良いです
x.php は実行を続け、メモリキューから定期的にデータを取得し、メモリ内のデータをマークし、処理後にそれを c エンドにプッシュしますが、戻りを待ちません
x.php が取得したときマークされた data
C 側はリクエストを返し、それを別の m.php に送信し、戻り値を受信してメモリ キューと比較し、一致するものを削除します。
------解決策------------------
PHP CLI モードは非 WIN 環境でもマルチスレッド化できますが、非常に弱いです
HTTP はステートレス プロトコルであり、複数のプロセスで実行できますが、重大な問題があります
A-> ; 10+/S
->C 10/5S
つまり、C の送信速度は A の受信速度よりも遅いです。その結果、前の C が終了する前に別の C が開始され、最終的に N 個のプロセスが蓄積されます。システムがクラッシュするか、C ごとに 1 つのプロセスが発生します。大きなデータ遅延が発生します。
各 C には個別のプロセスを割り当てることができますが、一度に 10 個に制限されるわけではありません。送信できる数だけ送信する必要があります。これにより、プロセスの数と遅延を効果的に制御できます。基本的に、最大遅延は実行時間 + 送信時間です。
または、各スレッドに 10 個のスレッドがある場合、各 C プロセス + マルチスレッドをキューに入れることができます。バックログが 10 を超えた場合は、新しいスレッドを開始します。基本的に、同期を確実にするには、データを提供する方法はパッシブ アクセスです。数 K のノードの生成と送信の負荷は高くないので、キャッシュを使用できます。
はは、SOAP の方が適しているかもしれませんが、アップストリームとダウンストリームのサポートが必要です。
------解決策------------------
私の提案:
1. B->C を処理する現在の php cli プログラムを Apache の下に置きます。つまり、http://www.x.com/b2c.php
2独立した php CLI プロセス php.exe db_read.php を開き、ループでデータベースを読み取り、読み取ったフィールドを b2c.php
に送信します。Apache はマルチスレッドをサポートしているため、一度に 10 個を問題なく送信できます。 )
------解決策----------------------
これについてはよくわかりませんが、少し前に「サーバープッシュ」テクノロジーを目にしました。役に立つかも知れません。
さらに、SQL データベースがあまり最適化されていない場合、一度に 10 項目をクエリできるため、データ要件がボトルネックになる可能性があります。このクエリでは完全には満たされません。
プッシュ速度に基づいて、一度に 100 個のデータを読み取り、ファイルとして一時的に保存することをお勧めします。結局のところ、ファイル操作はデータベース操作よりも高速です。
10 項目を押し出し、10 項目だけ残ったら 100 項目を読み取ります。これにより、データベースの読み取り回数を減らすことができます。
最適化したい場合は、歯まで最適化する必要があります。その他の点については、あまり知識が無いので、何も思いつかず、お役に立てず申し訳ありません。
------解決策--------
複数のプロセスを開きます (各 c に 1 つずつ) 個別の PHP プロセス, が影響を受けるため、2 つを同時に開いて常に使用しています。1 つは他のプロセスを監視し、もう 1 つはファイル操作を実行し、両方とも無限ループで実行されます。
------解決策------------------
投稿者の ShadowSniper の投稿を引用します: