2014-03-08 10:04:01
来 源
ITJS.CN
Nginx
本文介绍Nginx做反向代理时配置缓存按域名分目录存储,希望对于初学Nginx服务器相关的朋友有帮助,更多Nginx安装、配置、报错处理等资源请本站内搜索。。
相信很多人有已经从apache之类的web服务器转到Nginx了,然而Nginx除了单纯的web服务器用途外,可以当做反向代理服务器使用,配合proxy_cache功能基本可以代替squid了。

1. 编译安装Nginx

./configure --user=www --group=www --prefix=/opt/nginx --with-http_stub_status_module --with-http_ssl_module

make && make install

2. nginx.conf配置文件如下:

user  www www;

worker_processes 8;

error_log  /opt/nginx/logs/nginx_error.log  crit;

pid        /opt/nginx/nginx.pid; #Specifies the value for maximum file descriptors that can be opened by this process.

worker_rlimit_nofile 65535;

events

{

use epoll;

worker_connections 65535;

}

http

{

include       mime.types;

default_type  application/octet-stream;

charset  utf-8;

server_names_hash_bucket_size 128;

client_header_buffer_size 32k;

large_client_header_buffers 4 32k;

client_max_body_size 300m;

sendfile on;

tcp_nopush     on;

keepalive_timeout 60;

tcp_nodelay on;

client_body_buffer_size  512k;

proxy_connect_timeout    5;

proxy_read_timeout       60;

proxy_send_timeout       5;

proxy_buffer_size        16k;

proxy_buffers            4 64k;

proxy_busy_buffers_size 128k;

proxy_temp_file_write_size 128k;

gzip on;

gzip_min_length  1k;

gzip_buffers     4 16k;

gzip_http_version 1.1;

gzip_comp_level 2;

gzip_types       text/plain application/x-javascript text/css application/xml;

gzip_vary on;

#注:proxy_temp_path和proxy_cache_path指定的路径必须在同一分区

proxy_temp_path   /data/proxy_temp_dir;

#设置Web缓存区名称为cache_one,内存缓存空间大小为200MB,1天没有被访问的内容自动清除,硬盘缓存空间大小为30GB。

proxy_cache_path  /data/proxy_cache_dir  levels=1:2   keys_zone=cache_one:200m inactive=1d max_size=30g;

upstream backend_server {

server   192.168.8.43:80 weight=1 max_fails=2 fail_timeout=30s;

server   192.168.8.44:80 weight=1 max_fails=2 fail_timeout=30s;

server   192.168.8.45:80 weight=1 max_fails=2 fail_timeout=30s;

}

server

{

listen       80;

server_name  *.yourdomain.com;

index index.html index.htm;

root  /data/htdocs/www;

location /

{

#如果后端的服务器返回502、504、执行超时等错误,自动将请求转发到upstream负载均衡池中的另一台服务器,实现故障转移。

proxy_next_upstream http_502 http_504 error timeout invalid_header;

proxy_cache cache_one;

#对不同的HTTP状态码设置不同的缓存时间

proxy_cache_valid  200 304 12h;

#以域名、URI、参数组合成Web缓存的Key值,Nginx根据Key值哈希,存储缓存内容到二级缓存目录内

proxy_cache_key $host$uri$is_args$args;

proxy_set_header Host  $host;

proxy_set_header X-Forwarded-For  $remote_addr;

proxy_pass http://backend_server;

expires      1d;

}

#扩展名以.php、.jsp、.cgi结尾的动态应用程序不缓存。

location ~ .*.(php|jsp|cgi)?$

{

proxy_set_header Host  $host;

proxy_set_header X-Forwarded-For  $remote_addr;

proxy_pass http://backend_server;

}

access_log  off;

}

}

3. 接下来启动nginx吧

4. 能否将缓存按照域名分文件夹存放?

由于我们的运营的是一个网站集群,所以子站是通过域名泛解析解析到本机的,所以希望能否按照域名存放,便于整站清理缓存。比如:a.youdomain.com/a/b3/…. ,b.youdomain.com/b/ae/….,这样的目录结构。但是研究了很久nginx配置方式,并没有发现相关的设置。于是想到自己来改写nginx源代码,涉及到的文件是src/http/ngx_http_file_cache.c文件。

以下函数的改写是基于 nginx0.8.55的。

ngx_http_file_cache_name函数改写如下:

static ngx_int_t

ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path)

{

    u_char            *p;

    ngx_http_cache_t  *c;

    size_t            pathlen;     c = r->cache;

    //added by Lingter

    pathlen = path->name.len;

    ngx_http_file_cache_domain(r,path);

      c->file.name.len = path->name.len + 1 + path->len

     + 2 * NGX_HTTP_CACHE_KEY_LEN;

      c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1);

    if (c->file.name.data == NULL) {

            return NGX_ERROR;

    }

    ngx_memcpy(c->file.name.data, path->name.data, path->name.len);

    p = c->file.name.data + path->name.len + 1 + path->len;

    p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN);

    *p = '';

    ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len);

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,

               "cache file: "%s"", c->file.name.data);

    path->name.len = pathlen;

    return NGX_OK;

}

上一段代码中加入了一个新的函数ngx_http_file_cache_domain的调用。

先申明一下函数定义:

static ngx_int_t ngx_http_file_cache_domain(ngx_http_request_t *r,

ngx_path_t *path);

具体函数内容:

//added by Lingter

static ngx_int_t ngx_http_file_cache_domain(ngx_http_request_t *r,ngx_path_t *path)

{

    ngx_http_cache_t    *c;

    u_char              *pathname,*pos;

    size_t              i;

    ngx_str_t           *key,domain;

    c = r->cache;

    key = c->keys.elts;     domain.len  = key[0].len;

    domain.data = ngx_pstrdup(r->pool,& key[0]);

    pos = (u_char *) ngx_strchr(domain.data,'/');

    if(pos){

        *pos = '';

        domain.len = ngx_strlen(domain.data);

        pathname = path->name.data;

        i = path->name.len+1;

        pathname[i-1] = '/';

ngx_memcpy(&pathname[i],domain.data,domain.len);

        path->name.len = i + domain.len;

    }

    return NGX_OK;

}

实际上上面的代码仅仅是找出key中的第一个出现字符’/'的地方,并且将/前的字符串作为域名拼接到缓存路径里去。

由于本人不会C语言,所以写得比较粗糙,但是基本实现了这一需求。

看看最终的成果吧:

附上完整的 ngx_http_file_cache.c文件吧:

http://upload.server110.com/file/20131106/1-1311060T94b38.zip

声明: 此文观点不代表本站立场;转载须要保留原文链接;版权疑问请联系我们。