温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

FastCGI 中怎么利用Cache实现服务降级

发布时间:2021-08-09 14:54:48 来源:亿速云 阅读:117 作者:Leah 栏目:系统运维

本篇文章给大家分享的是有关FastCGI 中怎么利用Cache实现服务降级,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

架构图如下:

FastCGI 中怎么利用Cache实现服务降级

Degradation

实现的关键点在于通过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 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;     } }

插播一个小技巧:设置域名时用到了xip.io,有了它就不用设置hosts了,方便调试。

代码里用到的都是Nginx缺省包含的功能,我们可以看作是一个通用版,不过对照我们架构图中的目标就会发现:它没有实现全局激活缓存的功能。如何实现呢?最简单的方法就是通过单位时间内出错次数的多少来判断系统健康以否,设置相应的阈值,一旦超过限制就全局激活缓存,通过Lua我们可以实现一个定制版:

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()         ';     } }

说明:实际上真实案例中缓存键名的获取逻辑有点复杂,鉴于篇幅所限一切从简。

当系统正常时,运行于动态模式,数据通过PHP-FPM渲染;当系统异常时,全局缓存被激活,运行于静态模式,数据通过缓存渲染。通过测试发现,系统在从正常切换到异常时,因为舍弃了PHP-FPM,所以RPS从一千跃升到一万。这让我想起儿时看圣斗士的情景:每当不死鸟一辉被敌人击倒后,他总能重新站起来,并爆发出更大的能量。

此外需要说明的是:在发生故障的时候,如果出现大量缓存过期的情况,那么由于涉及到缓存的重建,所以依然会和PHP-FPM发生交互行为,这可能会影响性能,此时没有特别好的解决办法,如果Nginx版本够的话,可以考虑激活fastcgi_cache_revalidate,如此一来,PHP-FPM一旦判断系统处于异常情况,那么可以直接返回304实现缓存续期。

以上就是FastCGI 中怎么利用Cache实现服务降级,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI