免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2644 | 回复: 0
打印 上一主题 下一主题

高性能Web服务器Nginx的配置与部署研究 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-01-07 01:56 |只看该作者 |倒序浏览
高性能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));  


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP