转自[]
相信很多人有已经从apache之类的web服务器转到了,然而除了单纯的web服务器用途外,可以当做反向代理服务器使用,配合proxy_cache功能基本可以代替squid了。
1. 编译安装Nginx./configure --user=www --group=www --prefix=/opt/nginx --with-http_stub_status_module --with-http_ssl_modulemake && make install2. 配置文件如下: 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吧1/opt/nginx/sbin/nginx4. 能否将缓存按照域名分文件夹存放?由于我们的运营的是一个网站集群,所以子站是通过域名泛解析解析到本机的,所以希望能否按照域名存放,便于整站清理缓存。比如: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_tngx_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 = '\0'; 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 Lingterstatic 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 = '\0'; 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中的第一个出现字符’/'的地方,并且将/前的字符串作为域名拼接到缓存路径里去。