ブロックキャッシュとssiの主題は、Habréで何度も取り上げられました。 以下に、ブロックキャッシングを使用した別の実装と、これらの原則を使用したフレームワークのソースコードを紹介し
ます 。 そして、それがどのように機能するか-以下をお読みください。
MVCアプローチについて少し
このフレームワークは、「できるだけシンプルに」という原則に基づいています。 MVCパターンを使用してHTML出力のビルドの進行状況を見ると、プッシュとポーリングの2つのアプローチがあります。
最初のアプローチでは、フロントコントローラーは、モデルを実行する多数のコントローラーを呼び出し、Viewを使用して多数のブロックを形成します。これらのブロックは、Viewの前面で組み立てられます。
2番目のアプローチ-1つのViewテンプレートが処理されます。このテンプレートでは、対応するコントローラーを呼び出すコールバック関数があり、それらがHTMLブロックを形成します。 たとえば、このアプローチはZendFrameworkで使用されます。
この場合、最初のアプローチが使用されましたが、PHPスクリプトはアセンブリに関与せず、ssi(サーバー側インクルード)を介して直接WEBサーバー(nginx)に関与します。 SSIディレクティブが使用されます:includeおよびecho。 これにより、次のことが可能になります。
- コントローラのコードを簡素化し、PHPスクリプトの負荷を減らします
- 一度に複数のスクリプトを実行する
- WEBサーバーとバックエンドの間で転送されるバイトストリームを減らす
- バックエンドスクリプトを取得せずにサーバーツールを使用してキャッシュブロックを作成する(PHP)
フレームワーク自体(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が使用されている場合、コンテンツの圧縮はデフォルトで処理されます。
次のオプションが可能です。
- 圧縮を使用しないで、Memcached :: OPT_COMPRESSION = falseパラメーターを設定します。
- gzip / deflateをdefault_typeの場所に設定します。 ただし、64バイトまでの小さなボリュームでは、圧縮は実行されません。
- ngx_memcache_moduleにパッチを適用します。 memcacheから受け入れられたパラメーターの値に応じて、ヘッダーテキスト/ htmlまたはgzip / deflateを指定します(パッチ10行)。
謝辞
まず第一に、イゴール・シソエフ
sysoev.ruに感謝します。これがなければ、このコードと多くの高性能Runetプロジェクトはなかったでしょう。
また、ロケーションをフロントコントローラーとして使用するというアイデアを提供してくれたKonstantin Baryshnikov(fixxxer)にも感謝します。
Alexey Rybak(漁師)の彼の
電撃戦に感謝します。これは私のプロジェクト、特にこのフレームワークで3年以上も積極的に使用しています。
さて、php-fpmの作者であるAndrei Nigmatulin氏(今夜)は、彼のプロジェクトでrunetのハイロードに大きく貢献しました。
PS。 何かがあなたのために始まっていない場合、それは問題ではありません。 それは別の時に判明します、主なことは心を失うことではありません。 それまでの間、一休みしてHabrを読んでください。