高并发解决方案之NGINX缓存 发表于 2018-02-23 | 简介使用ngx_lua模块在Nginx层做缓存,可动态控制缓存开关,可做静态方案或者降级方案,在公司的一个专题页项目中使用该方案,QPS提高了20倍 架构图 Lua代码文件header_filter.lua文件1ngx.header.NgxCache = ngx.var.is_cache access.lua文件12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394function get_from_cache(key) local cache_ngx = ngx.shared.ngx_cache local value = cache_ngx:get(key) return valueendfunction set_to_cache(key, value, exptime) if not exptime then exptime = 0 end local cache_ngx = ngx.shared.ngx_cache local succ, err, forcible = cache_ngx:set(key, value, exptime) return succendfunction safe_add(key, value, exptime) if not exptime then exptime = 0 end local cache_ngx = ngx.shared.ngx_cache local succ, err, forcible = cache_ngx:safe_add(key, value, exptime) return succendfunction get_from_php(k, kk, flag, exptime) local options = {} options["method"] = ngx.var.request_method == "GET" and ngx.HTTP_GET or ngx.HTTP_POST options["body"] = ngx.var.request_body if ngx.var.args == nil then ngx.var.args = "debug=0" end local args = ngx.decode_args(ngx.var.args) args.subrequest = flag options["args"] = args local uri = ngx.var.uri local res = ngx.location.capture("/index.php"..uri, options) if res.status == 200 then if flag == "open" then set_to_cache(k, res.body, exptime) set_to_cache(kk, res.body, exptime*3) end return res.body else return res.status endendlocal open = "open"local close = "close"local time = 300ngx.req.read_body()local k = ngx.req.get_post_args()["containerid"] or "default"local ctrlkey = ngx.req.get_uri_args()["ctrlkey"] or ""if ctrlkey == open or ctrlkey == close then set_to_cache("ctrlkey", ctrlkey, 0)endif k == "default" then time = 10 endlocal uri = string.sub(ngx.var.uri,1,100)k = ngx.var.request_method .. ngx.var.host .. uri .. klocal content = nillocal sw = closelocal kk = k .. "old"sw = get_from_cache("ctrlkey")if sw == open then content = get_from_cache(k) if content ~= nil then ngx.var.is_cache = 1 else local atom = safe_add(k .. sw, 1, 5) if atom == nil then content = get_from_cache(kk) if content == nil then content = get_from_php(k, kk, sw, time) ngx.var.is_cache = 4 else ngx.var.is_cache = 2 end else content = get_from_php(k, kk, sw, time) ngx.var.is_cache = 3 end endelse content = get_from_php(k, kk, sw, time)endngx.print(content) Nginx主要配置12345678910111213141516171819202122232425262728293031323334353637lua_code_cache on;lua_shared_dict ngx_cache 32m;#...set $flag 1;if ($arg_subrequest = "") { set $flag "1${flag}";}if ($arg_containerid ~ "newartificial") { set $flag "1${flag}";}if ($arg_containerid = "") { set $flag "1${flag}";}if ($uri ~ "^/(path.*)$") { set $flag "1${flag}";}if ($flag = "1111") { rewrite "(.*)" $1 break;}#...location ~ /(.*)\.lua$ { deny all;}location ^~ /path { default_type text/html; set $is_cache 0; header_filter_by_lua_file /XXXXX/lua/header_filter.lua; access_by_lua_file /XXXXX/lua/access.lua;} 缓存开关控制脚本123456789101112131415161718#!/bin/bash# ./ctrl.sh open 开启缓存# ./ctrl.sh open 关闭缓存ips=(10.x.x.x 10.x.x.x 10.x.x.x 10.x.x.x 10.x.x.x 10.x.x.x)if [ x$1 != x ]; then state=$1else echo "need param open or close" exit 1fistate=$1for ip in ${ips[@]};do curl -v -x "$ip:80" -d "uid=xxx" "http://host/path?ctrlkey=$state" echo ""done 赏 微信打赏 支付宝打赏