私はウェブアプリを構築しています。 ElasticSearchとREST APIでPHPで記述されたAPIでインデックス付けされた書籍のデータベースがあります。
アプリには検索ボックスがあり、本の名前を入力すると、JSスクリプトが検索リクエストを呼び出し、ElasticSearchへの検索クエリでcurlリクエストを実行します。
問題は、ユーザーがすばやく入力すると、リクエストが多すぎることです。速度が低下し始め、通常は1回のリクエストが約200ミリ秒続きますが、最大5〜10秒かかり、長すぎます。実行するリクエストの数を減らすことはできますが、その即時のフィードバックが必要です。
だから私は尋ねます-サーバー上のcurlのコアは、別々のPHPリクエストで呼び出されたとしても、一度に1つのリクエストしか実行しないのですか?それとも他の何かですか?
簡単な答えは、非同期ではないということです。より長い答えは、「バックエンドを自分で作成しない限り、そうしない」です。
XHRを使用している場合、各リクエストのバックエンドには異なるワーカースレッドがあります。つまり、ヒットプロセスとメモリ制限を除いて、リクエストが他のリクエストをブロックすることはありません。 XHRはイベントベースのインターフェースを提供しますが、それでもブラウザーによって同期的に処理されるライブHTTPリクエストです(jsでは1つのスレッドしか取得できません)。 phpバックエンドも同期的にcurl呼び出しを行い、curl呼び出しが終了するまでXHRのhttpリクエストの結果を返しません。これで、JavaScriptを設定して結果をポーリングすることができますが、存続時間は3〜5秒未満であるため、それだけの価値はありません。
WebSocketを使用している場合は、お知らせください。特定のWebSocketは、バックエンド上の1つのプロセスに関連付けられていますが、そのプロセスでフォーク/スレッド/実行することができます。また、クライアントがリクエストを開始することなく、イベントをブラウザに直接プッシュすることもできます。これはcould非同期ですが、速度低下がバックエンドにある場合は、非同期設計に変更するのに役立ちません。
現実的には、最後の検索が戻るまで、クライアントのJavaScriptで次の検索を発行するのを待つ必要があります。裏側では、DOSを防ぐために、単一のクライアントがあまりにも多くの完了検索リクエストを送信し始めた場合、HTTP 429でリクエストのドロップを開始し、JSで429応答を処理して、増分バックオフを実行し、必要に応じて後で再試行します。
間違いなく実行する必要があるもう1つのことは、curlの要求タイムアウトをはるかに低い値に設定して、適切にタイムアウトするようにすることです。検索データが2〜3秒間しか役に立たない場合、curlリクエストのタイムアウトはほぼ同じである必要があります。バックエンドが十分にインテリジェントである場合、閉じた接続を「検索の停止」を意味すると解釈し、別のプロセスがそれらを使用するのに間に合うようにリソースの損失を停止できることを願っています。
私の理解では、オートコンプリートに使用できるスクリプトを実行するWebサーバーがあります。このスクリプトは、cURLを使用して別のサーバーに対してクエリを実行します。
まず、あなたの質問に答えるために:あなたのウェブサーバーはおそらく複数のPHPプロセスを並行して実行でき、cURLはPHPによって呼び出されるので、それも並行して実行されます。実行しているWebサーバーを教えてください。ただし、ほとんどの場合、これをサポートしています。
ただし、セットアップは非常にネットワークを集中的に使用しているようです。キーを押すたびにサーバーへのリクエストが生成され、他のサーバーへのリクエストが生成されます。サーバーにリソースが不足している場合、または他のサーバーにレートリミッターが設定されている場合は、パフォーマンスが低下します。たぶん、結果をWebサーバーにキャッシュするか(cURLを頻繁に実行する必要がないように)、Javascriptを数ミリ秒待機させて、高速なユーザーがあまり多くのリクエストをトリガーしないようにします。