相信很多人有已经从apache之类的web服务器转到Nginx了,然而Nginx除了单纯的web服务器用途外,可以当做反向代理服务器使用,配合proxy_cache功能基本可以代替squid了。
1. 编译安装Nginx
1
2
|
./configure --user=www --group=www --prefix=/opt/nginx --with-http_stub_status_module --with-http_ssl_module
make && make install
|
2. nginx.conf配置文件如下:
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
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函数改写如下:
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
|
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 = '\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的调用。
先申明一下函数定义:
1
2
|
static ngx_int_t ngx_http_file_cache_domain(ngx_http_request_t *r,
ngx_path_t *path);
|
具体函数内容:
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
|
//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 = '\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中的第一个出现字符’/'的地方,并且将/前的字符串作为域名拼接到缓存路径里去。
由于本人不会C语言,所以写得比较粗糙,但是基本实现了这一需求。
看看最终的成果吧:
附上完整的 ngx_http_file_cache.c文件吧:ngx_http_file_cache.c
(责任编辑:IT) |