ngx_lua灵活定制fastcgi_cache缓存key

Web开发常见的几种缓存

  • 常用缓存(memcached和redis)
  • Nginx的缓存(标准模块缓存: proxy_cache和fastcgi_cache / 第三方模块做缓存: ngx_lua)
  • CDN缓存
  • 浏览器缓存(Cache-Control和LocalStorage)

proxy_cache和fastcgi_cache

proxy_cache和fastcgi_cache都为Nginx的内置缓存,proxy_cache主要用于反向代理时,对后端内容源服务器进行缓存,fastcgi_cache主要用于对FastCGI的动态程序进行缓存。
两者相关配置类似,以下为fastcgi_cache举例

原理

针对fastcgi(如:php- fpm)返回的内容缓存为静态文件(文件名是用Md5算法对Key进行哈希后所得,而Key可使用fastcgi_cache的相关指令来进行控制)
,在用户浏览时,无需重复请求后端fastcgi,而直接返回缓存的内容,减少了后端的语言解析以及数据库连接的消耗。

数据流程图

指令注释

nginx的http作用域:

fastcgi_cache_path /home/wwwroot/yii.me/runtime/logs levels=1:2 keys_zone=keys_zone=zone:512m:1m inactive=1d
max_size=1g; #指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。以及最大占用空间(keys_zone主要缓存key和文件元信息,不会缓存页面)

nginx的location作用域:

fastcgi_cache zone; #表示开启FastCGI缓存并为其指定一个名称:zone
fastcgi_cache_valid 1m; #设置缓存时间1分钟
fastcgi_cache_min_uses 1; #设置链接请求1次就被缓存
fastcgi_cache_use_stale error timeout invalid_header http_500; #定义哪些情况下用过期缓存(如果对实效要求不高建议加updating,关闭fastcgi_cache_lock,可提高性能)
fastcgi_cache_methods GET POST; #缓存GET和POST请求
fastcgi_cache_key “$cache_path$containerid$containerpage”; #缓存key=页面+containerid+分页页码
fastcgi_ignore_headers Cache-Control Expires Set-Cookie; #包含这些header的响应不缓存
fastcgi_cache_lock on; #同时有请求处理的时候只有一个请求允许访问后端服务器,其余请求等待缓存结果或等待超时再进行响应
fastcgi_cache_lock_timeout 5s; #等待超时时间5秒,超时则穿透,且不缓存穿透结果
fastcgi_cache_bypass $skip_cache; #非0不从cache中取
fastcgi_no_cache $skip_cache; #非0不保存到cache

性能提升

以下测试使用的vps机器
ab -c10 -n50000 http://127.0.0.1:8080/echo.php

  • fastcgi_cache off Requests per second: 2441.56 [#/sec] (mean)
  • fastcgi_cache zone Requests per second: 3662.79 [#/sec] (mean)

ngx_lua模块

参考资料

在ngx_lua模块中使用共享内存

  • 定义一个共享内存对象
    语法:lua_shared_dict
    该命令主要是定义一块名为name的共享内存空间,内存大小为size。通过该命令定义的共享内存对象对于Nginx中所有worker进程都是可见的,当Nginx通过reload命令重启时,共享内存字典项会从新获取它的内容,而当Nginx
    退出时,字典项的值将会丢失。
    例子:

    1
    

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    location /testngxlua {

        default_type application/json;

        charset utf8;

        access_by_lua '

            function get_from_cache(key)

                local cache_ngx = ngx.shared.my_cache

                local value = cache_ngx:get(key)

                return value

            end

            function set_to_cache(key, value, exptime)

                if not exptime then

                    exptime = 0

                end

                local cache_ngx = ngx.shared.my_cache

                local succ, err, forcible = cache_ngx:set(key, value, exptime)

                return succ

            end

            ngx.req.read_body()

            local c = ngx.req.get_uri_args()["c"] or ""

            local str = get_from_cache(c)

            if (str ~= nil) then

                ngx.print("ngx_cache: "..str)

            else

                local options = {}

                options["method"] = ngx.var.request_method == "GET" and ngx.HTTP_GET or ngx.HTTP_POST

                options["body"] = ngx.var.request_body

                options["args"] = ngx.var.args

                local res = ngx.location.capture("/index.php"..ngx.var.uri, options)

                if res.status == 200 then

                    set_to_cache(c, res.body, 300)

                    ngx.print(res.body)

                else

                    ngx.say(res.status)

                end

            end

        ';

    }  

—|—

糖果

糖果
LUA教程

Lapis框架的常用处理方法

Lapis框架的常用处理方法 Continue reading

MoonScript实现选择排序

Published on February 26, 2017

MoonScript与Redis客户端

Published on January 19, 2017