nginx优化
# 1. Nginx隐藏版本号
方法一:修改配置文件(适合已安装nginx的场景)
vim /usr/local/nginx/conf/nginx.conf
28 server_tokens off;
2
如果php配置文件中配置了fastcgi_param SERVER_SOFTWARE选项,则编辑php-fpm配置文件,将fastcgi_param SERVER_SOFTWARE对应值修改为fastcgi_param SERVER_SOFTWARE nginx
方法二:修改源码包(适合还未安装nginx的场景)
vim /usr/src/nginx-1.6.2/src/core/nginx.h //修改以下变量
13 #define NGINX_VERSION "7.0.0 "
14 #define NGINX_VER "IIS/" NGINX_VERSION
2
3
# 2. 修改Nginx用户与组
Nginx 默认使用 nobody 用户账号与组账号
方法一:编译安装时指定
编译时加上--user=nginx --group=nginx参数
方法二:修改配置文件
vim /usr/local/nginx/conf/nginx.conf
2 user nginx nginx;
2
# 3. 配置Nginx网页缓存时间
设置方法:可修改配置文件,在http段、或server段、或者location段加入对特定内容的过期参数。
vim /usr/local/nginx/conf/nginx.conf
49 location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ {
50 expires 1d;
51 }
52 location ~ .*\.(js|css)$ {
53 expires 1h;
54 }
2
3
4
5
6
7
# 4. nginx日志切割
vim /opt/cut_nginx_log.sh
#!/bin/bash
# cut_nginx_log.sh
datetime=$(date -d "-1 day" "+%Y%m%d")
log_path="/usr/local/nginx/logs"
pid_path="/usr/local/nginx/logs/nginx.pid"
[ -d $log_path/backup ] || mkdir -p $log_path/backup
if [ -f $pid_path ]
then
mv $log_path/access.log $log_path/backup/access.log-$datetime
kill -USR1 $(cat $pid_path)
find $log_path/backup -mtime +30 | xargs rm -f
else
echo "Error,Nginx is not working!" | tee -a /var/log/messages
fi
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 5. 配置Nginx实现连接超时
- keepalived_timeout :设置连接保持超时时间,一般可只设置该参数,默认为 65 秒,可根据网站的情况设置,或者关闭,可在 http 段、server 段、或者 location 段设置。
- client_header_timeout :指定等待客户端发送请求头的超时时间。
- client_body_timeout :设置请求体读取超时时间。
注意: 若出现超时,会返回 408
# 6. 更改Nginx运行进程数
修改配置文件的worker_processes参数,一般设置为CPU的个数或核数的2倍。
grep 'core id' /proc/cpuinfo | uniq | wc -l //查看服务器核心数
1
vim /usr/local/nginx/conf/nginx.conf
3 worker_processes 2;
2
3
4
默认Nginx的多个进程可能更多的跑在一颗CPU上,可以分配不同的进程给不同的CPU处理,充分利用硬件多核多CPU。在一台4核物理服务器,可以进行下面的配置,将进程进行分配:
worker_cpu_affinity 0001 0010 0100 1000
1
# 7. 配置Nginx实现网页压缩功能
==ngx_http_gzip_module== 压缩模块提供了对文件内容压缩的功能。
vim /usr/local/nginx/conf/nginx.conf
38 gzip on; //开启gzip压缩输出
39 gzip_min_length 1k; //用于设置允许压缩的页面最小字节数
40 gzip_buffers 4 16k; //表示申请4个单位为16k的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来储存gzip压缩结果
41 gzip_http_version 1.1; //设置识别http协议版本,默认是1.1
42 gzip_comp_level 2; //gzip压缩比,1-9 等级
43 gzip_types text/plain text/javascript application/x-javascript text/css text/xmlapplication/xml application/xml+rss; //压缩类型,是就对哪些网页文档启用压缩功能
44 #gzip_vary on; //选项可以让前端的缓存服务器经过gzip压缩的页面
2
3
4
5
6
7
8
# 8. 配置Nginx实现防盗链功能
配置说明:
- valid_referers 设置信任网站
- none 浏览器中referer(Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器我是从哪个页面链接过来的,服务器基此可以获得一些信息用于处理)为空的情况,就直接在浏览器访问图片
- blocked referrer 不为空的情况,但是值被代理或防火墙删除了,这些值不以http://或 https://开头
vim /usr/local/nginx/conf/nginx.conf
location ~* \.(wma|wmv|asf|mp3|mmf|zip|rar|jpg|gif|png|swf|flv)$ {
valid_referers none blocked *.source.com source.com;
if ($invalid_referer) {
rewrite ^/ http://www.source.com/error.jpg;
#return 403;
}
}
2
3
4
5
6
7
8
9
第一行:wma|wmv|asf|mp3|mmf|zip|rar|jpg|gif|png|swf|flv 表示对这些后缀的文件实行防盗链。
第二行:none blocked *.source.com source.com; //不区分大小写,表示 referers 信息中匹配 none blocked *.source.com source.com (*代表任何,任何的二级域名)
if{}里面内容的意思是,如果链接不是来自第二行指定的就强制跳转到 403 错误页面,当然直接返回 404 也是可以的,也可以是图片。
# 9. 对FPM模块进行参数优化
FPM 优化参数:
- pm static| dynamic 使用哪种方式启动fpm进程,前者将产生固定数量的fpm进程,后者将以动态的方式产生fpm进程
- pm.max_children static 方式下开启的 fpm 进程数
- pm.start_servers 动态方式下初始的 fpm 进程数量
- pm.min_spare_servers 动态方式下最小的 fpm 空闲进程数
- pm.max_spare_servers 动态方式下最大的 fpm 空闲进程数
# 10. Nginx为目录添加访问控制
用户访问控制:使用 apache 的 htpasswd 来创建密码文件
htpasswd -c /usr/local/nginx/.htpasswd 用户名
修改配置文件以支持用户认证:
vim /usr/local/nginx/conf/nginx.conf
location ~ /status {
stub_status on;
access_log off;
auth_basic "Nginx Status";
auth_basic_user_file /usr/local/nginx/.htpasswd;
}
2
3
4
5
6
7
客户端地址访问控制:
vim /usr/local/nginx/conf/nginx.conf
location ~ /status {
stub_status on;
access_log off;
auth_basic "Nginx Status";
auth_basic_user_file /usr/local/nginx/.htpasswd;
allow 192.168.200.2;
deny 192.168.200.0/24;
}
2
3
4
5
6
7
8
9
# 11. 自定义错误页面
vim /usr/local/nginx/conf/nginx.conf
error_page 403 404 /404.html;
location = /404.html {
root html;
}
2
3
4
5
# 12. 自动索引
vim /usr/local/nginx/conf/nginx.conf
location /download {
autoindex on;
}
2
3
4
# 13. 目录别名功能
vim /usr/local/nginx/conf/nginx.conf
location ~ /Centos {
alias /usr/local/nginx/html/RedHat;
}
2
3
4
# 14. 通过UA实现手机端和电脑端的分离
location / {
// 默认PC端访问内容
root /usr/local/nginx/html/web;
// 如果是手机移动端访问内容
if ( $http_user_agent ~
"(MIDP)|(WAP)|(UP.Browser)|(Smartphone)|(Obigo)|(Mobile)|(AU.Browser)|(wxd.Mms)|(WxdB.Browser)|(CLDC)|(UP.Link)|(KM.Browser)|(UCWEB)|(SEMC-Browser)|(Mini)|(Symbian)|(Palm)|(Nokia)|(Panasonic)|(MOT-)|(SonyEricsson)|(NEC-)|(Alcatel)|(Ericsson)|(BENQ)|(BenQ)|(Amoisonic)|(Amoi-)|(Capitel)|(PHILIPS)|(SAMSUNG)|(Lenovo)|(Mitsu)|(Motorola)|(SHARP)|(WAPPER)|(LG-)|(LG/)|(EG900)|(CECT)|(Compal)|(kejian)|(Bird)|(BIRD)|(G900/V1.0)|(Arima)|(CTL)|(TDG)|(Daxian)|(DAXIAN)|(DBTEL)|(Eastcom)|(EASTCOM)|(PANTECH)|(Dopod)|(Haier)|(HAIER)|(KONKA)|(KEJIAN)|(LENOVO)|(Soutec)|(SOUTEC)|(SAGEM)|(SEC-)|(SED-)|(EMOL-)|(INNO55)|(ZTE)|(iPhone)|(Android)|(WindowsCE)|(Wget)|(Java)|(curl)|(Opera)" )
{
root /usr/local/nginx/html/mobile;
}
index index.html index.htm;
}
2
3
4
5
6
7
8
9
10
11
12
# 15.nginx平滑升级
Nginx 信号
主进程支持的信号:
- TERM, INT 立刻退出
- QUIT 等待工作进程结束后再退出
- KILL 强制终止进程
- HUP 重新加载配置文件,使用新的配置启动工作进程,并逐步关闭旧进程
- USR1 重新打开日志文件
- USR2 启动新的主进程,实现热升级
- WINCH 逐步关闭工作进程
工作进程支持的信号:
- TERM, INT 立刻退出
- QUIT 等待请求处理结束后再退出
- USR1 重新打开日志文件
1.查看旧版 nginx的编译参数
2.编译新版本Nginx源码包,安装路径需与旧版一致,不要执行make install
3.备份二进制文件,用新版本的替换
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old
cp objs/nginx /usr/local/nginx/sbin/
2
4.确保配置文件无报错
5.发送USR2信号
向主进程(master)发送 USR2 信号,Nginx 会启动一个新版本的 master 进程和对应工作进程,和旧版一起处理请求
6.发送WINCH信号
向旧的Nginx主进程(master)发送WINCH信号,它会逐步关闭自己的工作进程(主进程不退出),这时所有请求都会由新版Nginx处理
注意:回滚步骤,发送 HUP 信号
如果这时需要回退继续使用旧版本,可向旧的 Nginx 主进程发送 HUP 信号,它会重新启动工作进程, 仍使用旧版配置文件。然后可以将新版 Nginx 进程杀死(使用 QUIT、TERM、或者 KILL)
7.发送QUIT信号
升级完毕,可向旧的 Nginx 主进程(master)发送(QUIT、TERM、或者 KILL)信号,使旧的主进程退出
# 16. 主配置文件相关参数的优化
# 1. open files数量优化
ulimit -a查看系统参数,其中open files (-n) 1024表示系统同时最多能打开的文件数,如果同时超过1024个连接,那么nginx的日志就会报“24: Too many open files”
优化的第一步就是设置open files为ulimit
vim /etc/profile
ulimit -n 65535
2
# 2. worker进程连接数优化
默认这个值是worker_connections 1024,也就是说考虑到keep-alive超时65秒,每个浏览器平均消耗两个链接(chrome会同时打开多个连接来提到加载速度)。
那么默认情况下nginx平均每秒能处理1024/65/2=8,那么8*86440=64w,差不多相当于每天有60万ip。普通网站默认值就可以了,如果你的流量一直提升,可以考虑增加这个值为2048或者更高。
# 3. CPU Affinity(CPU绑定)
用来设置worker进程使用哪个cpu核心处理请求并且一直使用这个cpu核心。如果你不知道cpu调度,最好别碰这个,操作系统比你更懂如何调度。
# 4. tcp_nodelay 和 tcp_nopush优化
这两个指令影响nginx的底层网络,它们决定操作系统如何处理网络层buffer和什么时候把buffer内容刷新给终端用户。如果你不懂,就可以保持这两个指令默认不变,对nginx性能影响不明显。
# 5. 日志优化
access日志优化
默认情况下,access日志会记录所有请求到日志文件,写操作会增加IO操作,如果不需要统计信息,可以使用百度统计或者cnzz统计,完全可以关闭日志,来减少磁盘写,或者写入内存文件,提高IO效率。
Error日志优化
错误日志会记录运行中的错误,如果设置的太低,会记录的信息太多,会产生大量IO,推荐设置为warn,这样可以记录大部分信息,而不会有太多IO
# 6. Open File Cache
nginx会读文件系统的许多文件,如果这些文件的描述符能够缓存起来,那么会提高处理效率。详见http://wiki.nginx.org/HttpCoreModule#open_file_cache
# 7. Buffers size优化
buffer的大小是你需要调优最重要参数。如果buffer size太小就会到导致nginx使用临时文件存储response,这会引起磁盘读写IO,流量越大问题越明显。 client_body_buffer_size 处理客户端请求体buffer大小。用来处理POST提交数据,上传文件等。client_body_buffer_size 需要足够大以容纳如果需要上传POST数据。
fastcgi_buffers,proxy_buffers 处理后端(PHP,Apache)响应。如果这个buffer不够大,同样会引起磁盘都系IO。需要注意的是它们有一个上限值,这个上限值受 fastcgi_max_temp_file_size 、 proxy_max_temp_file_size控制。
# 8. 磁盘IO
如果能把数据全放到内存,不使用磁盘就可以完全去掉磁盘IO。 默认情况下操作系统也会缓存频繁访问的数据以降低IO。所以预算足够的情况加,加大内存。
# 9.网络IO
假设我们没有了磁盘IO,所有数据都在内存,那么我们的读IO大概有3-6gbps。这种情况下,如果你网络差,一样会很慢。所以尽可能提高网络带宽,压缩传输数据。
网络带宽买你能买的起的最大带宽,nginx的gzip模块可以用来压缩传输数据,通常gzip_comp_level 设为 4-5,再高就是浪费cpu了。同时也可以采用css,js压缩技术,当然这些技术就与nginx优化无关了。
# 10.内核参数的优化
net.ipv4.tcp_max_tw_buckets = 6000 timewait 的数量,默认是180000。
net.ipv4.ip_local_port_range = 1024 65000 允许系统打开的端口范围。
net.ipv4.tcp_tw_recycle = 1 启用timewait 快速回收。
net.ipv4.tcp_tw_reuse = 1 开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。
net.ipv4.tcp_syncookies = 1 开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理。
net.core.somaxconn = 262144 web 应用中listen 函数的backlog 默认会给我们内核参数的net.core.somaxconn 限制到128,而nginx 定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。
net.core.netdev_max_backlog = 262144 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.ipv4.tcp_max_orphans = 262144 系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS 攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_max_syn_backlog = 262144 记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M 内存的系统而言,缺省值是1024,小内存的系统则是128。
net.ipv4.tcp_timestamps = 0 时间戳可以避免序列号的卷绕。一个1Gbps 的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。这里需要将其关掉。
net.ipv4.tcp_synack_retries = 1 为了打开对端的连接,内核需要发送一个SYN 并附带一个回应前面一个SYN 的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。
net.ipv4.tcp_syn_retries = 1 在内核放弃建立连接之前发送SYN 包的数量。
net.ipv4.tcp_fin_timeout = 1 如 果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2 状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60 秒。2.2 内核的通常值是180 秒,3你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB 服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2 的危险性比FIN-WAIT-1 要小,因为它最多只能吃掉1.5K 内存,但是它们的生存期长些。
net.ipv4.tcp_keepalive_time = 30 当keepalive 起用的时候,TCP 发送keepalive 消息的频度。缺省是2 小时。