Nginx优化
跳到导航
跳到搜索
nginx 配置和目录说明
yum安装nginx的默认目录详解
自定义的配置文件放在/etc/nginx/conf.d
ginx配置文件nginx.conf conf.d(一般都放这个目录下)
nginx配置文件
user nginx nginx; #定义Nginx运行的用户和用户组 worker_processes 1; #nginx进程数,建议设置为等于CPU总核心数。 error_log /var/log/nginx/error.log info; #全局错误日志定义类型,[ debug | info | notice | warn | error | crit ] pid /var/run/nginx.pid; #进程文件 worker_rlimit_nofile 35535; #一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与nginx进程数相除,但是nginx分配请求并不均匀,所以#建议与ulimit -n的值保持一致 events { use epoll; #参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ]; epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型, 如果跑在FreeBS #D上面,就用kqueue模型。 worker_connections 65535; #单个进程最大连接数(最大连接数=连接数*进程数) } http #HTTP区块开始 { include mime.types; #Nginx支持的媒体类型库文件 default_type application/octet-stream; #默认媒体类型 #charset utf-8; #默认编码 server_names_hash_bucket_size 128; #服务器名字的hash表大小 client_header_buffer_size 32k; #上传文件大小限制 large_client_header_buffers 4 64k; #设定请求缓 client_max_body_size 8m; #设定请求缓 sendfile on; #开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为o #ff,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。 autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。 tcp_nopush on; #防止网络阻塞 tcp_nodelay on; #防止网络阻塞 keepalive_timeout 120; #连接超时,单位是秒 #FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。 fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; #gzip模块设置 gzip on; #开启gzip压缩输出 gzip_min_length 1k; #最小压缩文件大小 gzip_buffers 4 16k; #压缩缓冲区 gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0) gzip_comp_level 2; #压缩等级 gzip_types text/x-javascript text/css application/xml; #压缩类型,默认就已经包含text/html,所以下面就不用再写了,写上去也不会有问题,但是会有一个warn。 gzip_vary on; #limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用 ## # Gzip Settings from debian 默认的 折中办法 ## gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 6; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; } #虚拟主机的配置 server { listen 80; #监听端口 server_name localhost; #提供服务的域名主机名 location / { #第一个location区块开始 root html; #站点的根目录,相当于Nginx的安装目录 index index.html index.htm index.jsp; #默认的首页文件,多个用空格分开 } #第一个location区块结果 #图片缓存时间设置 location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 10d; } #JS和CSS缓存时间设置 location ~ .*\.(js|css)?$ { expires 1h; } #日志格式设定 log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for'; access_log /var/log/nginx/access_$(data+%F -d -1day).log access; #定义本虚拟主机的访问日志 location / { #对 "/" 启用反向代理 proxy_pass http://127.0.0.1:88; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #以下是一些反向代理的配置,可选 proxy_set_header Host $host; client_max_body_size 10m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数, proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时) proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置 proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 } #设定查看Nginx状态的地址 location /NginxStatus { stub_status on; access_log on; auth_basic "NginxStatus"; auth_basic_user_file conf/htpasswd; #htpasswd文件的内容可以用apache提供的htpasswd工具来产生。 } #本地动静分离反向代理配置 #所有jsp的页面均交由tomcat或resin处理 location ~ .(jsp|jspx|do)?$ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080; } #所有静态文件由nginx直接读取不经过tomcat或resin location ~ .*.(htm|html|gif|jpg|jpeg|png|bmp|swf|ioc|rar|zip|txt|flv|mid|doc|ppt|pdf|xls|mp3|wma)$ { expires 15d; } location ~ .*.(js|css)?$ { expires 1h; } } }
内核参数优化
net.ipv4.tcp_max_tw_buckets = 5000 #表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为 180000,改为 5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。 net.ipv4.ip_local_port_range = 1024 65000 #表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000 net.ipv4.tcp_tw_reuse = 1 # 开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭 net.ipv4.tcp_tw_recycle = 1 # 开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭 注意 用clb 不能打开 net.ipv4.tcp_syncookies = 1 # 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; net.core.somaxconn = 262144 #每个监听端口允许的最大的监听队列长度,这个值应该适当增大 net.core.netdev_max_backlog = 16384 #有人是262144 #该参数决定了, 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目, 不要设的过大 net.ipv4.tcp_max_orphans = 262144 # 系统所能处理不属于任何进程的TCP sockets最大数量。假如超过这个数量,那么不属于任何进程的连接会被立即reset,并同时显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的 DoS 攻击﹐千万不要依赖这个或是人为的降低这个限制,更应该增加这个值(如果增加了内存之后)。每个孤儿套接字最多能够吃掉你64K不可交换的内存。 系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。 net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数 进入SYN包的最大请求队列.默认1024.对重负载服务器,可调整到2048 记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。 net.ipv4.tcp_synack_retries = 1 tcp_synack_retries 显示或设定 Linux 核心在回应 SYN 要求时会尝试多少次重新发送初始 SYN,ACK 封包后才决定放弃。这是所谓的三段交握 (threeway handshake) 的第二个步骤。即是说系统会尝试多少次去建立由远端启始的 TCP 连线。tcp_synack_retries 的值必须为正整数,并不能超过 255。因为每一次重新发送封包都会耗费约 30 至 40 秒去等待才决定尝试下一次重新发送或决定放弃。tcp_synack_retries 的缺省值为 5,即每一个连线要在约 180 秒 (3 分钟) 后才确定逾时. net.ipv4.tcp_syn_retries = 1 对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1 决定的) net.ipv4.tcp_fin_timeout = 30 如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。 net.ipv4.tcp_keepalive_time = 30 单位是秒 当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时 缺省是2小时,(1200)20分钟
配置优化
note 如果是docker 选择alpine 轻量 1. gzip压缩优化 2. expires缓存有还 3. 网络IO事件模型优化 使用epoll的I/O模型 4. 隐藏软件名称和版本号 5. 防盗链优化 6. 禁止恶意域名解析 7. 禁止通过IP地址访问网站 8. HTTP请求方法优化 9. 防DOS攻击单IP并发连接的控制,与连接速率控制 10. 严格设置web站点目录的权限 11. 将nginx进程以及站点运行于监牢模式 12. 通过robot协议以及HTTP_USER_AGENT防爬虫优化 13. 配置错误页面根据错误码指定网页反馈给用户 14. nginx日志相关优化访问日志切割轮询,不记录指定元素日志、最小化日志目录权限 15. 限制上传到资源目录的程序被访问,防止木马入侵系统破坏文件 16. FastCGI参数buffer和cache配置文件的优化 17. php.ini和php-fpm.conf配置文件的优化 18. 有关web服务的Linux内核方面深度优化(网络连接、IO、内存等) 19. nginx加密传输优化(SSL) 20. web服务器磁盘挂载及网络文件系统的优化 21. 使用nginx cache Events模块 events { worker_connections 2048; multi_accept on; use epoll; server_tokens 并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的 gzip on; keepalive_timeout 60;
1、基本安全优化
1.1 隐藏版本信息
在http模块下加入:
server_tokens off;
删除欢迎主页
cd /usr/share/nginx/html echo >index.html
1.2 隐藏nginx要修改源代码
要修改内容的路径: 第一路径: 1 nginx-1.6.3/src/core/nginx.h 第14,16行 2 #define NGINX_VERSION "1.6.2" 修改为想要的版本号如2.4.3 3 #define NGINX_VER "nginx/" NGINX_VERSION 将nginx修改为想要修改的软件名称,如Apache。 第二路径 1 nginx-1.6.3/src/http/ngx_http_header_filter_module.c第49行 2 grep 'Server:nginx' ngx_http_header_filter_module.cstatic 3 sed -i 's#Server:nginx#Server:Apache#g' ngx_http_header_filter_module.c 第三路径 nginx-1.6.3/src/http/ngx_http_special_response.c第21,30行 "<hr><center>"NGINX_VER "(http://oldboy.blog.51cto.com)</center>" CRLF "<hr><center>OWS</center>" CRLF 然后重新编译
1.3 更改nginx服务的默认用户
--user=www --group=www
1.4 降权启动nginx
2、根据参数优化nginx服务性能
2.1 优化nginx进程个数的策略
在高并发、高访问量的web服务场景,需要事先启动好更多的nginx进程,以保证快速响应并处理大量并发用户的请求。 worker_processes 1;一般调整到与CPU的颗数相同 (1)查看LInux可查看CPU个数及总核数 grep processor /proc/cpuinfo|wc -l (2)查看CPU总颗数 grep 'physical id' /proc/cpuinfo|sort|uniq|wc -l (3)通过执行top命令,然后按数字1,即可显示所有的CPU核数 top 按1键就会显示第一个的信息 Cpu0 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0
https://nginx.org/en/docs/ngx_core_module.html
2.2优化绑定不同的nginx进程到不同的CPU上
默认情况下,nginx的进程跑在某一个CPU或CPU的某一个核上,导致nginx进程使用硬件的资源不均,本节的优化是不同的nginx进程给不同的CPU处理,充分有效的利用有效的硬件资源 1.4核CPU,开户4个进程 worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000; 2.双核配置CPU,开启2个进程 worker_processes 2; worker_cpu_affinity 01 10; 3. worker_processes 8; nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数 (如,2个四核的cpu计为8)。 worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; 为每个进程分配cpu,上例中将8 个进程分配到8 个cpu,当然可以写多个,或者将一个进程分配到多个cpu。 4. 4核CPU,开启2个进程 worker_processes 2; worker_cpu_affinity 0101 1010;
worker_cpu_affinity
https://www.cnblogs.com/pangbing/p/6537188.html
https://www.fujieace.com/nginx/worker.html
https://blog.csdn.net/u011957758/article/details/50959823
worker_rlimit_nofile
worker_rlimit_nofile 65535; 这个指令是指当一个nginx 进程打开的最多文件描述符数目,理论值应该是最多打开文 件数(ulimit -n)与nginx 进程数相除,但是nginx 分配请求并不是那么均匀,所以最好与ulimit -n 的值保持一致。 现在在Linux 2.6内核下开启文件打开数为65535,worker_rlimit_nofile就相应应该填写65535。 这是因为nginx调度时分配请求到进程并不是那么的均衡,所以假如填写10240,总并发量达到3-4万时就有进程可能超过10240了,这时会返回502错误。 查看linux系统文件描述符的方法: #这个不太一样 注意 [root@web001 ~]# sysctl -a | grep fs.file fs.file-max = 789972 fs.file-nr = 510 0 789972 java-01 nginx]# sysctl -a | grep fs.file fs.file-max = 789880 fs.file-nr = 1504 0 789880 fs.xfs.filestream_centisecs = 3000 sysctl: reading key "net.ipv6.conf.all.stable_secret" sysctl: reading key "net.ipv6.conf.br-c9b7840ce3c6.stable_secret" sysctl: reading key "net.ipv6.conf.default.stable_secret" sysctl: reading key "net.ipv6.conf.docker0.stable_secret" sysctl: reading key "net.ipv6.conf.eth0.stable_secret" sysctl: reading key "net.ipv6.conf.eth1.stable_secret" sysctl: reading key "net.ipv6.conf.lo.stable_secret" sysctl: reading key "net.ipv6.conf.veth87c2bc5.stable_secret"
worker_connections 65535
worker_connections 65535; 每个进程允许的最多连接数, 理论上每台nginx 服务器的最大连接数为worker_processes*worker_connections。
keepalive_timeout
keepalive_timeout 60; keepalive 超时时间
一些暂时还没加上的nginx 配置优化
7. client_header_buffer_size 4k; 客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。 分页大小可以用命令getconf PAGESIZE 取得。 [root@web001 ~]# getconf PAGESIZE 4096 但也有client_header_buffer_size超过4k的情况,但是client_header_buffer_size该值必须设置为“系统分页大小”的整倍数。 8. open_file_cache max=65535 inactive=60s; 这个将为打开文件指定缓存,默认是没有启用的,max 指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。 9. open_file_cache_valid 80s; 这个是指多长时间检查一次缓存的有效信息。 10. open_file_cache_min_uses 1; open_file_cache 指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。
2.3 nginx事件处理模型优化
nginx的连接处理机制在于不同的操作系统会采用不同的I/O模型,Linux下,nginx使用epoll的I/O多路复用模型,在freebsd使用kqueue的IO多路复用模型,在solaris使用/dev/pool方式的IO多路复用模型,在windows使用的icop等等。 要根据系统类型不同选择不同的事务处理模型,选择有“use [ kqueue | rtsig |epool |dev/pool |select |pllo ];”我们使用的是Centos,因此将nginx的事件处理模型调整为epool模型。 events { worker_connections 1024; use epoll; multi_accept on; }
2.8 配置nginx gzip压缩实现性能优化
http模块中加入gzip的配置 我常用的例子 gzip on; gzip_min_length 1k; gzip_comp_level 3; gzip_proxied expired ; gzip_types text/plain application/javascript text/xml text/css; #老的不正确写法 #gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css; gzip_disable "MSIE [1-6]\."; gzip_vary on; gzip_buffers 4 16k; #压缩缓冲区 gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0) #debina 10自带的写法 gzip on; # gzip_vary on; # gzip_proxied any; # gzip_comp_level 6; # gzip_buffers 16 8k; # gzip_http_version 1.1; # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; #debina 10自带的写法 测试效果 curl -I -H "Accept-Encoding: gzip, deflate" "mq.com" HTTP/1.1 200 OK Server: nginx/1.12.2 Date: Thu, 22 Aug 2019 09:25:01 GMT Content-Type: text/html Connection: keep-alive Vary: Accept-Encoding etag: W/"2505434914" last-modified: Tue, 20 Aug 2019 02:27:20 GMT Content-Encoding: gzip #看到没 有gzip curl -I -H "Accept-Encoding: gzip, deflate" "a.com" HTTP/1.1 200 OK Server: nginx/1.12.2 Date: Wed, 21 Aug 2019 02:35:39 GMT Content-Type: text/html Content-Length: 8 Last-Modified: Mon, 19 Aug 2019 07:14:41 GMT Connection: keep-alive ETag: "5d5a4c61-8" Accept-Ranges: bytes 下面是解说 gzip on; #开启gzip gzip_min_length 1k; #低于1kb的资源不压缩 gzip_comp_level 3; #压缩级别【1-9】,越大压缩率越高,同时消耗cpu资源也越多,建议设置在4左右。 gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css; #需要压缩哪些响应类型的资源,多个空格隔开。不建议压缩图片,下面会讲为什么。 gzip_disable "MSIE [1-6]\."; #配置禁用gzip条件,支持正则。此处表示ie6及以下不启用gzip(因为ie低版本不支持) gzip_vary on; #是否添加“Vary: Accept-Encoding”响应头 gzip_buffers 4 16k; #压缩缓冲区 gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0) #limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用 gzip_buffers 设置用于处理请求压缩的缓冲区数量和大小。比如32 4K表示按照内存页(one memory page)大小以4K为单位(即一个系统中内存页为4K),申请32倍的内存空间。建议此项不设置,使用默认值 官方eg gzip on; gzip_min_length 1000; gzip_proxied expired no-cache no-store private auth; gzip_types text/plain application/xml;
Note
在应用服务器前,公司还有一层Nginx的集群作为七层负责均衡,在这一层上,是没有开启gzip的。 如果我们使用了proxy_pass进行反向代理,那么nginx和后端的upstream server之间默认是用HTTP/1.0协议通信的。 如果我们的Cache Server也是nginx,而前端的nginx没有开启gzip。 同时,我们后端的nginx上没有设置gzip_http_version为1.0,那么Cache的url将不会进行gzip压缩 我相信,以后还有人会入坑,比如你用Apache ab做压测,如果不是设置gzip_http_version为1.0,你也压不出gzip的效果(同样的道理)。
https://blog.csdn.net/huangbaokang/article/details/79931429
2.9 nginx expires功能
nginx如何启用ETag,提高访问速度
开启gzip时,可能与etag出现冲突,用浏览器多次请求此网站的静态元素,如果只返回200,不返回304,证明存在冲突,请去步骤4;没有冲突去步骤2
未完 可查看下面
other
grep 'open files' /proc/$( cat /var/run/nginx.pid )/limits 这个可以查看到nginx实际最大连接数
刚才看是1024 配置文件是65535 设置了下nginx.service文件 添加了LimitNOFILE=65535