ホームページ >バックエンド開発 >PHPチュートリアル >バックグラウンド処理を使用して、ページの読み込み時間をスピードアップします
コアポイント
この記事は、パフォーマンスベンチマークと最適化のためのサンプルアプリケーション(マルチピクチャブログ)の構築に関する一連の記事の一部です。 (こちらのコードベースを表示)
以前の記事では、オンデマンド画像スケーリング機能を追加しました。画像は、初めてリクエストされたときに使用するためにスケーリングおよびキャッシュされます。これは便利ですが、システムはサムネイルを動的にレンダリングし、画像レンダリングが完了する前に最初のユーザーのページレンダリングを「ブロック」する必要があります。最適化ソリューションは、ギャラリーを作成した後にサムネイルをレンダリングすることです。 「わかりましたが、ギャラリーを作成したユーザーがブロックするだけでなく、スケーラブルなソリューションでもありません。ユーザーは、より長い読み込み時間について混乱します。または、画像が大きすぎて処理できない場合は、タイムアウトやエラーに遭遇します。最良の解決策は、これらの重いタスクを背景に移動することです。
背景タスク
背景タスクは、あらゆる重いタスクを処理するための最良の方法です。ユーザーにリクエストを受け取ったことをすぐに通知し、処理を手配することができます。 YouTubeがビデオをアップロードするためにも同じことが言えます。ビデオにはアップロード後にアクセスできません。ユーザーは、プレビューまたは共有する前にビデオが完全に処理されるまで待つ必要があります。ファイルの処理または生成、電子メール、またはその他の非クリティカルなタスクをバックグラウンドで実行する必要があります。
バックエンド処理での作業方法バックグラウンド処理方法には、タスクキューとワーカープロセスの2つの重要なコンポーネントがあります。アプリケーションは、処理する必要があるタスクを作成しますが、ワーカーが待機し、一度にキューから1つのタスクを取得します。
複数のワーカープロセス(プロセス)を作成して処理を高速化し、大きなタスクを小さなチャンクに分解し、同時に処理できます。ニーズに応じてバックエンド処理を整理および管理できますが、並列処理は簡単な作業ではないことに注意してください。潜在的な人種条件に注意を払い、失敗したタスクを優雅に処理する必要があります。
私たちのテクノロジースタック
BeanStalkDタスクキューを使用してタスクを保存し、Symfony Consoleコンポーネントを使用してワーカープロセスをコンソールコマンドとして実装し、スーパーバイザーを使用してワーカープロセスを管理します。
Homesteadの改善を使用すると、BeanStalkdとスーパーバイザーがインストールされているため、以下のインストール手順をスキップできます。
instalkd
BeanStalkdは、時間のかかるタスクを非同期に実行することにより、トラフィックの高いWebアプリケーションのページブラウジングの遅延を減らすように設計された一般的なインターフェイスを備えた高速ジョブキューです。
利用可能な多くのクライアントライブラリを使用できます。私たちのプロジェクトでは、Pheanstalkを使用しています。
ubuntuまたはdebianサーバーにBeanStalkdをインストールするには、sudo apt-get install beanstalkd
を実行するだけです。公式ダウンロードページをチェックして、他のオペレーティングシステムにBeanStalkdをインストールする方法を学びます。
インストール後、BeanStalkdはデーモンとして始まり、クライアントがジョブを接続して作成(または処理)するのを待っています。
<code>/etc/init.d/beanstalkd Usage: /etc/init.d/beanstalkd {start|stop|force-stop|restart|force-reload|status}</code>実行してPheanStalkを依存関係としてインストールします
。 composer require pda/pheanstalk
JobQueueFactory
ここで、必要に応じて工場サービスを注入して、BeanStalkdキューと対話することができます。キュー名を定数として定義し、仕事をキューに入れたり、ワーカープロセスでキューを監視したりするときにそれを参照します。
<code class="language-php"><?php namespace App\Service; use Pheanstalk\Pheanstalk; class JobQueueFactory { private $host = 'localhost'; private $port = '11300'; const QUEUE_IMAGE_RESIZE = 'resize'; public function createQueue(): Pheanstalk { return new Pheanstalk($this->host, $this->port); } }</code>
スーパーバイザーのインストール
公式ページによると、スーパーバイザーは、ユーザーがUNIXオペレーティングシステムの多くのプロセスを監視および制御できるクライアント/サーバーシステムです。
それを使用して、ワーカープロセスを起動、再起動、拡張、監視します。
を実行して、ubuntu/debianサーバーにスーパーバイザーをインストールします。インストール後、スーパーバイザーはデーモンとしてバックグラウンドで実行されます。スーパーバイザープロセスを制御するには、
を使用してください:
sudo apt-get install supervisor
supervisorctl
スーパーバイザーを使用してプロセスを制御するには、最初に構成ファイルを書き込み、プロセスを制御する方法を説明する必要があります。構成は
<code>$ sudo supervisorctl help default commands (type help <topic>): </topic>===================================== add exit open reload restart start tail avail fg pid remove shutdown status update clear maintail quit reread signal stop version</code>
スーパーバイザーに、生成されたプロセスの名前、実行するコマンドへのパス、自動的に開始および再起動する方法、必要なプロセスの数、出力を記録する場所を監督者に伝えます。監督者の構成の詳細については、こちらをご覧ください。 /etc/supervisor/conf.d/
バックグラウンドで画像をサイズ変更
インフラストラクチャがセットアップされたら(つまり、BeanStalkDとスーパーバイザーがインストールされます)、ギャラリーを作成した後、バックグラウンドで画像を変更するようにアプリケーションを変更できます。これを行うには、
が必要ですImageController
画像サービスのロジックを更新
これまでのところ、最初のリクエストで画像を変更しています。要求された画像ファイルが存在しない場合、動的に作成されます。
変更された画像ファイルが存在する場合にのみ、要求された画像応答を返すようにImageController
を変更します(つまり、画像がサイズ変更されました)。
それが存在しない場合、アプリケーションは、画像がサイズ変更されていることを示す共通のプレースホルダー画像応答を返します。プレースホルダーの画像は、プレースホルダーの画像をキャッシュしたくないため、異なるキャッシュコントロールヘッダーを備えていることに注意してください。
ギャラリーIDとしてペイロードを使用して、GalleryCreatedEvent
という単純なイベントを作成します。ギャラリーが正常に作成された後、このイベントはUploadController
:
<code>/etc/init.d/beanstalkd Usage: /etc/init.d/beanstalkd {start|stop|force-stop|restart|force-reload|status}</code>さらに、
"画像が処理されているを使用してフラッシュメッセージを更新します。"
準備が整う前に、ユーザーが画像で処理を行う必要があることをユーザーが知っていることがわかります。
GalleryEventSubscriber
GalleryCreatedEvent
イベントサブスクライバーを作成します。これは、
<code class="language-php"><?php namespace App\Service; use Pheanstalk\Pheanstalk; class JobQueueFactory { private $host = 'localhost'; private $port = '11300'; const QUEUE_IMAGE_RESIZE = 'resize'; public function createQueue(): Pheanstalk { return new Pheanstalk($this->host, $this->port); } }</code>
これで、ユーザーがギャラリーを正常に作成すると、アプリケーションがギャラリーページをレンダリングしますが、一部の画像のサムネイルはまだ準備ができていないため、表示されません。
サイズのワーカープロセスをコンソールコマンドとして実装
ワーカープロセスは、キューから取られた各ジョブに対して同じジョブを実行する単純なプロセスです。労働者プロセスの実行は、労働者が仕事を続けるか、タイムアウトが発生するまでコールでブロックされます。 $queue->reserve()
シンプルな労働者は次のようになります:
<code>/etc/init.d/beanstalkd Usage: /etc/init.d/beanstalkd {start|stop|force-stop|restart|force-reload|status}</code>
定義されたタイムアウト後またはジョブが処理された後に労働者プロセスが終了することに気付いたかもしれません。ワーカープロセスロジックを無限のループでラップして、無期限にジョブを繰り返すことができますが、これにより、長い非アクティブの後のデータベース接続タイムアウトや展開をより困難にするなどの問題を引き起こす可能性があります。これを防ぐために、単一のタスクが完了した後、ワーカープロセスのライフサイクルが終了します。スーパーバイザーは、新しいプロセスとして労働者プロセスを再開します。
ResizeImageWorkerCommand
./bin/console app:resize-image-worker
労働者コマンドの構造を理解する。この方法で実装された作業プロセスは、Symfony Consoleコマンドとして手動で開始することもできます。
スーパーバイザー構成を作成
ワーカープロセスを自動的に開始する必要があるため、構成にautostart=true
ディレクティブを設定します。ワーカープロセスは、タイムアウトまたはタスク処理が成功した後に再起動する必要があるため、autorestart=true
ディレクティブも設定します。
バックエンド処理の最良の部分は、並列処理の容易さです。 numprocs=5
ディレクティブを設定でき、スーパーバイザーは5つのワーカープロセスインスタンスを生成します。彼らは仕事を待って独立して処理し、システムを簡単に拡大できるようにします。システムが進化するにつれて、プロセス数を増やす必要がある場合があります。複数のプロセスが実行されるため、プロセス名の構造を定義する必要があるため、process_name=%(program_name)s_%(process_num)02d
ディレクティブを設定します。
最後になりましたが、労働者プロセスの出力を保存して、問題が発生したときに分析してデバッグできるようにしたいと考えています。 stderr_logfile
およびstdout_logfile
パスを定義します。
サイズの労働者プロセスの完全なスーパーバイザー構成は次のとおりです。
<code class="language-php"><?php namespace App\Service; use Pheanstalk\Pheanstalk; class JobQueueFactory { private $host = 'localhost'; private $port = '11300'; const QUEUE_IMAGE_RESIZE = 'resize'; public function createQueue(): Pheanstalk { return new Pheanstalk($this->host, $this->port); } }</code>
ディレクトリにある構成ファイルを作成(または更新)した後、次のコマンドを実行して、監督者に再確認して構成を更新するように指示する必要があります。
/etc/supervisor/conf.d/
<code>$ sudo supervisorctl help default commands (type help <topic>): </topic>===================================== add exit open reload restart start tail avail fg pid remove shutdown status update clear maintail quit reread signal stop version</code>
scripts/setup-supervisor.sh
デバイスを更新sudo ./scripts/setup-supervisor.sh
画像サムネイルは最初のリクエストでレンダリングされなくなるため、デバイスをデバイスクラスにロードすると、各画像のレンダリングを明示的にリクエストする必要があります。 デバイスの読み込みが遅くなるのを感じる必要があります。そのため、ユーザーが終了するのを強制するのではなく、バックグラウンドに移動しました。
LoadGalleriesData
ヒントとヒント
<code>[program:resize-worker] process_name=%(program_name)s_%(process_num)02d command=php PATH-TO-YOUR-APP/bin/console app:resize-image-worker autostart=true autorestart=true numprocs=5 stderr_logfile = PATH-TO-YOUR-APP/var/log/resize-worker-stderr.log stdout_logfile = PATH-TO-YOUR-APP/var/log/resize-worker-stdout.log</code>
ワーカープロセスはバックグラウンドで実行されるため、アプリケーションの新しいバージョンを展開しても、最初の再起動前に古いワーカープロセスが実行されます。
私たちの場合、すべての労働者プロセスがすべてのワーカープロセスが更新されることを確認するまで、すべてのワーカープロセスがタスクまたはタイムアウト(5分)を完了するのを待つ必要があります。展開プロセスを作成するときは、これに注意してください!
バックグラウンド処理を使用してページの読み込み時間をスピードアップするためのFAQ(FAQ)ページの読み込みをスピードアップする上で、バックグラウンド処理はどのような役割を果たしますか?バックグラウンド処理は、ページの読み込み速度を改善する上で重要な役割を果たします。これにより、特定のタスクをバックグラウンドで実行できるため、メインスレッドリソースを解放し、ページの読み込みに焦点を当てることができます。これは、ユーザーがこれらのタスクが完了するのを待つ必要がないことを意味し、その結果、より速くてスムーズなブラウジングエクスペリエンスが得られます。
Symfonyプロセスコンポーネントは、子プロセスでコマンドを実行できる強力なツールです。システムコマンドを実行し、その出力を管理するためのシンプルなオブジェクト指向APIを提供します。これは、メインスレッドをブロックせずに別々のプロセスでタスクを実行できるため、バックグラウンド処理に特に役立ちます。
バックエンド処理の一般的なユースケースは何ですか?
バックグラウンド処理は、通常、メインスレッドに関係なくタスクを実行できる状況で使用されます。これには、電子メールの送信、写真の処理、複雑な計算の実行などのタスクが含まれます。これらのタスクをバックグラウンドで実行することにより、アプリケーションのパフォーマンスを改善し、より良いユーザーエクスペリエンスを提供できます。
PHPでバックグラウンドプロセスを実行する方法は?
関数を使用して、PHPでバックグラウンドプロセスを実行できます。この関数を使用すると、子のプロセスでコマンドを実行し、コマンドが完了するのを待たずに残りのスクリプトを実行し続けることができます。簡単な例を次に示します:この例では、
はバックグラウンドで実行するスクリプトです。 exec()
Symfony Messengerコンポーネントとは何ですか? exec("php background_task.php > /dev/null &");
Symfony Messengerコンポーネントは、メッセージを非同期的にハンドラーに発送するために使用できるメッセージバスシステムです。これは、メッセージを処理するのを待たずにバスにメッセージを送信し、スクリプトの実行を続けることができることを意味します。これは、メッセージの処理を別のプロセスで実行できるため、バックグラウンド処理の形式です。 background_task.php
バックエンド処理を使用してウェブサイトのパフォーマンスを向上させる方法は?
タスクを背景にアンロードすることにより、メインスレッドリソースを解放して、ページのロードに集中できます。これにより、特に時間のかかるまたはリソース集約型のタスクがある場合は、ウェブサイトのパフォーマンスを大幅に改善できます。バックグラウンドにオフロードできる一般的なタスクには、電子メールの送信、写真の処理、複雑な計算の実行などがあります。
バックエンド処理の潜在的な課題と、これらの課題を緩和する方法は何ですか?
バックエンド処理の主な課題の1つは、タスクが正しい順序で成功し、完了することを保証することです。これは、タスクキューを使用して軽減できます。これにより、タスクが追加された順序で実行されることが保証されます。もう1つの課題は、バックグラウンドタスクのエラーを処理することです。これは、堅牢なエラー処理とロギングメカニズムを実装することで解決できます。
バックグラウンド処理は、他のパフォーマンス最適化手法と組み合わせて使用できますか?
はい、バックグラウンド処理は、他のパフォーマンス最適化手法と組み合わせて使用できます。たとえば、キャッシュを使用して高価な操作の結果を保存し、バックグラウンド処理を使用して定期的にキャッシュを更新できます。これにより、アプリケーションを遅くすることなく最新のデータを提供できます。
バックグラウンドタスクの進行を監視する方法は?
さまざまなツールとテクニックを使用して、バックエンドタスクの進行を監視できます。一般的なアプローチは、ロギングを使用して各タスクのステータスを記録することです。また、Symfonyのメッセンジャーコンポーネントなどのツールを使用することもできます。このツールは、バックエンドタスクの監視とデバッグのサポートを組み込んでいます。
バックグラウンド処理を使用する際にセキュリティ上の注意事項はありますか?
はい、バックグラウンド処理を使用する場合、いくつかのセキュリティ上の注意事項があります。たとえば、バックグラウンドタスクが機密情報を漏らし、注射攻撃の対象とならないことを確認する必要があります。また、安全な環境でタスクが実行され、仕事をするために必要な以上のアクセス許可がないことを確認する必要があります。
以上がバックグラウンド処理を使用して、ページの読み込み時間をスピードアップしますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。