- 论坛徽章:
- 0
|
高性能Web服务器Nginx的配置与部署研究
(1)Nginx中的Rewrite写法小记
实现http://a.com/abc得到http://b.com/abc
在server中添加一段代码:
view plaincopy to clipboardprint?
1. location ^~ /hd
2. {
3. rewrite ^/hd/(.*)$ http://www.google.com/$1 permanent;
4. }
实现http://a.com/msg?url=www.b.com得到http://www.b.com
注意问号。
view plaincopy to clipboardprint?
1. location ^~ /img_proxy
2. {
3. set $img_proxy_url "";
4. set $suffix "";
5. if ($query_string ~ "url=(.*)")
6. {
7. set $img_proxy_url $1;
8. set $suffix "";
9. }
10. resolver 208.67.222.222;
11. proxy_pass http://$img_proxy_url/$suffix;
12. proxy_set_header referer "http://$img_proxy_url";
13. }
4)常用Nginx命令
1. 启动Nginx
view plaincopy to clipboardprint?
1. sudo ./sbin/nginx
2. 停止Nginx
view plaincopy to clipboardprint?
1. sudo ./sbin/nginx -s stop
2. sudo ./sbin/nginx -s quit
3. Nginx重载配置
view plaincopy to clipboardprint?
1. sudo ./sbin/nginx -s reload
或者:
view plaincopy to clipboardprint?
1. service nginx reload
4. 指定Nginx配置文件
view plaincopy to clipboardprint?
1. sudo ./sbin/nginx -c /usr/local/nginx/conf/nginx.conf
(5)Nginx配置符号
1. 容量符号
k 千字节
K 千字节
m 兆字节
M 兆字节
2. 时间符号
ms 毫秒
s 秒
m 分
h 时
d 日
w 周
M 月(按照30天计算)
y 年(按照365天计算)
3. 示例
1h 30m 表示1小时30分钟
1y 6M 表示1年6个月
(6)核心模块之主模块的测试常用指令
1. daemon
含义:设置是否以守护进程模式运行
语法:daemon on|off
缺省:on
示例:daemon off;
注意:生产环境(production mode)中不要使用daemon指令,这些选项仅用于开发测试(development mode)。
2. debug_points
含义:断点调试
语法:debug_points [stop|abort]
缺省:none
示例:debug_points stop;
注意:在Nginx内有一些assert断言,这些断言允许Nginx,配合调试器中断程序运行、停止或创建core文件。
3. master_process
含义:设置是否启用主进程
语法:master_process on|off
缺省:on
示例:master_process off;
注意:不要在生产环境(production mode)中使用master_process指令,这些选项仅用于开发测试(development mode)。
4. error_log
含义:指定错误日志文件
语法:error_log file [debug|info|notice|warn|error|crit]
缺省:${prefix}/logs/error.log
示例:error_log /data/nginx/logs/error.log debug
注意:该命令并非只有在测试(或称为开发)模式下才可以使用,而是在编译时添加了--with-debug参数时,则可以使用error_log指令的额外参数,即:
error_log file [debug_core|debug_alloc|debug_mutex|debug_event|debug_http|debug_imap];
(7)核心模块之主模块的非测试常用指令
1. error_log
含义:指定存储错误日志的文件
语法:error_log <file> [debug|info|notice|warn|error|crit]
缺省:${prefix}/logs/error_log
示例:error_log file debug;
注意:在编译Nginx使用--with-debug参数,则可以参考《高性能Web服务器Nginx的配置与部署研究——(6)Nginx核心模块的测试常用指令》中的error_log部分
2. include
含义:指定所要包含的Nginx配置文件
语法:include <file|*>
缺省:none
示例:include vhosts/*.conf 或 include /home/michael/nginx/conf/nginx-main.conf
注意:
(1)include命令可以指定包含一个文件,比如第二个示例。也可以指定包含一个目录下的所有文件,比如第一个示例。
(2)指定的文件路径的基路径,由编译选项--prefix决定,如果编译时没有指定,则默认的路径是/usr/local/nginx。
3. lock_file
含义:
语法:lock_file <file>
缺省:compile-time option
示例:lock_file /var/log/lock_file;
注意:Nginx使用accept mutex来序列化accept()系统调用(syscalls)。如果是在i386,sparc64,ppc64或amd64平台上用GCC,Intel C++,SunPro C++编译器编译的,则Nginx使用CPU原指令实现mutex。其他情况下,则使用lock_file。
4. pid
含义:指定存储进程ID(即PID)的文件。
语法:pid <file>
缺省:compile-time option Example
示例:pid /var/log/nginx.pid;
注意:可以使用命令kill -HUP cat /var/log/nginx.pid\ 对Nginx进行进程ID文件的重新加载。
5. ssl_engine
含义:指定使用的openssl引擎。
语法:ssl_engine engine;
缺省:视系统而定
示例:
注意:你可以使用openssl engine -t命令来查看系统目前支持的openssl引擎。
6. timer_resolution
略
7. user
含义:指定可以使用Nginx的用户
语法:user <user> [group]
缺省:nobody nobody(第一个nobody是user,第二个nobody是group)
示例:user www users;
8. worker_processes
含义:指定worker进程数
语法:worker_processes <number>
缺省:1
示例:worker_processes 4;
注意:最大用户连接数=worker进程数×worker连接数,即max_clients=worker_processes*worker_connections。
9. worker_cpu_affinity
含义:为worker进程绑定CPU。
语法:worker_cpu_affinity cpumask [cpumask...]
缺省:none
示例:
(1)如果有4个CPU,并且指定4个worker进程,则:
worker_processes 4;
worker_cpu_affinity 0001 0010 0100 1000;
(2)如果有4个CPU,并且指定2个worker进程,则:
worker_processes 2;
worker_cpu_affinity 0101 1010;
注意:只有Linux平台上才可以使用该指令。
10. worker_priority
含义:指定各worker进程的优先级
语法:worker_priority [-] <number>;
缺省:on
示例:
注意:使用该指令可以给woker进程分配优先值。
11. worker_rlimit_core
含义:指定每个worker进程的core文件最大size。
语法:worker_rlimit_core <max_size>;
12. worker_rlimit_nofile
含义:worker进程的file descriptor可以打开的最大文件数。
语法:worker_rlimit_nofile <number>;
13. worker_rlimit_sigpending
略
(8)核心模块之事件模块
一、事件模块的作用是什么?
用来设置Nginx处理链接请求。
二、相关指令
1. accept_mutex
含义:设置是否使用连接互斥锁进行顺序的accept()系统调用。
语法:accept_mutex <on|off>;
缺省:on
示例:accept_mutex off;
2. accept_mutex_delay
含义:设置获得互斥锁的最少延迟时间。
语法:accpet_mutex_delay <number of millisecs>
缺省:500ms
示例:accpet_mutex_delay 1000ms;
3. debug_connection
含义:设置指定的clients产生debug日志。
语法:debug_connection [ip|CIDR];
缺省:none
示例:debug_connection 172.16.44.96;
一段较完整的事件模块代码如下:
error_log /data/nginx/log/error.log;
events {
debug_connection172.16.44.96;
}
4. multi_accept
含义:设置是否允许,Nginx在已经得到一个新连接的通知时,接收尽可能更多的连接。
语法:multi_accept <on|off>;
缺省:off
示例:multi_accept on;
5. rtsig_signo
略
6. rtsig_overflow_threshold
7. use
语法:use [kqueue | rtsig | epoll | /dev/poll | select | poll | eventport];
注意:如果在./configure的时候指定了不止一种事件模型,那么可以设置其中一个,告诉Nginx使用哪种事件模型。默认情况下,Nginx会在./configure时找出最适合系统的事件模型。
8. worker_connections
语法:worker_connection <number>;
注意:
最大连接数的计算公式如下:
max_clients = worker_processes * worker_connections;
如果作为反向代理,因为浏览器默认会开启2个连接到server,而且Nginx还会使用fds(file descriptor)从同一个连接池建立连接到upstream后端。则最大连接数的计算公式如下:
max_clients = worker_processes * worker_connections / 4;
(9)核心模块之HTTP模块基本常用指令
一、HTTP模块的作用是什么?
Nginx的HTTP模块用于控制Nginx的HTTP进程。
二、指令
1. alias
含义:指定location使用的路径,与root类似,但不改变文件的跟路径,仅适用文件系统的路径。
语法:alias <file-path | directory-path>
缺省:N/A
作用域:http.server.location
示例:
location /i/ {
alias /home/michael/web/i/;
}
则请求 /i/logo.png 则返回 /home/michael/web/i/logo.png。
注意:
(1)替换路径时,可以使用变量。
(2)alias无法在正则的location中使用。如果有这种需求,则必须使用rewrite和root。
2. client_body_in_file_only
含义:指定是否将用户请求体存储到一个文件里。
语法:client_body_in_file_only <on | off>
缺省:off
作用域:http.server.location
示例:client_body_in_file_only on;
注意:
(1)该指令为on时,用户的请求体会被存储到一个文件中,但是请求结束后,该文件也不会被删除;
(2)该指令一般在调试的时候使用。
3. client_body_buffer_size
含义:指定用户请求体所使用的buffer的最大值
语法:client_body_buffer_size <size>
缺省:两个page的大小,一般为8k或16k
作用域:http.server.location
示例:client_body_buffer_size 512k;
注意:如果用户请求体超过了buffer的大小,则将全部内容或部分内容存储到一个临时文件中。
4. client_body_temp_path
含义:设置存储用户请求体的文件的目录路径
语法:client_body_temp_path <directory path> [level1 | level2 | level3]
作用域:http.server.location
示例:client_body_temp_path /spool/nginx/client_temp 1 2;
5. client_body_timeout
含义:设置用户请求体的超时时间。
语法:client_body_timeout <time>
作用域:http.server.location
示例:client_body_timeout 120s;
注意:只有请求体需要被1次以上读取时,该超时时间才会被设置。且如果这个时间后用户什么都没发,nginx会返回requests time out 408.
6. client_header_buffer_size
含义:设置用户请求头所使用的buffer大小
语法:client_header_buffer_size <size>
缺省:1k
作用域:http.server
示例:client_header_buffer_size 2k;
注意:
(1)对绝大多数请求来说,1k足以满足请求头所需的buffer;
(2)对于携带有较大cookie或来自于wap用户的请求头来说,1k的buffer一般不够,这时可以使用指令large_client_header_buffers。
7. client_header_timeout
含义:设置用户请求头的超时时间。
语法:client_header_timeout <time>
缺省:1m
作用域:http.server.location
示例:client_header_timeout 3m;
注意:只有请求头需要被1次以上读取时,该超时时间才会被设置。且如果这个时间后用户什么都没发,nginx会返回requests time out 408.
8. client_max_body_size
含义:设置所能接收的最大请求体的大小
语法:client_max_body_size <size>
缺省:1m
作用域:http.server.location
示例:client_max_body_size 2m;
注意:根据请求头中的Content-Length来判断请求体大小是否允许。如果大于设定值,则返回“ Request Entity Too Large”(413)错误。不过要注意的是,浏览器一般并不对这个错误进行特殊显示。
(10)核心模块之HTTP模块Location相关指令
一、基本语法
语法:location [= | ~ | ~* | ^~] </uri/> {...}
缺省:N/A
作用域:server
二、匹配规则
1. 四种匹配方式
= 精确匹配
~ 大小写敏感正则匹配
~* 大小写不敏感正则匹配
^~ 前缀匹配
2. location匹配指令的执行顺序
首先:= 精确匹配;
其次:^~ 前缀匹配;
再次:~* 和 ~ 正则匹配,顺序依据出现顺序;
最后:如果出现正则匹配成功,则采用该正则匹配;如果无可匹配正则,则采用前缀匹配结果。
三、常用指令
1. internal
含义:表示请求必须来自内部,外部请求会丢给404页面。
语法:internal;
作用域:location
(11)应用模块之Memcached模块的两大应用场景
一、应用场景1
最近在一个项目中,用到了Nginx的Memcached模块,所以就在这个系列教程中提前把Memcached模块拿出来写了。另外发现最近我的博客文章频频被很多用采集器的网站拿走,帮我发扬光大,都不听我说声谢谢。在此还是希望我的博文被转载的时候能够被注明出处,满足下我小小的虚荣心。
现在有这样一种应用场景:
客户端Client通过Nginx反向代理,访问服务器Server。每次访问的内容就是将文件File传到Server上,然后可以访问到File的URL被广播到所有Client上,每个Client再加载File。
Analysis:
这么多Client同时加载File,对Server的压力一定很大吧?读者朋友肯定会说,有了Nginx反向代理,Client访问Server的时候,相应访问的资源就可以被Nginx缓存,减轻了Server的压力。但有一点要注意,如果这样的话,Nginx反向代理配置的缓存是在有Client访问到Nginx时才会从Server拿来缓存到Nginx上。可是广播后,所有Client加载File是同时的,如果等地一个访问请求到来并使得Nginx产生缓存后,其他Client接收到广播后的加载响应,恐怕早已经发起并且接近尾声了。负载压力还是落到Server上。怎么办呢?
Solution Overview:
某个Client上传File到Server的同时,将File内容写入到Nginx的缓存中,然后广播后,Client加载File的请求在到达Nginx时去缓存中查找,那么基本是100%命中。
Deployment Solution:
(1)Reverse-Server(192.168.0.1):反向代理服务器,用Nginx实现。对外提供11000端口,接收到HTTP请求后到Cache-Server的14000端口的缓存服务中查找,如果有则返回,如果没有则将请求传递给Store-Server的12000端口。
(2)Store-Server(192.168.0.2):文件存储服务器,用FastDFS实现。对外提供12000端口用于下载,接收来自Reverse-Sever的HTTP请求。对外还提供12500端口用于上传。
(3)Process-Server(192.168.0.3):业务处理服务器,对外提供13000端口,接收Client传递来的File,并将File通过Store-Server的12500端口转储到Store-Server中。
(4)Cache-Server(192.168.0.4):文件缓存服务器,用Memcached实现,对外提供14000端口。接收来自Reverse-Server的读操作,和Process-Server的写操作。
Configuration Solution:
(1)FastDFS的配置与部署,请参见GoogleCode上的FastDFS相关wiki。
(2)Memcached部署很简单,wget,tar,./configure,make,make install就OK了。
(3)Process-Server是由我自己实现的,不具有通用性就不说了。
(4)Reverse-Server的Nginx配置文件中http模块中,建立一个用户解决该问题的server,配置方式如下:
view plaincopy to clipboardprint?
1. server {
2. listen 11000;
3. server_namelocalhost;
4.
5. default_typetext/html;
6.
7. location / {
8. proxy_set_headerX-Real-IP $remote_addr;
9. proxy_set_headerHost $http_host;
10. proxy_set_headerX-Forwarded-For $proxy_add_x_forwarded_for;
11.
12. if ($request_method = POST) {
13. proxy_pass http://192.168.0.2:12000;
14. break;
15. }
16.
17. set $memcached_key "$uri";
18. memcached_pass 192.168.0.4:14000;
19.
20. error_page 501 404 502 = /fallback$uri;
21. }
22.
23. location /fallback/ {
24. internal;
25.
26. proxy_set_header X-Real-IP $remote_addr;
27. proxy_set_header Host $http_host;
28. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
29.
30. proxy_redirect off;
31.
32. proxy_pass http://192.168.0.2:12000
33. }
34. }
Details
Nginx的Memcached模块只提供对Memcached的读操作,不提供写操作。如果Memcached中没有相应的键值,即未命中,则返回404。如果请求未能找到Memcached Server,则返回502错误。因此,我们可以采用这样一种方式:当返回这类错误时,将请求交给Store-Server。这样只有在不命中时才访问Store-Server,缓存服务器由此可以为存储服务器分担很多负载。
二、应用场景2
在应用场景1中,将不命中时的逻辑换作向Memcached的写操作。这种场景的服务器系统部署方案如下:
(1)Reverse-Server:Client访问该服务器的11000端口,请求被转至Cache-Server的14000端口,如果Cache-Server命中则response;否则交给Process-Server的13000端口,进行进一步的处理。
(2)Data-Server:对外提供12000端口,用于读取数据。
(3)Process-Server:提供13000端口,用于接收Reverse-Server转发来的HTTP请求,到Store-Server的12000端口查询,并将得到的Value与从Reverse-Server发来的Key值共同构成K-V对,通过Cache-Server的14000端口写入Cache-Server。
(4)Cache-Server:提供14000端口,用于对外提供读写操作。
这是的Nginx的Memcached模块配置,要将request的方法为post和error_log,不再是如“应用场景1”中那样转至Store-Server,而是都转至Process-Server去。因为应用场景1中,向Cache写的操作,是预先完成的。而应用场景2中向Cache写的操作,是在读Cache失败后发生的。注意这两者适用的业务需求。
(12)应用模块之Memcached做文件缓存时压缩引起的问题
在上一篇文章中,提到的Nginx的Memcached模块应用场景,主要是作为文件缓存。然后就发现了一个问题,当以字节数组方式缓存较大的文件时,缓存数据会被压缩,从而在读取的时候出现问题。
解决方法很简单,就是在MemcachedClient端设置压缩的阈值。如果你使用的是net.spy.memcached的API,则可以如下设置:
view plaincopy to clipboardprint?
1. int EXPIRE_SECONDS = 18000;
2. SerializingTranscoder transcoder = new SerializingTranscoder();
3. transcoder.setCompressionThreshold(5242880);
4. fileCache.set(key, EXPIRE_SECONDS, value, transcoder);
如果你使用的是net.rubyeye.xmemcached的API,则可以如下设置:
view plaincopy to clipboardprint?
1. int EXPIRE_SECONDS = 18000;
2. BaseSerializingTranscoder transcoder = new BaseSerializingTranscoder();
3. transcoder.setCompressionThreshold(5242880);
4. client = set(key, EXPIRE_SECONDS, value, transcoder);
如果你使用的是danga.MemCached的API,则可以如下设置:
view plaincopy to clipboardprint?
1. int EXPIRE_SECONDS = 18000;
2. MemCachedClient.setCompressThreshold(5242880);
3. MemCachedClient.set(key, value, new Date(System.currentTimeMillis() + EXPIRE_SECONDS * 1000L));
|
|