caching - nginx 使用 memcached 缓存来自远程服务器的响应

标签 caching nginx memcached

我有以下 nginx 配置:

upstream backend {
  server localhost:8080;
}

upstream memcached_server {
  server 127.0.0.1:11211;
}

server {
    listen       3000;
    server_name  localhost;

    location /picture {
            set $memc_cmd get;
            set $memc_key $arg_login;
            memc_pass memcached_server;
            error_page 404 = @cache_miss;
    }

    location @cache_miss {
            proxy_pass http://backend;
    }

    location /image {
            proxy_pass http://myimageservice;
    }

当我发送请求至: localhost:3000/picture?login=john它尝试使用键“john”在 memcached 中查找内容。当 memcached 中不存在内容时,它会代理将请求传递到后端服务器 (localhost:8080),该服务器将“X-Accel-Redirect”设置为 John 图像的路径。路径以“/image”开头,因此 nginx 从 myimageservice 获取数据并将其返回给客户端。

问题是我想缓存从“myimageservice”返回的响应,所以下次 localhost:3000/picture?login=john 时调用时,不会向后端服务器(localhost:8080)发送任何请求,并立即从 memcache 返回响应。可能吗?

最佳答案

本周我遇到了同样的问题,这是我的解决方案(请参阅下面的设置以及 nginx 的编译者)

在 nginx.conf 下添加此行(它添加了对 Lua 的支持,请参阅下面的原因)

lua_package_path '/usr/local/lib/lua/?.lua';

站点配置(在我的例子中是默认的):

upstream memcached {
    server 127.0.0.1:11211;
    keepalive 32;
}

server {
    listen 8080 default_server;

    root /usr/share/nginx/html;
    index index.fhtml index.fhtm;

    # Make site accessible from http://localhost/
    server_name localhost;

    location = /memc {
        internal;

        memc_connect_timeout 100ms;
        memc_send_timeout 100ms;
        memc_read_timeout 100ms;
        memc_ignore_client_abort on;

        set $memc_key $arg_key;
        set $memc_exptime 300;

        memc_pass memcached;
    }

    location /memc-stats {
        add_header Content-Type text/plain;
        set $memc_cmd stats;
        memc_pass memcached;
    }

    location / {
        set_by_lua $key 'return ngx.md5(ngx.arg[1])' $request_uri;

        srcache_fetch GET /memc key=$key;
        srcache_methods GET;
        srcache_store_statuses 200 301 302;

        proxy_pass http://127.0.0.1:80$request_uri;
        set_by_lua $key 'return ngx.md5(ngx.arg[1])' $request_uri;
        srcache_request_cache_control off;
        srcache_store PUT /memc key=$key;
    }

}

我的设置就像在 Ubuntu 14.04 上一样,nginx 在端口 8080 上运行,Apache 在 80 上运行(只是为了测试这一点),nginx 1.7.5 在“full_configure_flags”下使用以下参数进行编译

full_configure_flags := \
    $(common_configure_flags) \
    --with-http_addition_module \
    --with-http_dav_module \
    --with-http_geoip_module \
    --with-http_gzip_static_module \
    --with-http_image_filter_module \
    --with-http_secure_link_module \
    --with-http_spdy_module \
    --with-http_sub_module \
    --with-http_xslt_module \
    --with-mail \
    --with-mail_ssl_module \
    --with-http_ssl_module \
    --with-http_stub_status_module \
    --add-module=/opt/nginx/modules/ngx_devel_kit-0.2.19 \
    --add-module=/opt/nginx/modules/set-misc-nginx-module-0.26 \
    --add-module=/opt/nginx/modules/memc-nginx-module-0.15 \
    --add-module=/opt/nginx/modules/srcache-nginx-module-0.28 \
    --add-module=$(MODULESDIR)/headers-more-nginx-module \
    --add-module=$(MODULESDIR)/nginx-auth-pam \
    --add-module=$(MODULESDIR)/nginx-cache-purge \
    --add-module=$(MODULESDIR)/nginx-dav-ext-module \
    --add-module=$(MODULESDIR)/nginx-echo \
    --add-module=$(MODULESDIR)/nginx-http-push \
    --add-module=$(MODULESDIR)/nginx-lua \
    --add-module=$(MODULESDIR)/nginx-upload-progress \
    --add-module=$(MODULESDIR)/nginx-upstream-fair \
    --add-module=$(MODULESDIR)/ngx_http_substitutions_filter_module

如你所见,我已经编译了 Lua 和其他模块。需要 Lua 是因为我希望有一种一致的方法来散列 memcached 键的值,而不必担心如果有人发送一些意外的值会发生什么,并且能够以相同的方式从后端。

希望这对您(和其他人)有帮助。

编辑: 您可以从这里获取我添加的模块:

关于caching - nginx 使用 memcached 缓存来自远程服务器的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25639445/

相关文章:

Docker 容器内的 Django + uWSGI/nginx - ImportError : No module named . wsgi

Django:使 ModelChoiceField 在运行时评估查询集

php - memcached.dll 是否存在?

java - Spring Boot EnableCaching 和 Cacheable 注释不起作用

java - Java中具有过期控制的分布式缓存

python - 使用 django、virtualenv、gunicorn 和 nginx 设置服务器以托管多个域

php - Docker PHP容器无法连接到MariaDB容器

Django/内存缓存错误 : The request's session was deleted before the request completed

database - 在 Web 应用程序中缓存适量的数据 - 数据库还是平面文件?

php - CSS 中的版本控制图像,如何?