ブロックキャッシングによるパフォーマンスの改善

ブロックキャッシュとssiの主題は、Habréで何度も取り上げられました。 以下に、ブロックキャッシングを使用した別の実装と、これらの原則を使用したフレームワークのソースコードを紹介します 。 そして、それがどのように機能するか-以下をお読みください。
ブロックキャッシュスキーム

MVCアプローチについて少し


このフレームワークは、「できるだけシンプルに」という原則に基づいています。 MVCパターンを使用してHTML出力のビルドの進行状況を見ると、プッシュとポーリングの2つのアプローチがあります。

最初のアプローチでは、フロントコントローラーは、モデルを実行する多数のコントローラーを呼び出し、Viewを使用して多数のブロックを形成します。これらのブロックは、Viewの前面で組み立てられます。

2番目のアプローチ-1つのViewテンプレートが処理されます。このテンプレートでは、対応するコントローラーを呼び出すコールバック関数があり、それらがHTMLブロックを形成します。 たとえば、このアプローチはZendFrameworkで使用されます。

この場合、最初のアプローチが使用されましたが、PHPスクリプトはアセンブリに関与せず、ssi(サーバー側インクルード)を介して直接WEBサーバー(nginx)に関与します。 SSIディレクティブが使用されます:includeおよびecho。 これにより、次のことが可能になります。フレームワーク自体(ZFの4倍のパフォーマンスであるため、すぐに名前を付けました)はnginxと密接に統合されており、nginx configの一部はプロジェクトの直接の部分です。 ( 誰かがそれを好まない...味と色のコンパニオンはありません )このため、ディレクティブinclude /path/to/project/conf/local.nginx.confをnginx.confに含める必要があります

仕組みについて少し説明します


WEBの従来のMVCスキーム-各コントローラーは、URLの特定の部分に関連付けられています。 URL部分はアクションにバインドされ、部分はパラメーターにバインドされます。

上記のように、nginxはコントローラー機能の一部を引き継ぎます。 URL解決は、ロケーションディレクティブを使用して行われます。 コントローラー(ページ)、アクション(アクション)、およびパラメーターによってすべてを解決できます。 ただし、同じZFよりも柔軟性があります。 locationディレクティブにpageパラメーターを含めるようにしてください。その値によって適切なクラスが選択されます。 彼らは適切なブロックコントローラーを呼び出したと信じています。
設定の一部の例: set $app_script run_app.php;
. . .
location ~ ^/catalog/(\w+)/? {
fastcgi_pass localhost:9000;
fastcgi_param page catalog;
fastcgi_param cat_name $1;
include fastcgi_params;
}
set $app_script run_app.php;
. . .
location ~ ^/catalog/(\w+)/? {
fastcgi_pass localhost:9000;
fastcgi_param page catalog;
fastcgi_param cat_name $1;
include fastcgi_params;
}

この例は、fcgiパラメーターpage = catalogが渡され、cat_nameがURLの最後の部分と等しいことを示しています。 PHPスクリプトはrun_app.phpという名前になります。run_app.phpは、ページディレクトリからcatalogPageクラス(ロケーションページ/ catalogPage.php)をインスタンス化し、run()メソッドを実行します。 url / catalog / bmvの環境変数cat_nameでは、値はbmvになります。

SSIとの連携方法


場所によるタキシングは、外部と内部の2つの部分に分かれています。 外部-これは、書き換えを使用した適切なssiテンプレートの選択です。 内部はプライベートコントローラの場所です。

サンプルSSIテンプレート(index.tpl):
< script >
<!--# include virtual = "$js" -->
</ script >
< table >
< tr >
< td > left block
<!--#include virtual="$top" -->
</ td >
content
< td valign ="top" > content block < br >
<!--#include virtual="$int" -->
</ td >
</ tr >
</ table >

* This source code was highlighted with Source Code Highlighter .

設定の一部の例:
set $ int "/ssi$request_uri" ;
set $top "/ssi/top10$request_uri" ;
. . .
location /catalog {
set $js "js/catalog.js" ;
rewrite ^(.*)$ /index.tpl;
}

location /ssi {
internal ; # ,
location /ssi/catalog/(\w+)/? {
fastcgi_pass localhost:9000;
fastcgi_param page catalog;
fastcgi_param cat_name $1;
fastcgi_param ssi 1;
include fastcgi_params;
}

location /ssi/top10/(\w+)/? {
fastcgi_pass localhost:9000;
fastcgi_param page top10;
fastcgi_param top_name $1;
fastcgi_param ssi 1;
include fastcgi_params;
}
}

* This source code was highlighted with Source Code Highlighter .


最初の場所は、変数$ js = js / catalog.jsでindex.tplに書き換えられます
index.tplテンプレートでは、必要なjsスクリプトが置き換えられ、#include ssiディレクティブを使用して必要なブロックが呼び出されます。 この例では、内部の場所/ ssi / catalog /が機能し、PHP run_appスクリプトを呼び出します。このスクリプトは、catalogPageクラスをインスタンス化し、run()メソッドを実行し、同様にtop10ブロックを実行します。

memcachedの仕組み


写真を見てください。 ここではすべてが明確です。場所/ top10でアドレス指定する代わりに、場所/ mcで直接memekeshにアクセスします。 キャッシュが無効(空)の場合、ngx_memcache_moduleモジュールは404エラーを返します。 404エラーを処理し、指定された場所mcbへの内部リダイレクトを行います。 PHPスクリプトはHTMLを作成し、キャッシュに配置する必要があります。 これについてあまり心配する必要はありません。クラスでパラメーターを指定すると、基本クラスで発生します。
protected $ _Cached = true;
public $ CachingKey = '/ top_ $ top_name';

設定例:
location ~ ^/catalog/(\w+) {
rewrite ^(.*)$ /index.tpl;
set $memkey "top_$1" ;
}

location /mc {
set $memcached_key $memkey;
default_type text/html;
memcached_pass localhost:11211;
error_page 404 @mcb; // ,
//
}

location @mcb {
fastcgi_pass localhost:9000;
fastcgi_param page block;
fastcgi_param blocknum $blocknum;
include fastcgi_params;
}

* This source code was highlighted with Source Code Highlighter .


キャッシング機能:
php_memcache拡張機能を使用する場合、機能はありません。

ライブラリlibmemcachedおよびphp_memcachedが使用されている場合、コンテンツの圧縮はデフォルトで処理されます。
次のオプションが可能です。

謝辞


まず第一に、イゴール・シソエフsysoev.ruに感謝します。これがなければ、このコードと多くの高性能Runetプロジェクトはなかったでしょう。
また、ロケーションをフロントコントローラーとして使用するというアイデアを提供してくれたKonstantin Baryshnikov(fixxxer)にも感謝します。
Alexey Rybak(漁師)の彼の電撃戦に感謝します。これは私のプロジェクト、特にこのフレームワークで3年以上も積極的に使用しています。
さて、php-fpmの作者であるAndrei Nigmatulin氏(今夜)は、彼のプロジェクトでrunetのハイロードに大きく貢献しました。

PS。 何かがあなたのために始まっていない場合、それは問題ではありません。 それは別の時に判明します、主なことは心を失うことではありません。 それまでの間、一休みしてHabrを読んでください。

Source: https://habr.com/ru/post/J109050/


All Articles