好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

“小白”带你们了解有关于Nginx的模块与工作原理吧!!!

nginx支持的事件模型如下(nginx的wiki):

Nginx支持如下处理连接的方法(I/O复用方法),这些方法可以通过use指令指定。

select – 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-select_module 和 –without-select_module 来启用或禁用这个模块。 poll – 标准方法。 如果当前平台没有更有效的方法,它是编译时默认的方法。你可以使用配置参数 –with-poll_module 和 –without-poll_module 来启用或禁用这个模块。 kqueue – 高效的方法,使用于 FreeBSD 4.1+, OpenBSD 2.9+, NetBSD 2.0 和 MacOS X. 使用双处理器的MacOS X系统使用kqueue可能会造成内核崩溃。 epoll – 高效的方法,使用于Linux内核2.6版本及以后的系统。在某些发行版本中,如SuSE 8.2, 有让2.4版本的内核支持epoll的补丁。 rtsig – 可执行的实时信号,使用于Linux内核版本2.2.19以后的系统。默认情况下整个系统中不能出现大于1024个POSIX实时(排队)信号。这种情况 对于高负载的服务器来说是低效的;所以有必要通过调节内核参数 /proc/sys/kernel/rtsig-max 来增加队列的大小。可是从Linux内核版本2.6.6-mm2开始, 这个参数就不再使用了,并且对于每个进程有一个独立的信号队列,这个队列的大小可以用 RLIMIT_SIGPENDING 参数调节。当这个队列过于拥塞,nginx就放弃它并且开始使用 poll 方法来处理连接直到恢复正常。 /dev/poll – 高效的方法,使用于 Solaris 7 11/99+, HP/UX 11.22+ (eventport), IRIX 6.5.15+ 和 Tru64 UNIX 5.1A+. eventport – 高效的方法,使用于 Solaris 10. 为了防止出现内核崩溃的问题, 有必要安装这个 安全补丁。

在linux下面,只有epoll是高效的方法

下面再来看看epoll到底是如何高效的
Epoll是Linux内核为处理大批量句柄而作了改进的poll。 要使用epoll只需要这三个系统调用:epoll_create(2), epoll_ctl(2), epoll_wait(2)。它是在2.5.44内核中被引进的(epoll(4) is a new API introduced in Linux kernel 2.5.44),在2.6内核中得到广泛应用。

epoll的优点

支持一个进程打开大数目的socket描述符(FD)

select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显 然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会带来网络效率的下降,二是可以选择多进程的解决方案(传统的 Apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完 美的方案。不过 epoll则没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左 右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。

IO效率不随FD数目增加而线性下降

传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是”活跃”的,但 是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对”活跃”的socket进行操 作—这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有”活跃”的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个”伪”AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的—比如一个高速LAN环境,epoll并不比select/poll有什么效率,相 反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。

使用mmap加速内核与用户空间的消息传递。

这 点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很 重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。

内核微调

这一点其实不算epoll的优点了,而是整个linux平台的优点。也许你可以怀疑linux平台,但是你无法回避linux平台赋予你微调内核的能力。比如,内核TCP/IP协 议栈使用内存池管理sk_buff结构,那么可以在运行时期动态调整这个内存pool(skb_head_pool)的大小— 通过echo XXXX>/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手 的数据包队列长度),也可以根据你平台内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网卡驱动架构。

(epoll内容,参考epoll_互动百科)

推荐设置worker的个数为cpu的核数,在这里就很容易理解了,更多的worker数,只会导致进程来竞争cpu资源了,从而带来不必要的上下文切换。而且,nginx为了更好的利用多核特性,提供了cpu亲缘性的绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。像这种小的优化在nginx中非常常见,同时也说明了nginx作者的苦心孤诣。比如,nginx在做4个字节的字符串比较时,会将4个字符转换成一个int型,再作比较,以减少cpu的指令数等等。

代码来总结一下nginx的事件处理模型:

while (true) {
    for t in run_tasks:
   t.handler();
    update_time(&now);
    timeout = ETERNITY;
    for t in wait_tasks: /* sorted already */
   if (t.time <= now) {
  t.timeout_handler();
   } else {
  timeout = t.time - now;
  break;
   }
    nevents = poll_function(events, timeout);
    for i in nevents:
   task t;
   if (events[i].type == READ) {
  t.handler = read_handler;
   } else { /* events[i].type == WRITE */
  t.handler = write_handler;
   }
   run_tasks_add(t);
}

四. Nginx+FastCGI运行原理

1、什么是 FastCGI

FastCGI是一个可伸缩地、高速地在HTTP server和动态脚本语言间通信的接口。多数流行的HTTP server都支持FastCGI,包括Apache、Nginx和lighttpd等。同时,FastCGI也被许多脚本语言支持,其中就有PHP。

FastCGI是从CGI发展改进而来的。传统CGI接口方式的主要缺点是性能很差,因为每次HTTP服务器遇到动态程序时都需要重新启动脚本解析器来执行解析,然后将结果返回给HTTP服务器。这在处理高并发访问时几乎是不可用的。另外传统的CGI接口方式安全性也很差,现在已经很少使用了。

FastCGI接口方式采用C/S结构,可以将HTTP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HTTP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给浏览器。这种方式可以让HTTP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。

2、Nginx+FastCGI运行原理

Nginx不支持对外部程序的直接调用或者解析,所有的外部程序(包括PHP)必须通过FastCGI接口来调用。FastCGI接口在Linux下是socket(这个socket可以是文件socket,也可以是ip socket)。

wrapper: 为了调用CGI程序,还需要一个FastCGI的wrapper(wrapper可以理解为用于启动另一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,通过FastCGI接口,wrapper接收到请求,然后Fork(派生)出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据通过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据(html页面或者图片)发送给客户端。这就是Nginx+FastCGI的整个运作过程,如图1-3所示。

所以,我们首先需要一个wrapper,这个wrapper需要完成的工作:

通过调用fastcgi(库)的函数通过socket和ningx通信(读写socket是fastcgi内部实现的功能,对wrapper是非透明的) 调度thread,进行fork和kill 和application(php)进行通信

3、spawn-fcgi与PHP-FPM

FastCGI接口方式在脚本解析服务器上启动一个或者多个守护进程对动态脚本进行解析,这些进程就是FastCGI进程管理器,或者称为FastCGI引擎。 spawn-fcgi与PHP-FPM就是支持PHP的两个FastCGI进程管理器。 因此HTTPServer完全解放出来,可以更好地进行响应和并发处理。

spawn-fcgi与PHP-FPM的异同:
1)spawn-fcgi是HTTP服务器lighttpd的一部分,目前已经独立成为一个项目,一般与lighttpd配合使用来支持PHP。但是ligttpd的spwan-fcgi在高并发访问的时候,会出现内存泄漏甚至自动重启FastCGI的问题。即:PHP脚本处理器当机,这个时候如果用户访问的话,可能就会出现白页(即PHP不能被解析或者出错)。

2)Nginx是个轻量级的HTTP server,必须借助第三方的FastCGI处理器才可以对PHP进行解析, 因此其实这样看来 nginx 是非常灵活的,它可以和任何第三方提供解析的处理器实现连接从而实现对 PHP 的解析 ( 在 nginx.conf 中很容易设置 ) 。 nginx也 可以使用 spwan-fcgi( 需要一同安装 lighttpd ,但是需要为 nginx 避开端口,一些较早的 blog 有这方面安装的教程 ) ,但是由于 spawn-fcgi 具有上面所述的用户逐渐发现的缺陷,现在慢慢减少用 nginx+spawn-fcgi 组合了。

由于spawn-fcgi的缺陷,现在出现了第三方(目前已经加入到PHP core中)的PHP的FastCGI处理器PHP-FPM,它和spawn-fcgi比较起来有如下优点:

由于它是作为PHP的patch补丁来开发的,安装的时候需要和php源码一起编译,也就是说编译到php core中了,因此在性能方面要优秀一些;

同时它在处理高并发方面也优于spawn-fcgi,至少不会自动重启fastcgi处理器。因此,推荐使用Nginx+PHP/PHP-FPM这个组合对PHP进行解析。

相对Spawn-FCGI,PHP-FPM在CPU和内存方面的控制都更胜一筹,而且前者很容易崩溃,必须用crontab进行监控,而PHP-FPM则没有这种烦恼。
FastCGI 的主要优点是把动态语言和HTTP Server分离开来,所以Nginx与PHP/PHP-FPM经常被部署在不同的服务器上,以分担前端Nginx服务器的压力,使Nginx专一处理静态请求和转发动态请求,而PHP/PHP-FPM服务器专一解析PHP动态请求。

4、Nginx+PHP-FPM

PHP-FPM是管理FastCGI的一个管理器,它作为PHP的插件存在,在安装PHP要想使用PHP-FPM时在老php的老版本(php5.3.3之前)就需要把PHP-FPM以补丁的形式安装到PHP中,而且PHP要与PHP-FPM版本一致,这是必须的)

  PHP-FPM其实是PHP源代码的一个补丁,旨在将FastCGI进程管理整合进PHP包中。必须将它patch到你的PHP源代码中,在编译安装PHP后才可以使用。
  PHP5.3.3已经集成php-fpm了,不再是第三方的包了。PHP-FPM提供了更好的PHP进程管理方式,可以有效控制内存和进程、可以平滑重载PHP配置,比spawn-fcgi具有更多优点,所以被PHP官方收录了。在./configure的时候带 –enable-fpm参数即可开启PHP-FPM。

fastcgi已经在php5.3.5的core中了,不必在configure时添加 --enable-fastcgi了。老版本如php5.2的需要加此项。

当我们安装Nginx和PHP-FPM完后,配置信息:

PHP-FPM的默认配置php-fpm.conf:

listen_address 127.0.0.1:9000 #这个表示php的fastcgi进程监听的ip地址以及端口

start_servers

min_spare_servers

max_spare_servers

Nginx配置运行php: 编辑nginx.conf加入如下语句:

location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000; 指定了fastcgi进程侦听的端口,nginx就是通过这里与php交互的
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
}

Nginx 通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理,而这里的IP地址和端口就是FastCGI进程监听的IP地址和端口。

其整体工作流程:

1)、FastCGI进程管理器php-fpm自身初始化,启动主进程php-fpm和启动 start_servers 个CGI 子进程。

主进程php-fpm主要是管理fastcgi子进程,监听9000端口。

fastcgi子进程 等待来自Web Server的连接。

2)、当客户端请求到达Web Server Nginx是时, Nginx 通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理,即 Nginx 通过location指令,将所有以php为后缀的文件都交给127.0.0.1:9000来处理。

3)FastCGI进程管理器PHP-FPM选择并连接到一个子进程CGI解释器。Web server将CGI环境变量和标准输入发送到FastCGI子进程。

4)、FastCGI子进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当FastCGI子进程关闭连接时,请求便告处理完成。

5)、FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在 WebServer中)的下一个连接。

五. Nginx+PHP正确配置

一般web都做统一入口:把PHP请求都发送到同一个文件上,然后在此文件里通过解析「REQUEST_URI」实现路由。

Nginx配置文件分为好多块,常见的从外到内依次是「http」、「server」、「location」等等,缺省的继承关系是从外到内,也就是说内层块会自动获取外层块的值作为缺省值。

例如:

server {
    listen 80;
    server_name foo测试数据;
    root /path;
    location / {
   index index.html index.htm index.php;
   if (!-e $request_filename) {
  rewrite . /index.php last;
   }
    }
    location ~ \.php$ {
   include fastcgi_params;
   fastcgi_param SCRIPT_FILENAME /path$fastcgi_script_name;
   fastcgi_pass 127.0.0.1:9000;
   fastcgi_index index.php;
    }
}

1) 不应该在 location 模块定义index

一旦未来需要加入新的「location」,必然会出现重复定义的「index」指令,这是因为多个「location」是平级的关系,不存在继承,此时应该在「server」里定义「index」,借助继承关系,「index」指令在所有的「location」中都能生效。

2) 使用 try_files

接下来看看「if」指令,说它是大家误解最深的Nginx指令毫不为过:

if (!-e $request_filename) {
rewrite . /index.php last;
}

很多人喜欢用「if」指令做一系列的检查,不过这实际上是「try_files」指令的职责:

try_files $uri $uri/ /index.php;

除此以外,初学者往往会认为「if」指令是内核级的指令,但是实际上它是rewrite模块的一部分,加上Nginx配置实际上是声明式的,而非过程式的,所以当其和非rewrite模块的指令混用时,结果可能会非你所愿。

3)fastcgi_params」配置文件 :

include fastcgi_params;

Nginx有两份fastcgi配置文件,分别是「fastcgi_params」和「fastcgi.conf」,它们没有太大的差异,唯一的区别是后者比前者多了一行「SCRIPT_FILENAME」的定义:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

注意:$document_root 和 $fastcgi_script_name 之间没有 /。

原本Nginx只有「fastcgi_params」,后来发现很多人在定义「SCRIPT_FILENAME」时使用了硬编码的方式,于是为了规范用法便引入了「fastcgi.conf」。

不过这样的话就产生一个疑问:为什么一定要引入一个新的配置文件,而不是修改旧的配置文件?这是因为「fastcgi_param」指令是数组型的,和普通指令相同的是:内层替换外层;和普通指令不同的是:当在同级多次使用的时候,是新增而不是替换。换句话说,如果在同级定义两次「SCRIPT_FILENAME」,那么它们都会被发送到后端,这可能会导致一些潜在的问题,为了避免此类情况,便引入了一个新的配置文件。

此外,我们还需要考虑一个安全问题:在PHP开启「cgi.fix_pathinfo」的情况下,PHP可能会把错误的文件类型当作PHP文件来解析。如果Nginx和PHP安装在同一台服务器上的话,那么最简单的解决方法是用「try_files」指令做一次过滤:

try_files $uri =404;

依照前面的分析,给出一份改良后的版本,是不是比开始的版本清爽了很多:

server {
    listen 80;
    server_name foo测试数据;
    root /path;
    index index.html index.htm index.php;
    location / {
   try_files $uri $uri/ /index.php;
    }
    location ~ \.php$ {
  try_files $uri =404;
  include fastcgi.conf;
  fastcgi_pass 127.0.0.1:9000;
   }
}

六. Nginx优化

1. 编译安装过程优化

1).减小Nginx编译后的文件大小

在编译Nginx时,默认以debug模式进行,而在debug模式下会插入很多跟踪和ASSERT之类的信息,编译完成后,一个Nginx要有好几兆字节。而在编译前取消Nginx的debug模式,编译完成后Nginx只有几百千字节。因此可以在编译之前,修改相关源码,取消debug模式。具体方法如下:

在Nginx源码文件被解压后,找到源码目录下的auto/cc/gcc文件,在其中找到如下几行:

 # debug  
CFLAGS=”$CFLAGS -g”

nginx可以使用多个worker进程,原因如下:

to use SMP
to decrease latency when workers blockend on disk I/O
to limit number of connections per process when select()/poll() is

used The worker_processes and worker_connections from the event sections

allows you to calculate maxclients value: k max_clients = worker_processes * worker_connections

worker_rlimit_nofile 102400;

每个nginx进程打开文件描述符最大数目 配置要和系统的单进程打开文件数一致,linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535 nginx调度时分配请求到进程并不是那么的均衡,假如超过会返回502错误。我这里写的大一点

use epoll

Nginx使用了最新的epoll(Linux 2.6内核)和kqueue(freebsd)网络I/O模型,而Apache则使用的是传统的select模型。

处理大量的连接的读写,Apache所采用的select网络I/O模型非常低效。在高并发服务器中,轮询I/O是最耗时间的操作 目前Linux下能够承受高并发

访问的Squid、Memcached都采用的是epoll网络I/O模型。

worker_processes

NGINX工作进程数(默认值是1)。在大多数情况下,一个CPU内核运行一个工作进程最好,建议将这个指令设置成自动就可以。有时可能想增大这个值,比如当工作进程需要做大量的磁盘I/O。

worker_connections 65535;
每个工作进程允许最大的同时连接数 (Maxclient = work_processes * worker_connections)

keepalive_timeout 75

keepalive超时时间

这里需要注意官方的一句话:
The parameters can differ from each other. Line Keep-Alive:

timeout=time understands Mozilla and Konqueror. MSIE itself shuts

keep-alive connection approximately after 60 seconds.

client_header_buffer_size 16k
large_client_header_buffers 4 32k
客户请求头缓冲大小
nginx默认会用client_header_buffer_size这个buffer来读取header值,如果header过大,它会使用large_client_header_buffers来读取

如果设置过小HTTP头/Cookie过大 会报400 错误 nginx 400 bad request
求行如果超过buffer,就会报HTTP 414错误(URI Too Long) nginx接受最长的HTTP头部大小必须比其中一个buffer大,否则就会报400的HTTP错误(Bad Request)。

open_file_cache max 102400

使用字段:http, server, location 这个指令指定缓存是否启用,如果启用,将记录文件以下信息: ·打开的文件描述符,大小信息和修改时间. ·存在的目录信息. ·在搜索文件过程中的错误信息 -- 没有这个文件,无法正确读取,参考open_file_cache_errors 指令选项:
·max - 指定缓存的最大数目,如果缓存溢出,最长使用过的文件(LRU)将被移除
例: open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;

open_file_cache_errors
语法:open_file_cache_errors on | off 默认值:open_file_cache_errors off 使用字段:http, server, location 这个指令指定是否在搜索一个文件是记录cache错误.

open_file_cache_min_uses

语法:open_file_cache_min_uses number 默认值:open_file_cache_min_uses 1 使用字段:http, server, location 这个指令指定了在open_file_cache指令无效的参数中一定的时间范围内可以使用的最小文件数,如 果使用更大的值,文件描述符在cache中总是打开状态.
open_file_cache_valid

语法:open_file_cache_valid time 默认值:open_file_cache_valid 60 使用字段:http, server, location 这个指令指定了何时需要检查open_file_cache中缓存项目的有效信息.


开启gzip
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.0;
gzip_comp_level 2;
gzip_types text/plain application/x-javascript text/css

application/xml;
gzip_vary on;

缓存静态文件:

location ~* ^.+\.(swf|gif|png|jpg|js|css)$ {
root /usr/local/ku6/ktv/show.ku6测试数据/;
expires 1m;
}

响应缓冲区:

比如我们Nginx+Tomcat 代理访问JS无法完全加载,这几个参数影响:

proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 128k;

Nginx在代理了相应服务后或根据我们配置的UpStream和location来获取相应的文件,首先文件会被解析到nginx的内存或者临时文件目录中,然后由nginx再来响应。那么当proxy_buffers和proxy_buffer_size以及proxy_busy_buffers_size 都太小时,会将内容根据nginx的配置生成到临时文件中,但是临时文件的大小也有默认值。所以当这四个值都过小时就会导致部分文件只加载一部分。所以要根据我们的服务器情况适当的调整proxy_buffers和proxy_buffer_size以及proxy_busy_buffers_size、proxy_temp_file_write_size。具体几个参数的详细如下:

proxy_buffers 32 128k; 设置了32个缓存区,每个的大小是128k

proxy_buffer_size 128k; 每个缓存区的大小是128k,当两个值不一致时没有找到具体哪个有效,建议和上面的设置一致。

proxy_busy_buffers_size 128k;设置使用中的缓存区的大小,控制传输至客户端的缓存的最大

proxy_temp_file_write_size 缓存文件的大小

6.优化访问日志

记录每个请求会消耗CPU和I/O周期,一种降低这种影响的方式是缓冲访问日志。使用缓冲,而不是每条日志记录都单独执行写操作,NGINX会缓冲一连串的日志记录,使用单个操作把它们一起写到文件中。
要启用访问日志的缓存,就涉及到在access_log指令中buffer=size这个参数。当缓冲区达到size值时,NGINX会把缓冲区的内容写到日志中。让NGINX在指定的一段时间后写缓存,就包含flush=time参数。当两个参数都设置了,当下个日志条目超出缓冲区值或者缓冲区中日志条目存留时间超过设定的时间值,NGINX都会将条目写入日志文件。当工作进程重新打开它的日志文件或退出时,也会记录下来。要完全禁用访问日志记录的功能,将access_log 指令设置成off参数。

7.限流

你可以设置多个限制,防止用户消耗太多的资源,避免影响系统性能和用户体验及安全。 以下是相关的指令:
limit_conn and limit_conn_zone: NGINX接受客户连接的数量限制,例如单个IP地址的连接。设置这些指令可以防止单个用户打开太多的连接,消耗超出自己的资源。
limit_rate: 传输到客户端响应速度的限制(每个打开多个连接的客户消耗更多的带宽)。设置这个限制防止系统过载,确保所有客户端更均匀的服务质量。
limit_req and limit_req_zone: NGINX处理请求的速度限制,与limit_rate有相同的功能。可以提高安全性,尤其是对登录页面,通过对用户限制请求速率设置一个合理的值,避免太慢的程序覆盖你的应用请求(比如DDoS攻击)。
max_conns:上 游配置块中服务器指令参数。在上游服务器组中单个服务器可接受最大并发数量。使用这个限制防止上游服务器过载。设置值为0(默认值)表示没有限制。
queue (NGINX Plus) : 创建一个队列,用来存放在上游服务器中超出他们最大max_cons限制数量的请求。这个指令可以设置队列请求的最大值,还可以选择设置在错误返回之前最大等待时间(默认值是60秒)。如果忽略这个指令,请求不会放入队列。

七. 错误排查

1、Nginx 502 Bad Gateway:

作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。

常见原因:
1、后端服务挂了的情况,直接502 (nginx error日志:connect() failed (111: Connection refused) )
2、后端服务在重启
实例:将后端服务关掉,然后向nginx发送请求后端接口,nginx日志可以看到502错误。

如果nginx+php出现502, 错误分析:

php-cgi进程数不够用、php执行时间长(mysql慢)、或者是php-cgi进程死掉,都会出现502错误

一般来说Nginx 502 Bad Gateway和php-fpm.conf的设置有关,而Nginx 504 Gateway Time-out则是与nginx.conf的设置有关

1)、查看当前的PHP FastCGI进程数是否够用:

netstat -anpo | grep "php-cgi" | wc -l

  如果实际使用的“FastCGI进程数”接近预设的“FastCGI进程数”,那么,说明“FastCGI进程数”不够用,需要增大。

2)、部分PHP程序的执行时间超过了Nginx的等待时间,可以适当增加

nginx.conf配置文件中FastCGI的timeout时间,例如:

http {
......
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
......
}

2、504 Gateway Timeout :

nginx 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)收到响应。

常见原因:
该接口太耗时,后端服务接收到请求,开始执行,未能在设定时间返回数据给nginx
后端服务器整体负载太高,接受到请求之后,由于线程繁忙,未能安排给请求的接口,导致未能在设定时间返回数据给nginx

2、413 Request Entity Too Large

解决:增大client_max_body_size

client_max_body_size:指令指定允许客户端连接的最大请求实体大小,它出现在请求头部的Content-Length字段. 如果请求大于指定的值,客户端将收到一个"Request Entity Too Large" (413)错误. 记住,浏览器并不知道怎样显示这个错误.

php.ini中增大
post_max_size 和upload_max_filesize

3、 Ngnix error.log出现: upstream sent too big header while reading response header from upstream错误

1)如果是nginx反向代理
proxy是nginx作为client转发时使用的,如果header过大,超出了默认的1k,就会引发上述的upstream sent too big header (说白了就是nginx把外部请求给后端server,后端server返回的header 太大nginx处理不过来就导致了。

server {
listen 80;
server_name *.xywy测试数据 ;

large_client_header_buffers 4 16k;

location / {

#添加这3行
proxy_buffer_size 64k;
proxy_buffers 32 32k;
proxy_busy_buffers_size 128k;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

2) 如果是 nginx+PHPcgi

错误带有 upstream: "fastcgi://127.0.0.1:9000"。就该

多加:

fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;

server {
listen 80;
server_name ddd测试数据;
index index.html index.htm index.php;

client_header_buffer_size 128k;
large_client_header_buffers 4 128k;
proxy_buffer_size 64k;
proxy_buffers 8 64k;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 128k;

location / {

......

}

}

八 、 Nginx的php漏洞

漏洞介绍:nginx是一款高性能的web服务器,使用非常广泛,其不仅经常被用作反向代理,也可以非常好的支持PHP的运行。80sec发现其中存在一个较为严重的安全问题,默认情况下可能导致服务器错误的将任何类型的文件以PHP的方式进行解析,这将导致严重的安全问题,使得恶意的攻击者可能攻陷支持php的nginx服务器。
漏洞分析:nginx默认以cgi的方式支持php的运行,譬如在配置文件当中可以以
location ~ .php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
include fastcgi_params;
}
的方式支持对php的解析,location对请求进行选择的时候会使用URI环境变量进行选择,其中传递到后端Fastcgi的关键变量SCRIPT_FILENAME由nginx生成的$fastcgi_script_name决定,而通过分析可以看到$fastcgi_script_name是直接由URI查看更多关于“小白”带你们了解有关于Nginx的模块与工作原理吧!!!的详细内容...

  阅读:46次