符合中小企业对网站设计、功能常规化式的企业展示型网站建设
本套餐主要针对企业品牌型网站、中高端设计、前端互动体验...
商城网站建设因基本功能的需求不同费用上面也有很大的差别...
手机微信网站开发、微信官网、微信商城网站...
本篇文章给大家分享的是有关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实现缓存续期。