控制nginx
信号可以用来控制nginx。nginx的主进程ID号默认写入/usr/local/nginx/logs/nginx.pid文件,可以在配置阶段修改文件名,或者在nginx.conf中使用pid指令进行修改。主进程支持以下信号:
- TERM, INT 立即关闭
- QUIT 正常关闭
- HUP 修改配置,保持变更的时区(仅对于FreeBSD和Linux),以新的配置启动新的工作进程,并正常关闭旧的工作进程。
- USR1 重新打开日志文件
- USR2 更新可执行文件
- WINCH 正常关闭工作进程
单独的工作进程也能被信号控制,尽管这不是必须的。支持的信号有:
- TERM, INT 立即关闭
- QUIT 正常关闭
- USR1 重新打开日志文件
- WINCH 因调试异常中止 (需要启用debug_points)
修改配置文件
发送HUP信号到主进程,nginx将重新读取配置文件。主进程在接受到HUP信号后,先检验配置文件的语法正确性,再尝试应用新的配置,即打开日志文件和新的监听套接字。若应用配置文件失败,回滚到先前的配置;若应用成功,启动新的工作进程,并发送消息给旧的工作进程要求它们正常关闭。旧的工作进程关闭监听的套接字并继续为旧的客户端服务。所有客户端被新的工作进程服务以后,旧的工作进程被关闭。
举个例子,假设nginx在FreeBSD 4.x下运行,执行以下命令:
ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
生成以下输出:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 33127 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33128 33126 nobody 0.0 1364 kqread nginx: worker process (nginx) 33129 33126 nobody 0.0 1364 kqread nginx: worker process (nginx)
编号为33129的旧工作进程仍然继续工作,一段时间后退出:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx)
滚动日志文件
为了滚动日志文件,需要先重命名日志文件,再发送USR1信号到主进程。主进程将会重新打开当前已打开的所有日志文件,并标示它们未授权的用户身份(工作进程运行的权限)。在重新打开成功后,主进程关闭所有打开的文件,发送消息给工作进程要求它们重新打开文件。于是工作进程立即打开新的文件并关闭旧的文件。因此,旧的文件几乎能立即响应post处理,例如压缩。
动态更新可执行文件
为了更新服务器可执行文件,需要先用新的可执行文件替代旧的,再发送USR2信号给主进程。主进程重命名它的进程ID文件,以.oldbin作为后缀,例如:/usr/local/nginx/logs/nginx.pid.oldbin,接着启动新的可执行文件,并相应地启动新的工作进程。
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 33135 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
在这之后所有的工作进程(新的和旧的)继续接受请求。如果发送WINCH信号到第一个主进程,它将发送消息给它的工作进程,请求它们正常关闭,接着这些工作进程开始退出:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 33135 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
当在Linux下使用“rtsig”方法时,在发送WINCH信号给旧的主进程后,新的进程可能不会接受任何连接请求。如果是这样,需要同步发送USR1信号给新的主进程,直到新的进程开始接受连接请求。
一段时间后,只有新的工作进程将会处理请求:
PID PPID USER %CPU VSZ WCHAN COMMAND 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
注意,旧的主进程不会关闭它所监听的套接字,在需要的情况下它能再次启动它的工作进程。如果由于某些原因新的可执行文件在执行时有误,可以按照下面的方式来解决:
- 发送HUP信号给旧的主进程,旧的主进程不需要重新读取配置便启动新的工作进程。启动完成后,所有新的进程可以被正常关闭,通过发送QUIT信号给新的主进程。
- 发送TERM信号给新的主进程。它将发送消息给它的工作进程请求立即退出,工作进程几乎在同时会立即退出。(如果新的进程由于一些原因不能退出,发送KILL信号强制它们退出。)当新的主进程退出,旧的主进程可以自动启动新的工作进程。
如果新的主进程退出,旧的主进程将会撤消进程ID文件的.oldbin后缀。
如果更新成功,需要发送QUIT信号给旧的主进程,仅保留新的进程:
PID PPID USER %CPU VSZ WCHAN COMMAND 36264 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx)
连接处理方法
nginx支持各种连接处理方法。对于每种特定的方法都需要有平台的支持,在支持多种方法的平台下nginx会自动选用最高效的方法。然而,如有需要,可以使用use指令显式指定所采用的连接处理方法。
以下的连接处理方法为nginx所支持的:
- select —— 标准方法。在缺少更多高效方法的平台下这个模块是被自动编译的。--with-select_module以及--without-select_module配置参数可以被用来强制启用或禁用对这个模块的编译。
- poll —— 标准方法。在缺少更多高效方法的平台下这个模块是被自动编译的。--with-poll_module和--without-poll_module配置参数可以被用来强制启用或禁用对这个模块的编译。
- kqueue —— 用在FreeBSD 4.1+,OpenBSD 2.9+,NetBSD 2.0以及Mac OS X下的高效模块。
- epoll —— 用在Linux 2.6+下的高效模块。
一些老的分发版像SuSE 8.2提供添加epoll支持到2.4内核的补丁。
- rtsig —— 实时信号,用在Linux 2.2.19+的高效模块。系统默认提供的事件队列限制在1024个信号。在负载服务器上可能有必要修改/proc/sys/kernel/rtsig-max内核参数来提高这个限制。然而,在Linux 2.66-mm2里不存在这个参数,现在所有进程有它自己的事件队列。每个队列的大小通过RLIMIT_SIGPENDING来指定,并可以通过worker_rlimit_sigpending来改变。
队列溢出时,nginx取消队列并回到利用poll连接请求方法,直到情况正常为止。
- /dev/poll —— 用在Solaris 77 11/99+,HP/UX 11.22+(eventport),IRIX 6.5.15+以及Tru64 UNIX 5.1A+下的高效模块。
- eventport —— 事件端口,用在Solaris 10下的高效方法。
设置hashes
为了快速处理静态数据集例如服务器名称、map指令的值、MIME类型、请求头字符串的名称,nginx使用hash表。在启动和每次重新配置过程中,nginx选择最小可能的hash表大小,例如桶大小,可以用来保存键和相同大小的hash值而不超过配置参数(hash桶大小)。hash表的大小以桶来表示。持续校准直到表大小超过hash最大值参数。大多数hash有对应的指令可以用来改变这些参数,例如,对于服务器名称,它们是server_names_hash_max_size和server_names_hash_bucket_size。
hash桶大小参数指定的大小是处理器cache大小的倍数。在现代处理器中这会减少内存访问次数,从而加快hash键的查找。如果hash桶大小同处理器cache大小相等,那么在最坏的情况下对键的查找中访存次数为2次——第一次计算桶地址,第二次在桶中查询键。因此,如果nginx发出增加hash最大值或hash桶大小的消息,那第一个参数将会被首先增加。
调试日志
要启用调试日志,nginx需要在编译时配置为支持调试:
./configure --with-debug...
接着使用error_log指令设置调试级别:
error_log /path/to/log debug;
Windows下的nginx二进制版本通常被编译为支持调试日志,因此只需要设置调试级别就可以了。
重新定义日志而没有指定调试级别将会禁用调试日志。在下面的例子中,在server级别上重新定义日志会禁用这个服务器的调试日志。
error_log /path/to/log debug; http { server { error_log /path/to/log; ...
为了防止这个,可以注释掉重定义日志的那行,或者添加调试级别的说明:
error_log /path/to/log debug; http { server { error_log /path/to/log debug; ...
也可以仅为selected_client_addresses启用调试日志:
error_log /path/to/log; events { debug_connection 192.168.1.1; debug_connection 192.168.10.0/24; }
配置文件计量单元
大小可以指定为bytes、kilobytes(后缀为k和K)或者megabytes(后缀为m和M),例如:“1024”、“8k”或“1M”。
时间间隔可以指定为毫秒、秒、分、时、天等等,使用以下后缀:
- ms 毫秒
- s 秒
- m 分
- h 时
- d 天
- w 周
- M 月,30天
- y 年,365天
计量单位可以合并为单个数值,按照从大到小的顺序指定,可以选择用空格分割,例如:“1h 30m”可以指定为“90m”或者“5400s”。没有后缀的值表示秒。推荐使用后缀指定。
一些时间间隔仅可以用秒来指定。
Windows版nginx
Windows版的nginx使用原生的Win32 API(不是采用Cygwin模拟层)。现在只有select()连接处理方法被使用,因此高性能和可扩展性是不被期望的。因为这以及一些其他大家知道的原因,Windows版本的nginx被认为是beta版。在Windows下nginx的beta版,除了XSLT过滤、图像过滤、GeoIP模块和内置的Perl语言,它几乎提供了UNIX版nginx的所有功能。
安装windows下的nginx,下载最新开发版本(1.3.15),因为nginx开发分支包含所有已知的修正。解压分发版,进入nginx-1.3.15目录,运行nginx。以下是驱动器C:根目录下的例子:
cd c:\ unzip nginx-1.3.15.zip cd nginx-1.3.15 start nginx
运行tasklist命令行组件来查看nginx进程:
C:\nginx-1.3.15>tasklist /fi "imagename eq nginx.exe" Image Name PID Session Name Session# Mem Usage =============== ======== ============== ========== ============ nginx.exe 652 Console 0 2 780 K nginx.exe 1332 Console 0 3 112 K
其中之一为主进程,另外一个是工作进程。如果nginx无法启动,可以在错误日志文件logs\error.log里查看原因。如果日志文件已经被创建,错误原因可以在Windows事件日志里查看。如果显示的是错误页面而不是期望的页面,也可以在logs\error.log文件里查看原因。
Windows下nginx使用它运行时的目录作为配置中相对路径的前缀。对于上面的例子,前缀为C:\nginx-1.3.15\。另外,配置文件中路径的指定必须采用UNIX风格,即使用斜杠:
access_log logs/site.log; root C:/web/html;
Windows下nginx以标准控制台程序运行(不是服务),而且可以通过以下命令管理:
- nginx -s stop 立即关闭
- nginx -s quit 正常关闭
- nginx -s reload 修改配置,用新的配置启动新的工作进程,正常关闭旧的工作进程
- nginx -s reopen 重新打开日志文件
已知问题
- 尽管可以启动多个工作进程,但是实际只有其中一个工作。
- 一个工作进程可以同时处理不多于1024个连接。
- 需要共享内存支持的cache模块和其他模块在Windows Vista以及更高版本下无法工作,因为在这些Windows版本中启用了地址空间布局随机化。
未来可能的改进
- 以服务运行
- 使用I/O完成端口作为连接处理方法
- 在单个工作进程里使用多个工作线程
介绍篇中还未翻译的有以下三篇,之后会额外进行翻译。PS:初次翻译,问题肯定有很多,欢迎拍砖!