本篇文章給大家分享的是有關(guān)FastCGI 中怎么利用Cache實(shí)現服務(wù)降級,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習,希望大家閱讀完這篇文章后可以有所收獲,話(huà)不多說(shuō),跟著(zhù)小編一起來(lái)看看吧。
架構圖如下:
Degradation
實(shí)現的關(guān)鍵點(diǎn)在于通過(guò)error_page處理異常,并且完成服務(wù)降級:
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 127.0.0.1:9000; server 127.0.0.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; } }
插播一個(gè)小技巧:設置域名時(shí)用到了xip.io,有了它就不用設置hosts了,方便調試。
代碼里用到的都是Nginx缺省包含的功能,我們可以看作是一個(gè)通用版,不過(guò)對照我們架構圖中的目標就會(huì )發(fā)現:它沒(méi)有實(shí)現全局激活緩存的功能。如何實(shí)現呢?最簡(jiǎn)單的方法就是通過(guò)單位時(shí)間內出錯次數的多少來(lái)判斷系統健康以否,設置相應的閾值,一旦超過(guò)限制就全局激活緩存,通過(guò)Lua我們可以實(shí)現一個(gè)定制版:
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 127.0.0.1:9000; server 127.0.0.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() '; } }
說(shuō)明:實(shí)際上真實(shí)案例中緩存鍵名的獲取邏輯有點(diǎn)復雜,鑒于篇幅所限一切從簡(jiǎn)。
當系統正常時(shí),運行于動(dòng)態(tài)模式,數據通過(guò)PHP-FPM渲染;當系統異常時(shí),全局緩存被激活,運行于靜態(tài)模式,數據通過(guò)緩存渲染。通過(guò)測試發(fā)現,系統在從正常切換到異常時(shí),因為舍棄了PHP-FPM,所以RPS從一千躍升到一萬(wàn)。這讓我想起兒時(shí)看圣斗士的情景:每當不死鳥(niǎo)一輝被敵人擊倒后,他總能重新站起來(lái),并爆發(fā)出更大的能量。
此外需要說(shuō)明的是:在發(fā)生故障的時(shí)候,如果出現大量緩存過(guò)期的情況,那么由于涉及到緩存的重建,所以依然會(huì )和PHP-FPM發(fā)生交互行為,這可能會(huì )影響性能,此時(shí)沒(méi)有特別好的解決辦法,如果Nginx版本夠的話(huà),可以考慮激活fastcgi_cache_revalidate,如此一來(lái),PHP-FPM一旦判斷系統處于異常情況,那么可以直接返回304實(shí)現緩存續期。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站