自然界では、多くの生き物が生と死のテストに直面し、多くの場合、最もよく知られているヤモリである驚くべき応答を行います、決定的な瞬間は、むしろ座って死を待つよりも、尾のように悪くない、生きる希望と引き換えに自傷を通して。インターネットプロジェクトは、また、多くの生と死のテストは、次のようなものがあります:アクセスサージ、データベースのダウンタイムなど、この時点で、合理的な劣化プログラムがない場合は、終了は行き止まりにバインドされています。
どのような問題であっても、いったん実際の状況から切り離されてしまうと、議論の意義が失われてしまいます。続行するには、それはケースの背景を導入する価値があるかもしれません:PHPのウェブサイトは、読み取りベース、もともとCDNの後ろに隠れて、非常に安定して動作し、その後、リアルタイム需要に新たな重点の多くを追加し、彼らは、システムの安定性に影響を与えるにつながったCDNを削除します。重い歴史的な手荷物のため、以前のアーキテクチャの完全な放棄は現実的ではないと思われるので、ソリューション***は、可能な限り透過的にすることができ、元のアーキテクチャに影響を与えることはできませんし、最終的に私は、サービス低下プログラムを達成するために選択しました。
FastCGIキャッシュは、多くの友人など、共有する前に行っている:スーパーグループ、蕁麻疹、概念的なことは、私は繰り返しませんが、何か違うと言う:キャッシュの使用が、リアルタイムの考慮のために、通常の状況下でキャッシュが浸透している異常クエリの場合にのみ、アーキテクチャは次のとおりです:
実装の重要なポイントは、error_page例外を処理し、サービスの劣化を完了することです:
limit_conn_zone $server_name zone=perserver:1m;
error_page 500 502 503 504 = @degradation;
fastcgi_cache_path /tmp
levels=1:2
keys_zone=degradation:100m
inactive=10d
max_size=10g;
upstream php {
server .1:9000;
server .1:9001;
}
server {
listen 80;
limit_conn perserver 1000;
server_name *.xip.io;
root /usr/local/www;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
set $cache_key $request_method://$host$request_uri;
set $cache_bypass "1";
if ($arg_degradation = "on") {
set $cache_bypass "0";
}
try_files $uri =404;
include fastcgi.conf;
fastcgi_pass php;
fastcgi_intercept_errors on;
fastcgi_next_upstream error timeout;
fastcgi_cache degradation;
fastcgi_cache_lock on;
fastcgi_cache_lock_timeout 1s;
fastcgi_cache_valid 200 301 302 10h;
fastcgi_cache_min_uses 10;
fastcgi_cache_use_stale error
timeout
invalid_header
updating
http_500
http_503;
fastcgi_cache_key $cache_key;
fastcgi_cache_bypass $cache_bypass;
add_header X-Cache-Status $upstream_cache_status;
add_header X-Response-Time $upstream_response_time;
}
location @degradation {
rewrite . $request_uri?degradation=on last;
}
}
ちょっとしたヒント:xip.io使用するドメイン名を設定すると、ホストを設定する必要がなくなり、デバッグが容易になります。
このコードはNginxにデフォルトで含まれている機能を使用しており、一般的なバージョンとして見ることができます。しかし、アーキテクチャ図のゴールと比較すると明らかなように、キャッシュのグローバルアクティベーションを実装していません。これはどうすればできるのでしょうか?最も簡単な方法は、単位時間あたりのエラー数によってシステムの健全性を判断し、対応する閾値を設定し、制限を超えたらグローバルにキャッシュをアクティブにすることです:
lua_shared_dict fault 1m;
limit_conn_zone $server_name zone=perserver:1m;
error_page 500 502 503 504 = @degradation;
fastcgi_cache_path /tmp
levels=1:2
keys_zone=degradation:100m
inactive=10d
max_size=10g;
upstream php {
server .1:9000;
server .1:9001;
}
init_by_lua '
get_fault_key = function(timestamp)
if not timestamp then
timestamp = ngx.time()
end
return os.date("fault:minute:%M", timestamp)
end
get_fault_num = function(timestamp)
local fault = ngx.shared.fault
local key = get_fault_key(timestamp)
return tonumber(fault:get(key)) or 0
end
incr_fault_num = function(timestamp)
local fault = ngx.shared.fault
local key = get_fault_key(timestamp)
if not fault:incr(key, 1) then
fault:set(key, 1, 600)
end
end
';
server {
listen 80;
limit_conn perserver 1000;
server_name *.xip.io;
root /usr/local/www;
index index.html index.htm index.php;
location / {
rewrite_by_lua '
if ngx.var.arg_degradation then
return ngx.exit(ngx.OK)
end
local ok = true
for i = 0, 1 do
local num = get_fault_num(ngx.time() - i * 60)
if num > 1000 then
ok = false
break
end
end
if not ok then
local query = "degradation=on"
if ngx.var.args then
ngxngx.var.args = ngx.var.args .. "&" .. query
else
ngx.var.args = query
end
end
';
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
set $cache_key $request_method://$host$request_uri;
set $cache_bypass "1";
if ($arg_degradation = "on") {
set $cache_bypass "0";
}
try_files $uri =404;
include fastcgi.conf;
fastcgi_pass php;
fastcgi_intercept_errors on;
fastcgi_next_upstream error timeout;
fastcgi_cache degradation;
fastcgi_cache_lock on;
fastcgi_cache_lock_timeout 1s;
fastcgi_cache_valid 200 301 302 10h;
fastcgi_cache_min_uses 10;
fastcgi_cache_use_stale error
timeout
invalid_header
updating
http_500
http_503;
fastcgi_cache_key $cache_key;
fastcgi_cache_bypass $cache_bypass;
add_header X-Cache-Status $upstream_cache_status;
add_header X-Response-Time $upstream_response_time;
}
location @degradation {
content_by_lua '
if ngx.var.arg_degradation then
return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
end
local res = ngx.location.capture(
ngx.var.request_uri, {args = "degradation=on"}
)
ngx.status = res.status
for name, value in pairs(res.header) do
ngx.header[name] = value
end
ngx.print(res.body)
incr_fault_num()
';
}
}
注:実際には、キャッシュキーの名前を取得するロジックは少し複雑です。
システムが正常なときは、ダイナミックモードで実行され、データはPHP-FPMを通してレンダリングされます。システムが異常なときは、グローバルキャッシュがアクティブになり、静的モードで実行され、データはキャッシュを通してレンダリングされます。テストを通して、システムが正常から異常に切り替わったとき、PHP-FPMが破棄されたため、RPSが1000から10000に跳ね上がることがわかりました。不死身の一騎が敵に倒されると、いつも立ち上がり、さらにエネルギーを爆発させていました。
また、それは注意する必要があります:障害が発生した場合、キャッシュの有効期限が多数ある場合、それはキャッシュの再構築を伴うので、それはまだパフォーマンスに影響を与える可能性がありますPHP - FPMと相互作用するので、この時点では特に良い解決策はありませんが、Nginxのバージョンが十分な場合は、fastcgi_cache_revalidateの活性化を検討することができます。Nginxのバージョンが十分な場合は、fastcgi_cache_revalidateをアクティブにすることを検討することができます、この方法では、一度PHP-FPMは、システムが異常な状況にあると判断し、直接304を返すことができますモラトリアムを達成するために。
...
FastCGI キャッシュによるサービス低下は **** 解決策ですか?そうではありません!例えば、複数のサーバーが関係している場合、ディスクIOに加え、多くの冗長なキャッシュが必要になります。これは****ソリューションではありませんが、シンプルで、私が困難な問題を解決しようとしているときに使っているものです:問題を軽減するための糞ソリューション、そして問題を解決するための****ソリューション。後ほど、FastCGIキャッシュの代わりに一貫したハッシュを持つMemcachedを使用することを検討します。





