成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

通過FastCGI Cache實(shí)現(xiàn)服務(wù)降級

運(yùn)維 系統(tǒng)運(yùn)維
關(guān)于FastCGI Cache,以前很多朋友已經(jīng)做過分享,說點(diǎn)與眾不同的:雖然使用了緩存,但出于實(shí)時(shí)性考慮,正常情況下緩存都是被穿透的,只有在出現(xiàn)異常情況的時(shí)候才查詢。本文總結(jié)了通過FastCGI Cache實(shí)現(xiàn)服務(wù)降級的方法。

在自然界中,很多生物面臨生死考驗(yàn)的時(shí)候,往往會做出驚人的反應(yīng),其中最為大家熟知的當(dāng)屬壁虎,危難關(guān)頭,與其坐以待斃,不如斷尾求生,通過自殘來換取活下去的希望。對于互聯(lián)網(wǎng)項(xiàng)目而言,同樣存在著很多生死考驗(yàn),比如:訪問量激增;數(shù)據(jù)庫宕機(jī)等等,此時(shí)如果沒有合理的降級方案,那么結(jié)局必然是死路一條。

 

任何問題一旦脫離了實(shí)際情況,便失去了討論的意義。在繼續(xù)之前,不妨先介紹一下案例的背景情況:一個(gè)PHP網(wǎng)站,以讀為主,原本躲在CDN后面,運(yùn)行很穩(wěn)定,后來新增了很多強(qiáng)調(diào)實(shí)時(shí)性的需求,便去掉了CDN,進(jìn)而導(dǎo)致系統(tǒng)穩(wěn)定性受到影響。因?yàn)闅v史包袱重,所以完全廢棄以前的架構(gòu)顯得并不現(xiàn)實(shí),解決方案***能夠盡可能透明,不能對原有架構(gòu)造成沖擊,最終我選擇了通過FastCGI Cache實(shí)現(xiàn)服務(wù)降級的方案。

關(guān)于FastCGI Cache,以前很多朋友已經(jīng)做過分享,比如:超群莿鳥棲草堂,概念性的東西我就不再贅述了,說點(diǎn)與眾不同的:雖然使用了緩存,但出于實(shí)時(shí)性考慮,正常情況下緩存都是被穿透的,只有在出現(xiàn)異常情況的時(shí)候才查詢,架構(gòu)圖如下:

Degradation

Degradation

實(shí)現(xiàn)的關(guān)鍵點(diǎn)在于通過error_page處理異常,并且完成服務(wù)降級:

  1. limit_conn_zone $server_name zone=perserver:1m; 
  2. error_page 500 502 503 504 = @degradation; 
  3. fastcgi_cache_path /tmp 
  4.        levels=1:2 
  5.        keys_zone=degradation:100m 
  6.                    inactive=10d 
  7.                    max_size=10g
  8. upstream php { 
  9.     server 127.0.0.1:9000; 
  10.     server 127.0.0.1:9001; 
  11. server { 
  12.     listen 80; 
  13.     limit_conn perserver 1000; 
  14.     server_name *.xip.io; 
  15.     root /usr/local/www; 
  16.     index index.html index.htm index.php; 
  17.     location / { 
  18.         try_files $uri $uri/ /index.php$is_args$args; 
  19.     } 
  20.     location ~ \.php$ { 
  21.         set $cache_key $request_method://$host$request_uri; 
  22.         set $cache_bypass "1"; 
  23.         if ($arg_degradation = "on") { 
  24.             set $cache_bypass "0"; 
  25.         } 
  26.         try_files $uri =404
  27.         include fastcgi.conf; 
  28.         fastcgi_pass php; 
  29.         fastcgi_intercept_errors on; 
  30.         fastcgi_next_upstream error timeout; 
  31.         fastcgi_cache degradation; 
  32.         fastcgi_cache_lock on; 
  33.         fastcgi_cache_lock_timeout 1s; 
  34.         fastcgi_cache_valid 200 301 302 10h; 
  35.         fastcgi_cache_min_uses 10; 
  36.         fastcgi_cache_use_stale error 
  37.                                 timeout 
  38.                                 invalid_header 
  39.                                 updating 
  40.                                 http_500 
  41.                                 http_503; 
  42.         fastcgi_cache_key $cache_key; 
  43.         fastcgi_cache_bypass $cache_bypass; 
  44.         add_header X-Cache-Status $upstream_cache_status; 
  45.         add_header X-Response-Time $upstream_response_time; 
  46.     } 
  47.     location @degradation { 
  48.         rewrite . $request_uri?degradation=on last; 
  49.     } 

插播一個(gè)小技巧:設(shè)置域名時(shí)用到了xip.io,有了它就不用設(shè)置hosts了,方便調(diào)試。

代碼里用到的都是Nginx缺省包含的功能,我們可以看作是一個(gè)通用版,不過對照我們架構(gòu)圖中的目標(biāo)就會發(fā)現(xiàn):它沒有實(shí)現(xiàn)全局激活緩存的功能。如何實(shí)現(xiàn)呢?最簡單的方法就是通過單位時(shí)間內(nèi)出錯(cuò)次數(shù)的多少來判斷系統(tǒng)健康以否,設(shè)置相應(yīng)的閾值,一旦超過限制就全局激活緩存,通過Lua我們可以實(shí)現(xiàn)一個(gè)定制版:

  1. lua_shared_dict fault 1m; 
  2.  
  3. limit_conn_zone $server_name zone=perserver:1m; 
  4.  
  5. error_page 500 502 503 504 = @degradation; 
  6.  
  7. fastcgi_cache_path /tmp 
  8.                    levels=1:2 
  9.                    keys_zone=degradation:100m 
  10.                    inactive=10d 
  11.                    max_size=10g
  12.  
  13. upstream php { 
  14.     server 127.0.0.1:9000; 
  15.     server 127.0.0.1:9001; 
  16. init_by_lua ' 
  17.     get_fault_key = function(timestamp) 
  18.         if not timestamp then 
  19.             timestamp = ngx.time() 
  20.         end 
  21.         return os.date("fault:minute:%M", timestamp) 
  22.     end 
  23.     get_fault_num = function(timestamp) 
  24.         local fault = ngx.shared.fault 
  25.         local key = get_fault_key(timestamp) 
  26.         return tonumber(fault:get(key)) or 0 
  27.     end 
  28.     incr_fault_num = function(timestamp) 
  29.         local fault = ngx.shared.fault 
  30.         local key = get_fault_key(timestamp) 
  31.         if not fault:incr(key, 1) then 
  32.             fault:set(key, 1, 600) 
  33.         end 
  34.     end 
  35. '; 
  36. server { 
  37.     listen 80; 
  38.     limit_conn perserver 1000; 
  39.     server_name *.xip.io; 
  40.     root /usr/local/www; 
  41.     index index.html index.htm index.php; 
  42.     location / { 
  43.         rewrite_by_lua ' 
  44.             if ngx.var.arg_degradation then 
  45.                 return ngx.exit(ngx.OK) 
  46.             end 
  47.  
  48.             local ok = true 
  49.  
  50.             for i = 0, 1 do 
  51.                 local num = get_fault_num(ngx.time() - i * 60) 
  52.                 if num > 1000 then 
  53.                     ok = false 
  54.                     break 
  55.                 end 
  56.             end 
  57.            if not ok then 
  58.                 local query = "degradation=on" 
  59.                 if ngx.var.args then 
  60.                     ngxngx.var.args = ngx.var.args .. "&" .. query 
  61.                 else 
  62.                     ngx.var.args = query 
  63.                 end 
  64.             end 
  65.         '; 
  66.         try_files $uri $uri/ /index.php$is_args$args; 
  67.     } 
  68.     location ~ \.php$ { 
  69.         set $cache_key $request_method://$host$request_uri; 
  70.  
  71.         set $cache_bypass "1"; 
  72.         if ($arg_degradation = "on") { 
  73.             set $cache_bypass "0"; 
  74.         } 
  75.         try_files $uri =404
  76.         include fastcgi.conf; 
  77.         fastcgi_pass php; 
  78.         fastcgi_intercept_errors on; 
  79.         fastcgi_next_upstream error timeout; 
  80.         fastcgi_cache degradation; 
  81.         fastcgi_cache_lock on; 
  82.         fastcgi_cache_lock_timeout 1s; 
  83.         fastcgi_cache_valid 200 301 302 10h; 
  84.         fastcgi_cache_min_uses 10; 
  85.         fastcgi_cache_use_stale error 
  86.                                 timeout 
  87.                                 invalid_header 
  88.                                 updating 
  89.                                 http_500 
  90.                                 http_503; 
  91.         fastcgi_cache_key $cache_key; 
  92.         fastcgi_cache_bypass $cache_bypass; 
  93.         add_header X-Cache-Status $upstream_cache_status; 
  94.         add_header X-Response-Time $upstream_response_time; 
  95.     } 
  96.     location @degradation { 
  97.         content_by_lua ' 
  98.             if ngx.var.arg_degradation then 
  99.                 return ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) 
  100.             end 
  101.             local res = ngx.location.capture( 
  102.                 ngx.var.request_uri, {args = "degradation=on"
  103.             ) 
  104.             ngx.status = res.status 
  105.             for name, value in pairs(res.header) do 
  106.                 ngx.header[name] = value 
  107.             end 
  108.             ngx.print(res.body) 
  109.             incr_fault_num() 
  110.         '; 
  111.     } 

說明:實(shí)際上真實(shí)案例中緩存鍵名的獲取邏輯有點(diǎn)復(fù)雜,鑒于篇幅所限一切從簡。

當(dāng)系統(tǒng)正常時(shí),運(yùn)行于動態(tài)模式,數(shù)據(jù)通過PHP-FPM渲染;當(dāng)系統(tǒng)異常時(shí),全局緩存被激活,運(yùn)行于靜態(tài)模式,數(shù)據(jù)通過緩存渲染。通過測試發(fā)現(xiàn),系統(tǒng)在從正常切換到異常時(shí),因?yàn)樯釛壛薖HP-FPM,所以RPS從一千躍升到一萬。這讓我想起兒時(shí)看圣斗士的情景:每當(dāng)不死鳥一輝被敵人擊倒后,他總能重新站起來,并爆發(fā)出更大的能量。

此外需要說明的是:在發(fā)生故障的時(shí)候,如果出現(xiàn)大量緩存過期的情況,那么由于涉及到緩存的重建,所以依然會和PHP-FPM發(fā)生交互行為,這可能會影響性能,此時(shí)沒有特別好的解決辦法,如果Nginx版本夠的話,可以考慮激活fastcgi_cache_revalidate,如此一來,PHP-FPM一旦判斷系統(tǒng)處于異常情況,那么可以直接返回304實(shí)現(xiàn)緩存續(xù)期。

通過FastCGI Cache實(shí)現(xiàn)服務(wù)降級,這是一個(gè)***的方案么?非也!它甚至有些丑陋,比如說多臺服務(wù)器時(shí),會導(dǎo)致大量冗余的緩存,此外磁盤IO也需要注意。雖然這不是一個(gè)***的方案,但是它簡單,正符合我解決棘手問題時(shí)的慣用打法:先用一個(gè)土鱉一點(diǎn)的方案緩解問題,再用一個(gè)***的方案解決問題。稍后我會考慮使用Memcached,加上一致性哈希來替換FastCGI Cache,實(shí)現(xiàn)一個(gè)相對***的服務(wù)降級方案。

責(zé)任編輯:黃丹 來源: 火丁筆記
相關(guān)推薦

2013-04-25 10:01:35

Nginx

2025-04-17 02:00:00

2025-06-09 07:46:44

服務(wù)降級高并發(fā)

2024-11-29 16:02:17

2018-08-01 14:20:11

微服務(wù)架構(gòu)人工智能

2025-03-26 00:58:14

2017-11-16 15:45:25

服務(wù)降級熔斷

2021-03-16 08:31:59

微服務(wù)Sentinel雪崩效應(yīng)

2017-07-03 09:50:07

Spring Clou微服務(wù)架構(gòu)

2016-12-19 11:33:26

2023-05-05 18:38:33

多級緩存Caffeine開發(fā)

2023-02-27 13:41:04

apt-get軟件包

2023-06-20 08:10:00

2024-01-30 18:10:25

2012-09-25 11:47:48

FacebookCache服務(wù)器

2023-08-03 08:52:10

緩存數(shù)據(jù)逐出數(shù)據(jù)

2025-04-03 10:04:53

服務(wù)降級分布式系統(tǒng)系統(tǒng)

2010-03-29 16:58:41

Nginx FastC

2014-11-04 10:34:27

JavaCache

2024-05-17 12:48:58

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 天天综合国产 | 欧美视频在线播放 | 激情亚洲| 久久久男人的天堂 | 欧美国产中文 | 在线播放亚洲 | 国产福利91精品一区二区三区 | 精品视频999 | 日韩一区二区三区在线视频 | 特黄色毛片 | 国产精品久久久久久久久久免费 | 久久精品国产亚洲夜色av网站 | 免费永久av | 久草视频在线播放 | 亚洲精品乱码 | 亚洲一二三在线 | 日韩精品在线观看免费 | 日本在线观看视频 | 久久久久久国产精品免费 | 亚洲精品美女视频 | 午夜影院在线观看 | 亚洲一二三视频 | 欧美一区二区三区在线播放 | 老司机久久 | 精品伊人| 999精品在线| 午夜视频在线 | 亚洲欧美在线观看 | 国产精品一级在线观看 | 日日爽| 91国内精品 | 精品无码久久久久久久动漫 | 久久中文字幕一区 | 天天拍天天草 | 国产福利一区二区 | 成人在线视频一区 | 国产欧美精品在线观看 | 丝袜美腿一区二区三区 | 国产精品久久久久久亚洲调教 | 日本一区二区三区视频在线 | 亚洲精品一区二三区不卡 |