ステップ21:パフォーマンス向上のためにキャッシュする

パフォーマンス向上のためにキャッシュする

パフォーマンスに関する問題はよく訪れます。典型的な例だと,データベースのインデックスの欠如や,ページあたりの大量のSQL発行などです。空のデータベースでは発生しませんが,トラフィックが増えデータが増加すると,発生する可能性があります。

HTTPキャッシュヘッダーの追加

HTTPキャッシュを利用することは,ほとんど労力をかけずにエンドユーザーへのパフォーマンス向上を最大限に引き出せるすぐれた戦略です。本番環境でリバースプロキシキャッシュを追加して有効にし,CDNを使用してキャッシュすることで,さらに優れたパフォーマンスを実現します。

ホームページを1時間キャッシュしてみましょう:

patch_file
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
——/ src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -33,9 +33,12 @@类ConferenceController扩展了AbstractController#[Route('/', name: 'homepage')] public function index(ConferenceRepository $ ConferenceRepository): Response {-返回新的响应($this->twig->render('conference/index.html. php ')。嫩枝”,(+ $response = new response ($this->twig->render('会议/index.html. html ');嫩枝”,('会议' => $conferenceRepository->findAll(),]);+ $响应- > setSharedMaxAge (3600);++返回$响应;} #(路线(“/会议/{蛞蝓}”,名字:“会议”))

setSharedMaxAge ()メソッドはリバースプロキシのキャッシュ有効期限を設定します。ブラウザのキャッシュを制御するにはsetMaxAge ()メソッドを使用します。時間は秒単位で設定します。(1時間 = 60分 = 3,600秒)

カンファレンスページのキャッシュはより動的なため,難しいです。誰でもいつでもコメントを追加できますが,誰もが1時間待つことを望んでいません。そのような場合は,HTTP验证を利用します。

欧宝娱乐app下载地址Symfony HTTP缓存内核をアクティベートする

欧宝娱乐app下载地址Symfony HTTPリバースプロキシを有効化して,HTTPキャッシュをテストします:

patch_file
1 2 3 4 5 6 7 8
——/ config /包/ framework.yaml+ + + b / config /包/ framework.yaml@@ -15,3 +15,5 @@框架:#fragments: true php_errors: log: true++ http_cache:真

本格的なHTTPリバースプロキシであることに加え,欧宝娱乐app下载地址Symfony HTTPリバースプロキシ(HttpCacheクラスを介します)はHTTPヘッダーとして有用なデバッグ情報を追加します。これは,設定したキャッシュヘッダーの検証に大いに役立ちます。

ホームページ上で確認する:

1
$ curl -s -I -X GET https://127.0.0.1:8000/
1 2 3 4 5 6 7 8 9 10 11
HTTP / 200年龄:0cache - control:公共,s-maxage = 3600内容类型:text / html;charset=UTF-8 date: Mon, Oct 28 2019 08:11:57 GMT x-content-digest: en63cef7045fe418859d73668c2703fb1324fcc0d35b21d95369a9ed1aca48e73e x-debug-token: 9eb25a x-debug-token-link: https://127.0.0.1:8000/_profiler/9eb25a x-robots-tag: noindexx-欧宝娱乐app下载地址symfony-cache: GET /: miss, store内容长度:50978

最初のリクエストに対して,キャッシュサーバーはキャッシュが小姐で,レスポンスをキャッシュするために商店を実行したことを返します。cache - controlヘッダーをチェックして,設定されたキャッシュ方法を確認しましょう。

以降のリクエストでは,レスポンスがキャッシュされています。(年龄も更新されています)。

1 2 3 4 5 6 7 8 9 10 11
HTTP / 200年龄:143cache - control:公共,s-maxage = 3600内容类型:text / html;charset=UTF-8 date: Mon, Oct 28 2019 08:11:57 GMT x-content-digest: en63cef7045fe418859d73668c2703fb1324fcc0d35b21d95369a9ed1aca48e73e x-debug-token: 9eb25a x-debug-token-link: https://127.0.0.1:8000/_profiler/9eb25a x-robots-tag: noindexx-欧宝娱乐app下载地址symfony-cache: GET /: fresh内容长度:50978

ESIを使用してSQLリクエストを回避する

TwigEventSubscriberリスナーは,树枝にグローバル変数と一緒に全てのカンファレンスオブジェクトをWebサイトの各ページごとに注入します。それはおそらく,最適化のための大きな狙いどころとなります。

毎日新しいデータを追加するわけではないので,このコードはデータベースから毎回全く同じデータを取得することになります。

欧宝娱乐app下载地址Symfony缓存を使用してカンファレンスの名前とスラッグをキャッシュすることもできますが,可能であればHTTPキャッシュインフラストラクチャへ依存するのが望ましいです。

ページの一部をキャッシュしたい場合は,サブリクエストを作成して,現在のHTTPリクエストから別にします。应急服务国际公司はこのユースケースに最適です。应急服务国际公司はHTTPリクエストの結果を別のリクエストに埋め込むことができます。

カンファレンス情報のHTMLの一部のみを返すコントローラーを作成する:

patch_file
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
——/ src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -41,6 +41,14 @@类ConferenceController扩展了AbstractController返回$响应;}+ #[Route('/conference_header', name: 'conference_header')]+ public function conferenceHeader(ConferenceRepository $ ConferenceRepository): Response+ {+返回新的响应($this->twig->render('conference/header.html. ')嫩枝”,(+ 'conferences' => $conferenceRepository->findAll(),+)));+}+#[Route('/conference/{slug}', name: 'conference')] public function show(Request $ Request, conference $conference, CommentRepository $ CommentRepository, string $photoDir): Response {

対応するテンプレートを作成する:

模板/会议/ header.html.twig
1 2 3 4 5
< ul >{%会议会议%}<李> < a href = "{{路径(“会议”,{鼻涕虫:conference.slug})}}" >{{会议}}< / > < /李>{%endfor%}< / ul >

/ conference_headerにアクセスし,全てが正常に動作しているか確認しましょう。

トリックを明らかにする時が来ました!先ほど作成した控制器で呼び出している树枝テンプレートを更新しましょう。

patch_file
12 3 4 5 6 7 8 9 10 11 12 13 14 15
——/模板/ base.html.twig+ + + b /模板/ base.html.twig@@ -8,11 +8,7 @@<身体> <标题> < h1 > < a href = "{{路径(主页)}}" >留言板< / > < / h1 >——< ul >- {% for conference in conferences %}- 
  • - {% endfor %}- < / ul >+ {{render(path('conference_header'))}}
    {% block body %}{% endblock %}
  • それだけです。ページを更新しても引き続き同じものが表示されます。

    ちなみに

    欧宝娱乐app下载地址Symfonyプロファイラの“请求/响应”を開き,メインリクエストとサブリクエストの詳細を確認します。

    これで,ブラウザでページにアクセスするたびに,ヘッダー用とメインページ用の2つのHTTPリクエストが実行されます。パフォーマンスが低下しました。おめでとう!

    現在,カンファレンスヘッダーのHTTPコールは欧宝娱乐app下载地址Symfonyによって内部的に行われています。よってHTTPラウンドトリップは関係ありません。これはHTTPキャッシュヘッダーを使う方法がないことも意味します。

    ESIを使ってリアルなHTTPコールへ変換しましょう。

    まずは,ESIサポートを有効化します:

    patch_file
    1 2 3 4 5 6 7 8 9 10 11
    ——/ config /包/ framework.yaml+ + + b / config /包/ framework.yaml@@ -11,7 +11,7 @@框架:cookie_samesite: lax- # esi:真的+ esi:真#fragments: true php_errors: log: true

    つぎに,渲染のかわりにrender_esiを使用します:

    patch_file
    1 2 3 4 5 6 7 8 9 10 11
    ——/模板/ base.html.twig+ + + b /模板/ base.html.twig@@ -10,7 +10,7 @@<身体> <标题> < h1 > < a href = "{{路径(主页)}}" >留言板< / > < / h1 >- {{render(path('conference_header'))}}+ {{render_esi(path('conference_header'))}}
    {% block body %}{% endblock %}

    欧宝娱乐app下载地址SymfonyがESIの処理方法を知っているリバースプロキシを検出した場合,自動的にESIサポートを有効にします(そうでない場合,フォールバックしてサブリクエストを同期的にレンダリングします)。

    欧宝娱乐app下载地址SymfonyリバースプロキシはESIをサポートしているか,ログを確認しましょう(最初にキャッシュを削除します。次節の”キャッシュ削除“を参照ください)。

    1
    $ curl -s -I -X GET https://127.0.0.1:8000/
    12 3 4 5 6 7 8 9 10 11 12
    HTTP / 200年龄:0缓存控制:必须重新验证,无缓存,私有内容类型:text / html;x-content-digest: en4dd846a34dcd757eb9fd277f43220effd28c00e4117bed41af7f85700eb07f2c x-debug-token: 719a83 x-debug-token-link: https://127.0.0.1:8000/_profiler/719a83x-robots-tag: noindexx-欧宝娱乐app下载地址symfony-cache: GET /: miss;GET /conference_header: miss content-length: 50978

    数回再読み込みします。/レスポンスはキャッシュされていますが/ conference_headerはキャッシュされていません。ページ全体をキャッシュしながら一部を動的に保つことを成し遂げました!

    しかしながら,これは私たちが望むものではありません。他のページとは別に,ヘッダーページを1時間キャッシュしましょう:

    patch_file
    12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    ——/ src /控制器/ ConferenceController.php+ + + b / src /控制器/ ConferenceController.php@@ -44,9 +44,12 @@类ConferenceController扩展了AbstractController#[Route('/conference_header', name: 'conference_header')] public function ConferenceRepository (ConferenceRepository $ ConferenceRepository): Response {-返回新的响应($this->twig->render('conference/header.html。嫩枝”,(+ $response = new response ($this->twig->render('会议/header.html. html ');嫩枝”,('会议' => $conferenceRepository->findAll(),]);+ $响应- > setSharedMaxAge (3600);++返回$响应;} #(路线(“/会议/{蛞蝓}”,名字:“会议”))

    キャッシュは両方のリクエストで有効になりました:

    1
    $ curl -s -I -X GET https://127.0.0.1:8000/
    1 2 3 4 5 6 7 8 9 10 11
    HTTP / 200年龄:613cache - control:公共,s-maxage = 3600内容类型:text / html;x-content-digest: en15216b0803c7851d3d07071473c9f6a3a3360c6a83ccb0e550b35d5bc484bbd2 x-debug-token: cfb0e9 x-debug-token-link: https://127.0.0.1:8000/_profiler/cfb0e9 x-robots-tag: noindexx-欧宝娱乐app下载地址symfony-cache: GET /: fresh;GET / conference_header:新鲜内容长度:50978

    x-欧宝娱乐app下载地址symfony-cacheヘッダーは2つの要素を含みます。メインの/リクエストとサブリクエスト(ESIのconference_header)です。両方ともキャッシュ(新鲜的)にあります。

    キャッシュ設定は,メインページやESIとは異なる設定を行うこともできます。“关于”ページは,キャッシュに1週間保存し,1時間ごとにヘッダーを更新することもできます。

    不要になったリスナーを削除します:

    1
    rm src / EventSubscriber / TwigEventSubscriber.php美元

    テストのためのHTTPキャッシュ削除

    ブラウザでのテスト,もしくは自動化したテストには,キャッシュされている箇所は多少難しくなります。

    var /缓存/ dev / http_cacheディレクトリ内を全て消すことで,全てのHTTPキャッシュを削除することができます。

    1
    $ rm -rf var/cache/dev/http_cache/

    一部のURLのみキャッシュを無効にする場合や,ファンクショナルテストでキャッシュを無効化したい場合,前述のやり方ではうまく機能しません。小さな管理画面を追加して,いくつかのURLをキャッシュ無効にしてみましょう。

    patch_file
    12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
    ——/ src /控制器/ AdminController.php+ + + b / src /控制器/ AdminController.php@@ -6,8 +6,10 @@ use App\Entity\Comment;使用App \ \ CommentMessage消息;使用原则\ ORM \ EntityManagerInterface;控制器使欧宝娱乐app下载地址用Symfony \包\ FrameworkBundle \ \ AbstractController;+使用Sy欧宝娱乐app下载地址mfony \包\ FrameworkBundle \ HttpCache \ HttpCache;使用Sy欧宝娱乐app下载地址mfony \ HttpFoundation \ \组件请求;组件使用欧宝娱乐app下载地址Symfony \ \ HttpFoundation \反应;+使用Sy欧宝娱乐app下载地址mfony \ \ HttpKernel \ KernelInterface组件;使用Sy欧宝娱乐app下载地址mfony \组件\ \ MessageBusInterface使者;使用Sy欧宝娱乐app下载地址mfony \组件\路由\注释\路线;使用Sy欧宝娱乐app下载地址mfony \工作流组件\ \注册;@@ -52,4 +54,17 @@ class AdminController扩展了AbstractController'评论' => $评论,]);}++ #(路线(' / admin / http缓存/ {< uri。* >}’,方法:[‘清洗’]))+ public function purgeHttpCache(KernelInterface $kernel, Request $ Request, string $uri): Response+ {+ if ('prod' === $kernel->getEnvironment()) {+返回新的响应('KO', 400);+}++ $store = (new class($kernel) extends HttpCache {})->getStore();+ $存储- >清除(请求- > getSchemeAndHttpHost()。‘/’。美元uri);++返回新的响应('完成');+}}

    新しいコントローラーは清洗HTTPメソッドに制限されています。このメソッドはHTTPの標準メソッドではありませんが,キャッシュを無効にするために広く使われています。

    デフォルトでは,ルーティングのパラメーターに/を含めることはできません。最後のルーティングパラメーターにuriなどで(. *)を設定することで,この制限をオーバーライドすることができます。

    HttpCacheインスタンスを取得する方法も少し奇妙に見えます。“実際の”クラスにアクセスできないため,匿名クラスを使います。HttpCacheインスタンスはカーネルをラップしており,これは本来であればキャッシュレイヤーを認識しません。

    旋度での呼び出しを介して,ホームページとカンファレンスヘッダーを無効にします:

    1 2
    $ curl -I -X清除-u admin:admin欧宝娱乐app下载地址symfony var:出口SYMFONY_PROJECT_DEFAULT_ROUTE_URL/admin/http-cache/ $ curl -I欧宝娱乐app下载地址symfony var:出口SYMFONY_PROJECT_DEFAULT_ROUTE_URL/管理/ http缓存/ conference_header

    欧宝娱乐app下载地址var:出口欧宝娱乐app下载地址SYMFONY_PROJECT_DEFAULT_ROUTE_URLサブコマンドはローカルWebサーバーの現在のURLを返します。

    注釈

    コントローラーはコードで参照されることがないため,ルート名がありません。

    プレフィクスで同様のルーティングをグループ化する

    管理画面コントローラーには同じ/管理プレフィクスを持ったルートがあります。全てのルートで繰り返さず,クラス自体にプレフィクスの設定を行ってルートをリファクタリングします。

    patch_file
    12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
    ——/ src /控制器/ AdminController.php+ + + b / src /控制器/ AdminController.php@@ -15,6 +15,7 @@ use 欧宝娱乐app下载地址Symfony\Component\Routing\Annotation\Route;使用Sy欧宝娱乐app下载地址mfony \工作流组件\ \注册;用树枝\环境;+ #(路线(' / admin '))class AdminController extends AbstractController {private $twig;@@ -28,7 +29,7 @@类AdminController扩展了AbstractController$ this - >总线= $总线;}- #[Route('/admin/comment/review/{id}', name: 'review_comment')]+ #(路线(' /评论/审查/ {id}’,名字:“review_comment”))public function reviewComment(Request $ Request, Comment $ Comment, Registry $ Registry): Response {$ Request ->query->get('拒绝');@@ -55,7 +56,7 @@类AdminController扩展了AbstractController]);}- #(路线(' / admin / http缓存/ {< uri。* >}’,方法:[‘清洗’]))+ #【路线(' / http缓存/ {< uri。* >}’,方法:[‘清洗’]))public function purgeHttpCache(KernelInterface $kernel, Request $ Request, string $uri): Response {if ('prod' === $kernel-> getenenvironment ()) {

    CPU /メモリ集中操作をキャッシュする

    CPUやメモリーを集中的に使用するアルゴリズムはこのWebサイト上にはありません。ローカルキャッシュについて説明するために,現在作業中のステップ(正確には,現在のGitコミットにつけられたGitタグ名)を表示するコマンドを作りましょう。

    欧宝娱乐app下载地址Symfony过程コンポーネントはコマンドを実行して結果を取得できます(標準出力およびエラー出力)。インストールしてみましょう。

    1
    $ 欧宝娱乐app下载地址symfony composer请求进程

    コマンドを実装します:

    src /命令/ StepInfoCommand.php
    12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    名称空间App \命令;使用欧宝娱乐app下载地址Symfony \命令\ \组件\控制台命令;使用欧宝娱乐app下载地址Symfony \ \控制台输入\ \ InputInterface组件;使用欧宝娱乐app下载地址Symfony \ \输出控制台\ \ OutputInterface组件;使用欧宝娱乐app下载地址Symfony \组件\ \过程;StepInfoCommand扩展命令{受保护的静态defaultName美元=应用步骤:信息的;受保护的函数执行(InputInterface输入美元,OutputInterface输出美元):int{美元的过程=过程([“git”,“标签”,“- l”,”——点“,“头”]);美元的过程->mustRun();输出美元->(美元的过程->getOutput());返回0;}}

    注釈

    :命令を使ってコマンドを作成することもできます。

    1
    $ 欧宝娱乐app下载地址symfony console make:command app:step:info

    コマンドの出力を数分間キャッシュするにはどうすればよいでしょうか吗?欧宝娱乐app下载地址Symfony缓存を利用します:

    1
    $ 欧宝娱乐app下载地址symfony composer请求缓存

    キャッシュのロジックでコードをラップします:

    patch_file
    12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
    ——/ src /命令/ StepInfoCommand.php+ + + b / src /命令/ StepInfoCommand.php@@ -6,16 +6,31 @@ use 欧宝娱乐app下载地址Symfony\Component\Console\Command\Command;使用Sy欧宝娱乐app下载地址mfony \ \控制台输入\ \ InputInterface组件;使用Sy欧宝娱乐app下载地址mfony \组件\ \控制台输出\ OutputInterface;使用Sy欧宝娱乐app下载地址mfony \组件\ \过程;+使用Sy欧宝娱乐app下载地址mfony \ \缓存\ CacheInterface合同;class stepinfo extends Command {protected static $defaultName = 'app:step:info';+私人美元缓存;++ public function __construct(CacheInterface $cache)+ {+ $this->cache = $cache;++父:__construct ();+}+protected function execute(InputInterface $input, OutputInterface $output): int {- $ = new过程([“git”、“标签”,“- l”,“——点”,“头”));-过程- > mustRun ();-输出- >写美元(美元过程- > getOutput ());+ $step = $this->cache->get('app. ')Current_step ',函数($item) {+ $ = new过程([“git”、“标签”,“- l”,“——点”,“头”));+ $流程- > mustRun ();+ $ item - > expiresAfter (30);++返回流程- > getOutput ();+});+输出美元- > writeln($步骤);返回0;}

    プロセスは現在,app.current_stepがキャッシュされていない時のみ呼び出せます。

    パフォーマンスをプロファイリングして比較する

    盲目的にキャッシュを追加しないでください。キャッシュを追加することで複雑さが増えるということを覚えておいてください。推測で速度を判断するのは大変危険で,キャッシュを使うことでアプリケーションを遅くする状況に陥る可能性があります。

    黑焰のようなプロファイリングツールで,キャッシュを追加した場合の影響を常に計測しましょう。

    黑焰を使用したデプロイ前のコードをテストする方法の詳細に関しては,“パフォーマンス”のステップを参照してください。

    本番環境でのリバースプロキシキャッシュを設定する

    本番環境では欧宝娱乐app下载地址Symfonyリバースプロキシを使わないでください。インフラストラクチャ上で清漆のようなリバースプロキシを利用するか商用のCDNを利用してください。

    欧宝娱乐app欧宝体育应用最新版app下载下载地址SymfonyCloudに清漆を追加します:

    patch_file
    12 3 4 5 6 7 8 9 10 11 12 13 14 15
    ——/ .sy欧宝娱乐app下载地址mfony / services.yaml+ + + b欧宝娱乐app下载地址 / .symfony / services.yaml@@ -2,3 +2,12 @@ db:类型:postgresql:13磁盘:1024大小:S++漆:+类型:清漆:6.0+关系:+应用程序:“应用:http”+配置:+ vcl:包括+类型:字符串+路径:config.vcl

    ルーティングのメインエントリーポイントとして清漆を利用します:

    patch_file
    1 2 3 4 5 6
    ——/ .sy欧宝娱乐app下载地址mfony / routes.yaml+ + + b欧宝娱乐app下载地址 / .symfony / routes.yaml@@ 1,2 +1,2 @@——“https://{} /”:{类型:上游,上游:“应用:http”}+"https://{all}/": {type: upstream, upstream: "varnish:http", cache: {enabled: false}}“http://{} / ":{类型:重定向,:“https://{} /”}

    最後に,清漆の設定ファイルconfig.vclを作成します:

    .欧宝娱乐app下载地址symfony / config.vcl
    1 2 3
    vcl_recv{req.backend_hint=应用程序后端();}

    清漆でESIサポートを有効にする

    清漆上でESIサポートを有効にするにはリクエストごとに明示的に設定する必要があります。欧宝娱乐app下载地址Symfonyは標準のSurrogate-CapabilityおよびSurrogate-Controlヘッダーを使ってESIサポートを要求します。

    .欧宝娱乐app下载地址symfony / config.vcl
    1 2 3 4 5 6 7 8 9 10 11
    vcl_recv{req.backend_hint=应用程序后端();req.http.Surrogate-Capability=“abc = ESI / 1.0”;}vcl_backend_response{如果(beresp.http.Surrogate-Control~“ESI / 1.0”){设置beresp.http.Surrogate-Control;beresp.do_esi=真正的;}}

    清漆キャッシュを削除する

    本番環境でキャッシュを無効化することは,緊急時か以外のブランチをのぞいて,必要になることはないでしょう。キャッシュを頻繁に削除する必要があるのであれば,(TTLを下げるか有効期限の代わりにバリデーションを使用して)キャッシュの設定を微調整する必要があることを意味します。

    ともあれ,キャッシュを無効化するための清漆の設定を見てみましょう。

    patch_file
    12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
    ——/ .sy欧宝娱乐app下载地址mfony / config.vcl+ + + b欧宝娱乐app下载地址 / .symfony / config.vcl@@ -1,6 +1,13 @@子vcl_recv{设置req。后端_hint = application.backend(); set req.http.Surrogate-Capability = "abc=ESI/1.0";++如果(点播。方法==“清除”){+如果(req.http。x-purge-token != "PURGE_NOW") {+返回(synth (405));+}+返回(清洗);+}} sub vcl_backend_response {

    実際には,清漆文档に記載されているように,IPアドレスによって制限することになるでしょう。

    いくつかのURLを削除します:

    1 2
    $ curl -X清除-H“x-purge-token PURGE_NOW”欧宝娱乐app下载地址symfony env: url——第一$ curl -X清除-H“x-purge-token PURGE_NOW”欧宝娱乐app下载地址symfony env: url——第一conference_header

    env: urlはで返されるURL/で終わっているため,少し奇妙に感じるかもしれません。


    • «前ステップ20:管理者へメールを送信する
    • 下一个”ステップ22:Webpackでユーザーインタフェースにスタイリングする

    这项工作,包括代码样本,是在一个Creative Commons BY-NC-SA 4.0许可证。