配色: 字号:
nginx详解
2015-03-13 | 阅:  转:  |  分享 
  
高性能的Nginx常用功能介绍

Nginx作为Web缓存服务器应用

Nginx作为负载均衡服务器的应用

Nginx的性能优化技巧



1nginx的组成和工作原理

nginx是由内核和模块组成的,其中,内核的设计非常微小和简洁。完成的工作也非常简单。仅仅通过查找配置文件将客户端的请求映射到一个locationblock(locatoin是Nginx配置中的一个命令,用于URL匹配),而这个location中所配置的每个命令将会启动不同的模块去完成相应的工作。

Nginx的模块从结构上分为核心模块、基础模块和第三方模块。其中,HTTP模块、EVENT模块和MAIL模块属于核心模块,HTTPAccess模块、HTTPFastCGI模块、HTTPProxy模块和HTTPRewrite模块属于基本模块,而HTTPUpstreamRequestHash模块、Notice模块和HTTPAccessKey模块属于第三方模块,用户根据自己需要开发的模块都属于第三方模块。



配置与调试nginx

Nginx安装完毕后,会产生相应的安装目录,根据前面的安装路径,Nginx的配置文件路径为/opt/nginx/conf,其中nginx.conf为Nginx的主配置文件。这里重点介绍nginx.conf这个配置文件。

Nginx配置文件主要分为4部分:main(全局设置)、server(主机设置)、upstream(负载均衡服务器设置)和location(URL匹配特定位置的设置)。main部分设置的指令将影响其他所有设置;server部分的指令主要用于指定主机和端口;upstream指令主要用于负载均衡,设置一系列的后端服务器;location部分用于匹配网页位置。这四者之间的关系如下:server继承main,location继承server,upstream既不会继承其他设置也不会被继承。



在这4个部分当中,每个部分都包含若干指令,这些指令主要包含Nginx的主模块指令、事件模块指令、HTTP核心模块指令。同时每个部分还可以使用其他HTTP模块指令,例如HttpSSL模块、HttpGzipStatic模块和HttpAddition模块等。



下面通过一个Nginx配置实例,详细介绍nginx.conf每个指令的含义。为了能更清楚地了解Nginx的结构和每个配置选项的含义,这里按照功能点将Nginx配置文件分为7个部分依次讲解。下面就围绕这7个部分进行介绍。

在这4个部分当中,每个部分都包含若干指令,这些指令主要包含Nginx的主模块指令、事件模块指令、HTTP核心模块指令。同时每个部分还可以使用其他HTTP模块指令,例如HttpSSL模块、HttpGzipStatic模块和HttpAddition模块等。



下面通过一个Nginx配置实例,详细介绍nginx.conf每个指令的含义。为了能更清楚地了解Nginx的结构和每个配置选项的含义,这里按照功能点将Nginx配置文件分为7个部分依次讲解。下面就围绕这7个部分进行介绍。



1.Nginx的全局配置



下面这段内容是对Nginx的全局属性配置,代码如下:



usernobodynobody;

worker_processes4;

error_loglogs/error.lognotice;

pidlogs/nginx.pid;

worker_rlimit_nofile65535;

events{

useepoll;

worker_connections65536;

}

上面这段代码中每个配置选项的含义解释如下:



user是个主模块指令,指定NginxWorker进程运行用户以及用户组,默认由nobody账号运行。



worker_processes是个主模块指令,指定了Nginx要开启的进程数。每个Nginx进程平均耗费10MB~12MB内存。根据经验,一般指定一个进程足够了,如果是多核CPU,建议指定和CPU的数量一样多的进程数即可。



error_log是个主模块指令,用来定义全局错误日志文件。日志输出级别有debug、info、notice、warn、error、crit可供选择,其中,debug输出日志最为最详细,而crit输出日志最少。



pid是个主模块指令,用来指定进程id的存储文件位置。



worker_rlimit_nofile用于绑定worker进程和CPU,Linux内核2.4以上可用。



events指令用来设定Nginx的工作模式及连接数上限。



use是个事件模块指令,用来指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是标准的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平台上,而kqueue用在BSD系统中。对于Linux系统,epoll工作模式是首选。



worker_connections也是个事件模块指令,用于定义Nginx每个进程的最大连接数,默认是1024。最大客户端连接数由worker_processes和worker_connections决定,即max_client=worker_processesworker_connections,在作为反向代理时变为:max_clients=worker_processesworker_connections/4。



进程的最大连接数受Linux系统进程的最大打开文件数限制,在执行操作系统命令“ulimit-n65536”后worker_connections的设置才能生效。



2.HTTP服务器配置



接下来开始对HTTP服务器进行配置。



下面这段内容是Nginx对HTTP服务器相关属性的配置,代码如下:



http{

includeconf/mime.types;

default_typeapplication/octet-stream;

log_formatmain''$remote_addr-$remote_user[$time_local]''

''"$request"$status$bytes_sent''

''"$http_referer""$http_user_agent"''

''"$gzip_ratio"'';

log_formatdownload''$remote_addr-$remote_user[$time_local]''

''"$request"$status$bytes_sent''

''"$http_referer""$http_user_agent"''

''"$http_range""$sent_http_content_range"'';

client_max_body_size20m;

client_header_buffer_size32k;

large_client_header_buffers432k;

sendfileon;

tcp_nopushon;

tcp_nodelayon;

keepalive_timeout60;

client_header_timeout10;

client_body_timeout10;

send_timeout10;

下面详细介绍这段代码中每个配置选项的含义。



include是个主模块指令,实现对配置文件所包含的文件的设定,可以减少主配置文件的复杂度。类似于Apache中的include方法。





default_type属于HTTP核心模块指令,这里设定默认类型为二进制流,也就是当文件类型未定义时使用这种方式,例如在没有配置PHP环境时,Nginx是不予解析的,此时,用浏览器访问PHP文件就会出现下载窗口。



下面的代码实现对日志格式的设定。



log_formatmain''$remote_addr-$remote_user[$time_local]''

''"$request"$status$bytes_sent''

''"$http_referer""$http_user_agent"''

''"$gzip_ratio"'';

log_formatdownload''$remote_addr-$remote_user[$time_local]''

''"$request"$status$bytes_sent''

''"$http_referer""$http_user_agent"''

''"$http_range""$sent_http_content_range"'';

log_format是Nginx的HttpLog模块指令,用于指定Nginx日志的输出格式。main为此日志输出格式的名称,可以在下面的access_log指令中引用。



client_max_body_size用来设置允许客户端请求的最大的单个文件字节数。



client_header_buffer_size用于指定来自客户端请求头的headerbuffer大小。对于大多数请求,1KB的缓冲区大小已经足够,如果自定义了消息头或有更大的cookie,可以增加缓冲区大小。这里设置为32KB。



large_client_header_buffers用来指定客户端请求中较大的消息头的缓存最大数量和大小,“4”为个数,“128K”为大小,最大缓存为4个128KB。



sendfile参数用于开启高效文件传输模式。将tcp_nopush和tcp_nodely两个指令设置为on,用于防止网络阻塞。



keepalive_timeout用于设置客户端连接保持活动的超时时间。在超过这个时间之后,服务器会关闭该连接。



client_header_timeout用于设置客户端请求头读取超时时间。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Requesttimeout(408)”错误。



client_body_timeout用于设置客户端请求主体读取超时时间,默认值为60。如果超过这个时间,客户端还没有发送任何数据,Nginx将返回“Requesttimeout(408)”错误。



send_timeout用于指定响应客户端的超时时间。这个超时仅限于两个连接活动之间的时间,如果超过这个时间,客户端没有任何活动,Nginx将会关闭连接。



3.HttpGzip模块配置



下面配置Nginx的HttpGzip模块。这个模块支持在线实时压缩输出数据流。要查看是否安装了此模块,需要使用下面的命令:



[root@localhostconf]#/opt/nginx/sbin/nginx-V

nginxversion:nginx/0.7.65

configurearguments:--with-http_stub_

status_module--with-http_gzip_static_module--prefix=/opt/nginx

通过/opt/nginx/sbin/nginx-V命令可以查看安装Nginx时的编译选项。由输出可知,我们已经安装了HttpGzip模块。



下面是HttpGzip模块在Nginx配置中的相关属性设置:



gzipon;

gzip_min_length1k;

gzip_buffers416k;

gzip_http_version1.1;

gzip_comp_level2;

gzip_typestext/plainapplication/x-javascripttext/cssapplication/xml;

gzip_varyon;

gzip用于设置开启或者关闭gzip模块,“gzipon”表示开启gzip压缩,实时压缩输出数据流。



gzip_min_length用于设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取。默认值是0,不管页面多大都进行压缩。建议设置成大于1K的字节数,小于1K可能会越压越大。



gzip_buffers表示申请4个单位为16K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。



gzip_http_version用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持gzip解压,使用默认即可。



gzip_comp_level用来指定gzip压缩比,1压缩比最小,处理速度最快;9压缩比最大,传输速度快,但处理最慢,也比较消耗CPU资源。



gzip_types用来指定压缩的类型,无论是否指定,“text/html”类型总是会被压缩的。



gzip_vary选项可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。



4.负载均衡配置



下面设定负载均衡的服务器列表。



upstreamixdba.net{

ip_hash;

server192.168.12.133:80;

server192.168.12.134:80down;

server192.168.12.135:8009max_fails=3fail_timeout=20s;

server192.168.12.136:8080;

}

upstream是Nginx的HTTPUpstream模块,这个模块通过一个简单的调度算法来实现客户端IP到后端服务器的负载均衡。在上面的设定中,通过upstream指令指定了一个负载均衡器的名称ixdba.net。这个名称可以任意指定,在后面需要用到的地方直接调用即可。



Nginx的负载均衡模块目前支持4种调度算法,下面进行分别介绍,其中后两项属于第三方调度算法。



轮询(默认)。每个请求按时间顺序逐一分配到不同的后端服务器,如果后端某台服务器宕机,故障系统被自动剔除,使用户访问不受影响。



Weight。指定轮询权值,Weight值越大,分配到的访问机率越高,主要用于后端每个服务器性能不均的情况下。



ip_hash。每个请求按访问IP的hash结果分配,这样来自同一个IP的访客固定访问一个后端服务器,有效解决了动态网页存在的session共享问题。



fair。这是比上面两个更加智能的负载均衡算法。此种算法可以依据页面大小和加载时间长短智能地进行负载均衡,也就是根据后端服务器的响应时间来分配请求,响应时间短的优先分配。Nginx本身是不支持fair的,如果需要使用这种调度算法,必须下载Nginx的upstream_fair模块。



url_hash。此方法按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,可以进一步提高后端缓存服务器的效率。Nginx本身是不支持url_hash的,如果需要使用这种调度算法,必须安装Nginx的hash软件包。



在HTTPUpstream模块中,可以通过server指令指定后端服务器的IP地址和端口,同时还可以设定每个后端服务器在负载均衡调度中的状态。常用的状态有:



down,表示当前的server暂时不参与负载均衡。



backup,预留的备份机器。当其他所有的非backup机器出现故障或者忙的时候,才会请求backup机器,因此这台机器的压力最轻。



max_fails,允许请求失败的次数,默认为1。当超过最大次数时,返回proxy_next_upstream模块定义的错误。



fail_timeout,在经历了max_fails次失败后,暂停服务的时间。max_fails可以和fail_timeout一起使用。



注意当负载调度算法为ip_hash时,后端服务器在负载均衡调度中的状态不能是weight和backup。



5.server虚拟主机配置



下面介绍对虚拟主机的配置。建议将对虚拟主机进行配置的内容写进另外一个文件,然后通过include指令包含进来,这样更便于维护和管理。



server{

listen80;

server_name192.168.12.188www.ixdba.net;

indexindex.htmlindex.htmindex.jsp;

root/web/wwwroot/www.ixdba.net

charsetgb2312;

server标志定义虚拟主机开始;listen用于指定虚拟主机的服务器端口;server_name用来指定IP地址或者域名,多个域名之间用空格分开;index用于设定访问的默认首页地址;root指令用于指定虚拟主机的网页根目录,这个目录可以是相对路径,也可以是绝对路径;charset用于设置网页的默认编码格式。

access_loglogs/www.ixdba.net.access.logmain;

access_log用来指定此虚拟主机的访问日志存放路径。最后的main用于指定访问日志的输出格式。



6.URL匹配配置



URL地址匹配是Nginx配置中最灵活的部分。location支持正则表达式匹配,也支持条件判断匹配,用户可以通过location指令实现Nginx对动、静态网页的过滤处理。



以下这段设置是通过location指令来对网页URL进行分析处理,所有扩展名为.gif、.jpg、.jpeg、.png、.bmp、.swf的静态文件都交给Nginx处理,而expires用来指定静态文件的过期时间,这里是30天。



location~.\.(gif|jpg|jpeg|png|bmp|swf)${

root/web/wwwroot/www.ixdba.net;

expires30d;

}



Nginx日常维护技巧



1.Nginx基本信息检查



(1)检查Nginx配置文件的正确性





Nginx提供的配置文件调试功能非常有用,可以快速定位配置文件存在的问题。执行如下命令检测配置文件的正确性:



/opt/nginx/sbin/nginx–t或者

/opt/nginx/sbin/nginx-t-c/opt/nginx/conf/nginx.conf

其中,“-t”参数用于检查配置文件是否正确,但并不执行。“-c”参数用于指定配置文件路径,如果不指定配置文件路径,Nginx默认会在安装时指定的安装目录下查找conf/nginx.conf文件。

如果检测结果显示如下信息,说明配置文件正确。



theconfigurationfile/opt/nginx/conf/nginx.confsyntaxisok

configurationfile/opt/nginx/conf/nginx.conftestissuccessful

(2)显示Nginx的版本以及相关编译信息

在命令行执行以下命令可以显示安装Nginx的版本信息。



/opt/nginx/sbin/nginx-v

执行以下命令显示安装的Nginx版本和相关编译信息:





/opt/nginx/sbin/nginx-V

不但显示Nginx的版本信息,同时显示nginx在编译时指定的相关模块信息。



2.Nginx的启动、关闭与重启



Nginx对进程的控制能力非常强大,可以通过信号指令控制进程。常用的信号有:

?QUIT,表处理完当前请求后,关闭进程。

?HUP,表示重新加载配置,也就是关闭原有的进程,并开启新的工作进程。此操作不会中断用户的访问请求,因此可以通过此信号平滑的重启Nginx。

?USR1,用于Nginx的日志切换,也就是重新打开一个日志文件,例如每天要生成一个新的日志文件时,可以使用这个信号来控制。

?USR2,用于平滑升级可执行程序。

?WINCH,从容关闭工作进程。



(1)Nginx的启动

Nginx的启动非常简单,只需输入:



/opt/nginx/sbin/nginx

即可完成nginx的启动。nginx启动后,可以通过如下命令查看Nginx的启动进程:





[root@localhostlogs]#ps-ef|grepnginx

root165721011:14?00:00:00nginx:masterprocess/opt/nginx/sbin/nginx

nobody1659116572011:15?00:00:00nginx:workerprocess

nobody1659216572011:15?00:00:00nginx:workerprocess

nobody1659316572011:15?00:00:00nginx:workerprocess

nobody1659416572011:15?00:00:00nginx:workerprocess

(2)Nginx的关闭

如果要关闭Nginx进程,可以使用如下命令:

kill-XXXpid

其中,XXX就是信号名,pid是Nginx的进程号,可以通过如下两个命令获取:





ps-ef|grep"nginx:masterprocess"|grep-v"grep"|awk-F''''''{print$2}''

cat/opt/nginx/logs/nginx.pid

(3)Nginx的平滑重启

要不间断服务地重新启动Nginx,可以使用如下命令:



kill-HUP‘cat/opt/nginx/logs/nginx.pid‘



Nginx常用功能介绍

一、虚拟主机配置实例

下面在Nginx中创建三个虚拟主机,需要说明的是,这里仅仅列出了虚拟主机配置部分。



http{

server{

listen80;

server_namewww.domain1.com;

access_loglogs/domain1.access.logmain;

location/{

indexindex.html;

root/web/www/domain1.com/htdocs;

}

}

server{

listen80;

server_namewww.domain2.com;

access_loglogs/domain2.access.logmain;

location/{

indexindex.html;

root/web/www/domain2.com/htdocs;

}

}

include/opt/nginx/conf/vhosts/www.domain2.com.conf;

}

这里用到了include指令,其中/opt/nginx/conf/vhosts/www.domain2.com.conf的内容为:



server{

listen80;

server_namewww.domain3.com;

access_loglogs/domain3.access.logmain;

location/{

indexindex.html;

root/web/www/domain3.com/htdocs;

}

}

二、负载均衡配置实例

下面通过Nginx的反向代理功能配置一个Nginx负载均衡服务器。后端有三个服务节点,用于提供Web服务,通过Nginx的调度实现三个节点的负载均衡。



http

{

upstreammyserver{

server192.168.12.181:80weight=3max_fails=3fail_timeout=20s;

server192.168.12.182:80weight=1max_fails=3fail_timeout=20s;

server192.168.12.183:80weight=4max_fails=3fail_timeout=20s;

}



server

{

listen80;

server_namewww.domain.com192.168.12.189;

indexindex.htmindex.html;

root/ixdba/web/wwwroot;



location/{

proxy_passhttp://myserver;

proxy_next_upstreamhttp_500http_502http_503errortimeoutinvalid_header;

include/opt/nginx/conf/proxy.conf;

}

}

}



在上面这个配置实例中,首先定义了一个负载均衡组myserver,然后在location部分通过“proxy_passhttp://myserver”实现负载调度功能,其中proxy_pass指令用来指定代理的后端服务器地址和端口,地址可以是主机名或者IP地址,也可以是通过upstream指令设定的负载均衡组名称。

proxy_next_upstream用来定义故障转移策略,当后端服务节点返回500、502、503、504和执行超时等错误时,自动将请求转发到upstream负载均衡组中的另一台服务器,实现故障转移。最后通过include指令包含进来一个proxy.conf文件。

其中/opt/nginx/conf/proxy.conf的内容为:



proxy_redirectoff;

proxy_set_headerHost$host;

proxy_set_headerX-Real-IP$remote_addr;

proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;

proxy_connect_timeout90;

proxy_send_timeout90;

proxy_read_timeout90;

proxy_buffer_size4k;

proxy_buffers432k;

proxy_busy_buffers_size64k;

proxy_temp_file_write_size64k;

Nginx的代理功能是通过httpproxy模块来实现的。默认在安装Nginx时已经安装了httpproxy模块因此可直接使用httpproxy模块。下面详细解释proxy.conf文件中每个选项代表的含义。

?proxy_set_header:设置由后端的服务器获取用户的主机名或者真实IP地址,以及代理者的真实IP地址。

?client_body_buffer_size:用于指定客户端请求主体缓冲区大小,可以理解为先保存到本地再传给用户。

?proxy_connect_timeout:表示与后端服务器连接的超时时间,即发起握手等候响应的超时时间。

?proxy_send_timeout:表示后端服务器的数据回传时间,即在规定时间之内后端服务器必须传完所有的数据,否则,Nginx将断开这个连接。

?proxy_read_timeout:设置Nginx从代理的后端服务器获取信息的时间,表示连接建立成功后,Nginx等待后端服务器的响应时间,其实是Nginx已经进入后端的排队之中等候处理的时间。

?proxy_buffer_size:设置缓冲区大小,默认,该缓冲区大小等于指令proxy_buffers设置的大小。

?proxy_buffers:设置缓冲区的数量和大小。nginx从代理的后端服务器获取的响应信息,会放置到缓冲区。

?proxy_busy_buffers_size:用于设置系统很忙时可以使用的proxy_buffers大小,官方推荐的大小为proxy_buffers2。

?proxy_temp_file_write_size:指定proxy缓存临时文件的大小。



三、防盗链配置实例

Nginx的防盗链功能也非常强大。在默认情况下,只需要进行简单的配置,即可实现防盗链处理。请看下面的这个实例:



location~\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)${

valid_referersnoneblocked.ixdba1.netixdba1.net;

if($invalid_referer){

rewrite^/http://www.ixdba.net/img/error.gif;

#return403;

}

}

location/images{

root/opt/nginx/html;

valid_referersnoneblocked.ixdba1.netixdba1.net;

if($invalid_referer){

return403;

}

}

在上面这段防盗链设置中,分别针对不同文件类型和不同的目录进行了设置,读者可以根据自己的需求进行类似的设定。

“jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar”表示对以jpg、gif、png、swf、flv、wma、wmv、asf、mp3、mmf、zip和rar为后缀的文件实行防盗链处理。

“.ixdba1.netixdba1.net”表示这个请求可以正常访问上面指定的文件资源。

if{}中的内容的意思是:如果地址不是上面指定的地址就跳转到通过rewrite指定的地址,也可以直接通过return返回403错误。

要做更加复杂的防盗链处理,可以使用Nginx的HttpAccessKeyModule,通过这个模块可以实现功能更强大的防盗链处理,更详细的参考官方文档。



四、日志分割配置实例

Nginx没有类似Apache的cronolog日志分割处理的功能,但是,可以通过nginxNginx的信号控制功能利用脚本来实现日志的自动切割。请看下面的一个实例。

Nginx对日志进行处理的脚本:



#/bin/bash

savepath_log=''/home/nginx/logs''

nglogs=''/opt/nginx/logs''



mkdir-p$savepath_log/$(date+%Y)/$(date+%m)

mv$nglogs/access.log$savepath_log/$(date+%Y)/$(date+%m)/access.$(date+%Y%m%d).log

mv$nglogs/error.log$savepath_log/$(date+%Y)/$(date+%m)/error.$(date+%Y%m%d).log

kill-USR1`cat/opt/nginx/logs/nginx.pid`



将这段脚本保存后加入到Linux的crontab守护进程,让此脚本在每天凌晨0点执行,就可以实现日志的每天分割功能了。

其中,变量savepath_log指定分割后的日志存放的路径,而变量nglogs指定Nginx日志文件的存放路径。最后一行,通过Nginx的信号“USR1”实现了日志的自动切换功能。



7nginx优化

7.1编译安装过程优化

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

#debug

CFLAGS=”$CFLAGS-g”

注释掉或删除

为特定的CPU指定CPU类型编译优化

在编译Nginx时,默认的GCC编译参数是“-O”,要优化GCC编译,可以使用以下两个参数:



--with-cc-opt=''-O3''



--with-cpu-opt=CPU#为特定的CPU编译,有效的值包括:pentium,pentiumpro,pentium3,pentium4,athlon,opteron,amd64,sparc32,sparc64,ppc64



要确定CPU类型,可以通过如下命令:



[root@localhosthome]#cat/proc/cpuinfo|grep"modelname"



7.2利用TCMalloc优化Nginx的性能

TCMalloc的全称为Thread-CachingMalloc,是谷歌开发的开源工具“google-perftools”中的一个成员。与标准的glibc库的malloc相比,TCMalloc库在内存分配效率和速度上要高很多,这在很大程度上提高了服务器在高并发情况下的性能,从而降低系统负载。下面简单介绍如何为Nginx添加TCMalloc库支持。要安装TCMalloc库,需要安装libunwind(32位操作系统不需要安装)和google-perftools两个软件包,libunwind库为基于64位CPU和操作系统的程序提供了基本函数调用链和函数调用寄存器功能。下面介绍利用TCMalloc优化Nginx的具体操作过程:



1.安装libunwind库

可以从http://download.savannah.gnu.org/releases/libunwind下载相应的libunwind版本,这里下载的是libunwind-0.99-alpha.tar.gz,安装过程如下



[root@localhosthome]#tarzxvflibunwind-0.99-alpha.tar.gz



[root@localhosthome]#cdlibunwind-0.99-alpha/



[root@localhostlibunwind-0.99-alpha]#CFLAGS=-fPIC./configure



[root@localhostlibunwind-0.99-alpha]#makeCFLAGS=-fPIC



[root@localhostlibunwind-0.99-alpha]#makeCFLAGS=-fPICinstall



2.安装google-perftools

可以从http://google-perftools.googlecode.com下载相应的google-perftools版本,这里下载的是google-perftools-1.8.tar.gz,安装过程如下:



[root@localhosthome]#tarzxvfgoogle-perftools-1.8.tar.gz



[root@localhosthome]#cdgoogle-perftools-1.8/



[root@localhostgoogle-perftools-1.8]#./configure



[root@localhostgoogle-perftools-1.8]#make&&makeinstall



[root@localhostgoogle-perftools-1.8]#echo"/usr/local/lib">/etc/ld.so.conf.d/usr_local_lib.conf



[root@localhostgoogle-perftools-1.8]#ldconfig



至此,google-perftools安装完成。



3.重新编译Nginx

为了使Nginx支持google-perftools,需要在安装过程中添加“–with-google_perftools_module”选项重新编译Nginx,安装代码如下:



[root@localhostnginx-0.7.65]#



./configure--user=www--group=www--prefix=/usr/local/nginx--with-http_stub_status_module--with-http_ssl_module--with-http_gzip_static_module--with-ipv6--with-google_perftools_module







[root@localhostnginx-0.7.65]#make



[root@localhostnginx-0.7.65]#makeinstall



到这里Nginx安装完成。



4.为google-perftools添加线程目录

创建一个线程目录,这里将文件放在/tmp/tcmalloc下,操作如下:



[root@localhosthome]#mkdir/tmp/tcmalloc



[root@localhosthome]#chmod0777/tmp/tcmalloc



5.修改Nginx主配置文件

修改nginx.conf文件,在pid这行的下面添加如下代码:



#pidlogs/nginx.pid;



google_perftools_profiles/tmp/tcmalloc;



接着,重启Nginx,完成google-perftools的加载。



6.验证运行状态

为了验证google-perftools已经正常加载,通过如下命令查看:



[root@localhosthome]#lsof-n|greptcmalloc



nginx2395nobody9wREG8,801599440/tmp/tcmalloc.2395



nginx2396nobody11wREG8,801599443/tmp/tcmalloc.2396



nginx2397nobody13wREG8,801599441/tmp/tcmalloc.2397



nginx2398nobody15wREG8,801599442/tmp/tcmalloc.2398



由于在Nginx配置文件中,设置worker_processes的值为4,因此开启了4个Nginx线程,每个线程会有一行记录。每个线程文件后面的数字值就是启动的Nginx的PID值。至此,利用TCMalloc优化Nginx的操作完成。



7.3Nginx内核参数优化

内核参数的优化,主要是在Linux系统中针对Nginx应用而进行的系统内核参数优化,常见的优化参数值如下。



下面给出一个优化实例以供参考:



net.ipv4.tcp_max_tw_buckets=6000



net.ipv4.ip_local_port_range=102465000



net.ipv4.tcp_tw_recycle=1



net.ipv4.tcp_tw_reuse=1



net.ipv4.tcp_syncookies=1



net.core.somaxconn=262144



net.core.netdev_max_backlog=262144



net.ipv4.tcp_max_orphans=262144



net.ipv4.tcp_max_syn_backlog=262144



net.ipv4.tcp_synack_retries=1



net.ipv4.tcp_syn_retries=1



net.ipv4.tcp_fin_timeout=1



net.ipv4.tcp_keepalive_time=30



将上面的内核参数值加入/etc/sysctl.conf文件中,然后执行如下命令使之生效:



[root@localhosthome]#/sbin/sysctl-p



下面是对实例中选项的含义进行介绍:



net.ipv4.tcp_max_tw_buckets参数用来设定timewait的数量,默认是180000,这里设为6000。



net.ipv4.ip_local_port_range选项用来设定允许系统打开的端口范围。



net.ipv4.tcp_tw_recycle选项用于设置启用timewait快速回收。



net.ipv4.tcp_tw_reuse选项用于设置开启重用,允许将TIME-WAITsockets重新用于新的TCP连接。



net.ipv4.tcp_syncookies选项用于设置开启SYNCookies,当出现SYN等待队列溢出时,启用cookies进行处理。



net.core.somaxconn选项默认值是128,这个参数用于调节系统同时发起的tcp连接数,在高并发的请求中,默认的值可能会导致链接超时或者重传,因此,需要结合并发请求数来调节此值。



net.core.netdev_max_backlog选项表示当每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许发送到队列的数据包的最大数目。



net.ipv4.tcp_max_orphans选项用于设定系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤立连接将立即被复位并打印出警告信息。这个限制只是为了防止简单的DoS攻击。不能过分依靠这个限制甚至人为减小这个值,更多的情况是增加这个值。



net.ipv4.tcp_max_syn_backlog选项用于记录那些尚未收到客户端确认信息的连接请求的最大值。对于有128MB内存的系统而言,此参数的默认值是1024,对小内存的系统则是128。



net.ipv4.tcp_synack_retries参数的值决定了内核放弃连接之前发送SYN+ACK包的数量。



net.ipv4.tcp_syn_retries选项表示在内核放弃建立连接之前发送SYN包的数量。



net.ipv4.tcp_fin_timeout选项决定了套接字保持在FIN-WAIT-2状态的时间。默认值是60秒。正确设置这个值非常重要,有时候即使一个负载很小的Web服务器,也会出现因为大量的死套接字而产生内存溢出的风险。



net.ipv4.tcp_keepalive_time选项表示当keepalive启用的时候,TCP发送keepalive消息的频度。默认值是2(单位是小时)。



下面贴一个完整的内核优化设置:



vi/etc/sysctl.confCentOS5.5中可以将所有内容清空直接替换为如下内容:



net.ipv4.ip_forward=0



net.ipv4.conf.default.rp_filter=1



net.ipv4.conf.default.accept_source_route=0



kernel.sysrq=0



kernel.core_uses_pid=1



net.ipv4.tcp_syncookies=1



kernel.msgmnb=65536



kernel.msgmax=65536



kernel.shmmax=68719476736



kernel.shmall=4294967296



net.ipv4.tcp_max_tw_buckets=6000



net.ipv4.tcp_sack=1



net.ipv4.tcp_window_scaling=1



net.ipv4.tcp_rmem=4096873804194304



net.ipv4.tcp_wmem=4096163844194304



net.core.wmem_default=8388608



net.core.rmem_default=8388608



net.core.rmem_max=16777216



net.core.wmem_max=16777216



net.core.netdev_max_backlog=262144



net.core.somaxconn=262144



net.ipv4.tcp_max_orphans=3276800



net.ipv4.tcp_max_syn_backlog=262144



net.ipv4.tcp_timestamps=0



net.ipv4.tcp_synack_retries=1



net.ipv4.tcp_syn_retries=1



net.ipv4.tcp_tw_recycle=1



net.ipv4.tcp_tw_reuse=1



net.ipv4.tcp_mem=94500000915000000927000000



net.ipv4.tcp_fin_timeout=1



net.ipv4.tcp_keepalive_time=30



net.ipv4.ip_local_port_range=102465000



7.4配置文件优化

基本优化

一般来说nginx配置文件中对优化比较有作用的为以下几项:



1.worker_processes8;

nginx进程数,建议按照cpu数目来指定,一般为它的倍数(如,2个四核的cpu计为8)。



2.worker_cpu_affinity0000000100000010000001000000100000010000001000000100000010000000;

为每个进程分配cpu,上例中将8个进程分配到8个cpu,当然可以写多个,或者将一个进程分配到多个cpu。



3.worker_rlimit_nofile65535;

这个指令是指当一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(ulimit-n)与nginx进程数相除,但是nginx分配请求并不是那么均匀,所以最好与ulimit-n的值保持一致。详见ulimit关于系统连接数的优化

现在在linux2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。



这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。



查看linux系统文件描述符的方法:



[root@web001~]#sysctl-a|grepfs.file







fs.file-max=789972







fs.file-nr=5100789972



4.useepoll;

使用epoll的I/O模型



(



补充说明:



与apache相类,nginx针对不同的操作系统,有不同的事件模型



A)标准事件模型Select、poll属于标准事件模型,如果当前系统不存在更有效的方法,nginx会选择select或pollB)高效事件模型Kqueue:使用于FreeBSD4.1+,OpenBSD2.9+,NetBSD2.0和MacOSX.使用双处理器的MacOSX系统使用kqueue可能会造成内核崩溃。Epoll:使用于Linux内核2.6版本及以后的系统。



/dev/poll:使用于Solaris711/99+,HP/UX11.22+(eventport),IRIX6.5.15+和Tru64UNIX5.1A+。



Eventport:使用于Solaris10.为了防止出现内核崩溃的问题,有必要安装安全补丁。



)



5.worker_connections65535;

每个进程允许的最多连接数,理论上每台nginx服务器的最大连接数为worker_processesworker_connections。



6.keepalive_timeout60;

keepalive超时时间。



7.client_header_buffer_size4k;

客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。



分页大小可以用命令getconfPAGESIZE取得。



[root@web001~]#getconfPAGESIZE

4096



但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。



8.open_file_cachemax=65535inactive=60s;

这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive是指经过多长时间文件没被请求后删除缓存。



9.open_file_cache_valid80s;

这个是指多长时间检查一次缓存的有效信息。



10.open_file_cache_min_uses1;

open_file_cache指令中的inactive参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive时间内一次没被使用,它将被移除。



简单配置文件

下面是一个简单的nginx配置文件:



userwwwwww;



worker_processes8;



worker_cpu_affinity000000010000001000000100000010000001000000100000



01000000;



error_log/www/log/nginx_error.logcrit;



pid/usr/local/nginx/nginx.pid;



worker_rlimit_nofile204800;



events



{



useepoll;



worker_connections204800;



}



http



{



includemime.types;



default_typeapplication/octet-stream;



charsetutf-8;



server_names_hash_bucket_size128;



client_header_buffer_size2k;



large_client_header_buffers44k;



client_max_body_size8m;



sendfileon;



tcp_nopushon;



keepalive_timeout60;



fastcgi_cache_path/usr/local/nginx/fastcgi_cachelevels=1:2



keys_zone=TEST:10m



inactive=5m;



fastcgi_connect_timeout300;



fastcgi_send_timeout300;



fastcgi_read_timeout300;



fastcgi_buffer_size4k;



fastcgi_buffers84k;



fastcgi_busy_buffers_size8k;



fastcgi_temp_file_write_size8k;



fastcgi_cacheTEST;



fastcgi_cache_valid2003021h;



fastcgi_cache_valid3011d;



fastcgi_cache_validany1m;



fastcgi_cache_min_uses1;



fastcgi_cache_use_staleerrortimeoutinvalid_headerhttp_500;



open_file_cachemax=204800inactive=20s;



open_file_cache_min_uses1;



open_file_cache_valid30s;



tcp_nodelayon;



gzipon;



gzip_min_length1k;



gzip_buffers416k;



gzip_http_version1.0;



gzip_comp_level2;



gzip_typestext/plainapplication/x-javascripttext/cssapplication/xml;



gzip_varyon;



server



{



listen8080;



server_namebackup.aiju.com;



indexindex.phpindex.htm;



root/www/html/;



location/status



{



stub_statuson;



}



location~.\.(php|php5)?$



{



fastcgi_pass127.0.0.1:9000;



fastcgi_indexindex.php;



includefcgi.conf;



}



location~.\.(gif|jpg|jpeg|png|bmp|swf|js|css)$



{



expires30d;



}



log_formataccess‘$remote_addr—$remote_user[$time_local]“$request”‘



‘$status$body_bytes_sent“$http_referer”‘



‘”$http_user_agent”$http_x_forwarded_for’;



access_log/www/log/access.logaccess;



}



}



关于FastCGI的几个指令:

fastcgi_cache_path/usr/local/nginx/fastcgi_cachelevels=1:2keys_zone=TEST:10minactive=5m;



这个指令为FastCGI缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。



fastcgi_connect_timeout300;



指定连接到后端FastCGI的超时时间。



fastcgi_send_timeout300;



向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。



fastcgi_read_timeout300;



接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间。



fastcgi_buffer_size4k;



指定读取FastCGI应答第一部分需要用多大的缓冲区,一般第一部分应答不会超过1k,由于页面大小为4k,所以这里设置为4k。



fastcgi_buffers84k;



指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答。



fastcgi_busy_buffers_size8k;



这个指令我也不知道是做什么用,只知道默认值是fastcgi_buffers的两倍。



fastcgi_temp_file_write_size8k;



在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍。



fastcgi_cacheTEST



开启FastCGI缓存并且为其制定一个名称。个人感觉开启缓存非常有用,可以有效降低CPU负载,并且防止502错误。



fastcgi_cache_valid2003021h;fastcgi_cache_valid3011d;fastcgi_cache_validany1m;



为指定的应答代码指定缓存时间,如上例中将200,302应答缓存一小时,301应答缓存1天,其他为1分钟。



fastcgi_cache_min_uses1;



缓存在fastcgi_cache_path指令inactive参数值时间内的最少使用次数,如上例,如果在5分钟内某文件1次也没有被使用,那么这个文件将被移除。



fastcgi_cache_use_staleerrortimeoutinvalid_headerhttp_500;



不知道这个参数的作用,猜想应该是让nginx知道哪些类型的缓存是没用的。以上为nginx中FastCGI相关参数,另外,FastCGI自身也有一些配置需要进行优化,如果你使用php-fpm来管理FastCGI,可以修改配置文件中的以下值:



再来优化PHP-FPM,打开/usr/local/php/etc/php-fpm.conf,这个文件和PHP的语法很相似,凡是需要激活的配置,直接删掉前面的分号(;)即可:



1.[global]

2.

3.pid=run/php-fpm.pid

4.

5.process_control_timeout=5

6.

7.[www]

8.

9.listen.allowed_clients=127.0.0.1

10.

11.user=www-data

12.

13.group=www-data

14.

15.pm=dynamic

16.

17.pm.max_children=20(这个配置决定了php-fpm的总进程数,内存小的少设点)

18.

19.pm.max_requests=10000(并发数越大,此请求数应越大)

20.

21.pm.start_servers=10(初始php-fpm进程数)

22.

23.emergency_restart_threshold=60

24.

25.emergency_restart_interval=60s

上边这两个,表示在emergency_restart_interval所设值内出现SIGSEGV或者SIGBUS错误的php-cgi进程数如果超过emergency_restart_threshold个,php-fpm就会优雅重启。这两个选项一般保持默认值





ulimit关于系统连接数的优化

linux默认值openfiles和maxuserprocesses为1024



#ulimit-n



1024



#ulimit–u



1024



问题描述:说明server只允许同时打开1024个文件,处理1024个用户进程



使用ulimit-a可以查看当前系统的所有限制值,使用ulimit-n可以查看当前的最大打开文件数。



新装的linux默认只有1024,当作负载较大的服务器时,很容易遇到error:toomanyopenfiles。因此,需要将其改大。



解决方法:



使用ulimit–n65535可即时修改,但重启后就无效了。(注ulimit-SHn65535等效ulimit-n65535,-S指soft,-H指hard)



修改方式

有如下三种修改方式:



1.在/etc/rc.local中增加一行ulimit-SHn65535



2.在/etc/profile中增加一行ulimit-SHn65535



3.在/etc/security/limits.conf最后增加:



4.softnofile65535



5.hardnofile65535



6.softnproc65535



7.hardnproc65535



具体使用哪种,在CentOS中使用第1种方式无效果,使用第3种方式有效果,而在Debian中使用第2种有效果



#ulimit-n



65535



#ulimit-u



65535



备注:ulimit命令本身就有分软硬设置,加-H就是硬,加-S就是软默认显示的是软限制



soft限制指的是当前系统生效的设置值。hard限制值可以被普通用户降低。但是不能增加。soft限制不能设置的比hard限制更高。只有root用户才能够增加hard限制值。





献花(0)
+1
(本文系苏鱼鱼的IT...首藏)