企业级nginx服务优化(一)
配置文件总结
nginx.conf httpd.conf httpd-vhosts.conf httpd-mpm.conf my.cnf php.ini php-fpm.conf
更改版本信息
[root@localhost ~]# curl -l 127.0.0.1 192.168.1.1 Nginx_1.9.15 [root@localhost ~]# wget -S 118.190.81.171 #获取头文件信息 --2017-03-19 21:01:24-- http://118.190.81.171/ Connecting to 118.190.81.171:80... connected. HTTP request sent, awaiting response... HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Sun, 19 Mar 2017 13:01:24 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive X-Powered-By: PHP/5.5.20第一种 修改版本及版本号 nginx编译前更改
① src/core/nginx.h #define nginx_version 1008001 #define NGINX_VERSION "1.8.1" #修改想要显示的版本如:2.2.23 #define NGINX_VER "nginx/" NGINX_VERSION #将nginx修改成想要显示的软件名称,保留‘/’ #define NGINX_VAR "NGINX" #将nginx修改成想要显示的软件名称(Evan Web Server) #define NGX_OLDPID_EXT ".oldbin" ② src/http/ngx_http_header_filter_module.c static char ngx_http_server_string[] = "Server: nginx" CRLF; #将nginx修改为想要的版本,替换‘nginx’字符串 ③ src/http/ngx_http_special_response.c "<hr><center>nginx</center>" CRLF #将nginx修改为想要的版本信息
第二种 隐藏版本号
nginx配置文件里增加 server_tokens off;
在http {—}里加上server_tokens off;
server_tokens默认值是on,表示显示版本信息,设置server_tokens值是off,就可以在所有地方隐藏nginx的版本信息。
http{ server_tokens off; } [root@localhost ~]# /usr/local/nginx/sbin/nginx -s reload [root@localhost ~]# curl -I 127.0.0.1 HTTP/1.1 200 OK Server: nginx #发现没有版本号了 Date: Wed, 08 Jun 2016 08:48:32 GMT Content-Type: text/html Content-Length: 25 Last-Modified: Tue, 10 May 2016 07:55:53 GMT Connection: keep-alive ETag: "57319409-19" Accept-Ranges: bytes
更改掉nginx的用户
grep “#user” nginx.conf.default //默认文件
#user nobody;
1 vim nginx.conf //修改配置文件
user nginx nginx;
2 ./configure –user=nginx –group=nginx
ps -ef | grep nginx root 56512 1 0 02:35 ? 00:00:00 nginx: master process //主进程用root运行,可以更为nginx,端口必须大于1024 nginx 57470 56512 0 04:04 ? 00:00:00 nginx: worker process
配置nginx worker进程个数
worker_processes auto; //等于CPU的核心数 cat /proc/cpuinfo |grep -c processor 查CPU 更改为 worker_processes 2; 查看(ps -lef | grep nginx) nginx 1822 1784 0 04:14 ? 00:00:00 nginx: worker process nginx 1823 1784 0 04:14 ? 00:00:00 nginx: worker process**配置worker_cpu-affinity ** Nginx默认没有开启利用多核cpu,我们可以通过增加worker_cpu_affinity配置参数来充分利用多核cpu的性能。cpu是任务处理,计算最关键的资源,cpu核越多,性能就越好。 规则设定 (1)cpu有多少个核,就有几位数,1代表内核开启,0代表内核关闭 (2)worker_processes最多开启8个,8个以上性能就不会再提升了,而且稳定性会变的更低,因此8个进程够用了 示例:linode VPS 最低配,8核CPU,nginx配置信息:
worker_processes 8; worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;CPU工作状况:(输入 top 后,按1 查看)
top - 11:16:56 up 39 days, 1:16, 2 users, load average: 0.09, 0.07, 0.10 Tasks: 134 total, 1 running, 133 sleeping, 0 stopped, 0 zombie Cpu0 : 0.0%us, 0.0%sy, 0.0%ni, 95.1%id, 0.0%wa, 0.0%hi, 0.0%si, 4.9%st Cpu1 : 0.0%us, 0.0%sy, 0.0%ni, 98.8%id, 0.0%wa, 0.0%hi, 0.0%si, 1.2%st Cpu2 : 2.3%us, 0.0%sy, 0.0%ni, 92.8%id, 0.0%wa, 0.0%hi, 0.0%si, 4.9%st Cpu3 : 4.6%us, 9.2%sy, 0.0%ni, 81.2%id, 0.0%wa, 0.0%hi, 0.0%si, 5.0%st Cpu4 : 1.9%us, 0.0%sy, 0.0%ni, 96.1%id, 0.0%wa, 0.0%hi, 0.0%si, 1.9%st Cpu5 : 0.0%us, 0.0%sy, 0.0%ni, 98.1%id, 0.0%wa, 0.0%hi, 0.0%si, 1.9%st Cpu6 : 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st Cpu7 : 0.0%us, 0.0%sy, 0.0%ni, 96.9%id, 0.0%wa, 0.0%hi, 0.0%si, 3.1%st Mem: 1024884k total, 891244k used, 133640k free, 144852k buffers Swap: 262140k total, 4172k used, 257968k free, 434072k cached上面的配置表示:8核CPU,开启8个进程。00000001表示开启第一个cpu内核,00000010表示开启第二个cpu内核,依次类推;有多少个核,就有几位数,1表示该内核开启,0表示该内核关闭。 配置实例: 1、2核CPU,开启2个进程
worker_processes 2; worker_cpu_affinity 01 10;2、2核CPU,开启4进程
worker_processes 4; worker_cpu_affinity 01 10 01 10;3、2核CPU,开启8进程
worker_processes 8; worker_cpu_affinity 01 10 01 10 01 10 01 10;4、8核CPU,开启2进程
worker_processes 2; worker_cpu_affinity 10101010 01010101;说明:10101010表示开启了第2,4,6,8内核,01010101表示开始了1,3,5,7内核 通过apache 的ab测试查看nginx对CPU的使用状况:
top - 11:25:53 up 39 days, 1:25, 2 users, load average: 0.33, 0.11, 0.09 Tasks: 133 total, 3 running, 130 sleeping, 0 stopped, 0 zombie Cpu0 : 2.3%us, 0.9%sy, 0.0%ni, 82.7%id, 0.0%wa, 0.0%hi, 0.0%si, 14.1%st Cpu1 : 1.7%us, 0.6%sy, 0.0%ni, 81.8%id, 0.0%wa, 0.0%hi, 0.0%si, 16.0%st Cpu2 : 2.8%us, 1.9%sy, 0.0%ni, 74.4%id, 0.0%wa, 0.0%hi, 0.0%si, 20.9%st Cpu3 : 2.0%us, 0.9%sy, 0.0%ni, 83.0%id, 0.0%wa, 0.0%hi, 0.0%si, 14.0%st Cpu4 : 2.2%us, 0.8%sy, 0.0%ni, 79.3%id, 0.0%wa, 0.0%hi, 0.0%si, 17.6%st Cpu5 : 3.6%us, 1.1%sy, 0.0%ni, 75.9%id, 0.0%wa, 0.0%hi, 0.0%si, 19.5%st Cpu6 : 2.1%us, 0.9%sy, 0.0%ni, 87.2%id, 0.0%wa, 0.0%hi, 0.0%si, 9.8%st Cpu7 : 1.7%us, 0.6%sy, 0.0%ni, 80.6%id, 0.0%wa, 0.0%hi, 0.0%si, 17.1%st Mem: 1024884k total, 891020k used, 133864k free, 144912k buffers Swap: 262140k total, 4172k used, 257968k free, 434244k cached如果多个CPU内核的利用率都相差不多,证明nginx己经成功的利用了多核CPU。 测试结束后,CPU内核的负载应该都同时降低。 安装压力测试软件 **webbench** 安装:
wget http://blog.s135.com/soft/linux/webbench/webbench-1.5.tar.gz tar zxf webbench-1.5.tar.gz cd webbench-1.5 make && make install使用:
webbench -c 20000 -t 180 http://192.168.10.11/ // -c 表示客户端数,-t 表示时间 taskset - retrieve or set a process’s CPU affinity taskset -c 1,2,3 /etc/init.d/mysql start //某个进程跑在某个CPU上
事件处理模型优化
在linux下epoll模型
events { //设定nginx工作模式及连接数上限 use epoll; worker_connections 20480; //每个进程的最大连接数,默认1024 }Max_client=worker_processes*worker_connections; 最大数 进程的最大连接数受系统进程最大打开文件数限制,执行**ulimit -HSn 65535**,或者配置相应文件的 worker_connections的设置后生效。 **worker_rlimit_nofile** 65535; //每个进程最大文件打开数 主标签段 * * * **优化服务器名字hash表大小**
http://wgli.vip/ //泛解析 http{ server_names_hash_bucket_size 64; server_names_hash_max_size 512; //默认为512,一般为CPU L1的4-5倍 }
开启高效的文件传输模式
sendfile on;
tcp_nopush on;
连接超时时间 // php服务建议 短连接
keepalive_timeout 60; //客户端连接保持会话的超时时间 tcp_nodelay on; client_header_timeout 15; //客户端请求头读取超时时间,超过不发送数据,返回408错误 client_body_timeout 15; //主体 send_timeout 15; // 响应客户端的超时时间
上传文件大小限制 (动态应用)
client_max_body_size 10m; //客户端最大上传 超过了报413错误 0是不检查 php默认2m
fastcgi 调优
location ~ .*\.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi.conf; } 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; fastcgi_cache hequan_nginx fastcgi_cache_valid 200 302 1h; fastcgi_cache_valid 301 1d; fastcgi_cache_valid any 1m; fastcgi_cache_min_uses 1; drwx------ 12 nginx root 4096 4月 5 04:32 fastcgi_temp // 临时文件
企业级nginx服务优化(二 )
配置nginx gzip压缩功能
gzip on; gzip_min_length 1k; // 大于1K才压缩 gzip_buffers 4 32k; // 压缩缓存区大小 gzip_http_version 1.1; gzip_comp_level 9; //压缩比率 1-9 gzip_types text/css text/xml application/javascript ; // 压缩类型,不同版本,类型不一样, gzip_vary on; // vary header支持测试软件 unzip test_deflate.zip 火狐流量器加载yslow插件,可以查看缓存结果 * * * ** include mime.types;** # **cat ** **conf/mime.types //版本不一样,类型不一样**
types { text/html html htm shtml; text/css css; text/xml xml; image/gif gif; image/jpeg jpeg jpg; application/javascript js; application/atom+xml atom; application/rss+xml rss;
apache mod_deflate // 编译时 –enable-deflate
nginx expire缓存功能 在客户端本地保存多久 在server标签里
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 3650d; } location ~ .*\.(js|css)?$ { expires 30d; } 实例: location ~(robots.txt) { // 为robots.txt 为7天并不记录404 log_not_found off; expires 7d; break; } apache ./configure --enable-expires cd /httpd-2.2.22/modules/metadata/ //切到apache 软件目录 /application/apache/bin/apxs -c -i -a mod_expires.c // 已dso的方式编译到apache ll /aplication/apache2.2.22/modules/mod_expires.so //检查 * * * [http://www.51cto.com/robots.txt](http://www.51cto.com/robots.txt) /// 写这样的一个文件 User-agent: * Crawl-delay: 500 Disallow: /wuyou/ Disallow: /php/ Disallow: /wuyou_admin/ Disallow: /actions/ 修改nginx.conf,禁止网络爬虫的ua,返回403。
server { listen 80; server_name 127.0.0.1;#添加如下内容即可防止爬虫
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot") { return 403; //也可以把上面改成浏览器,禁止浏览器访问 }
配置nginx 日志切割脚本 sysog日志分析 crontlog
日志切割
cd /application/nginx/logs && \ /bin/mv www_access.log www_access_$(date +%F -d -1day).log /application/nginx/sbin/nginx -s reload crontab -e 00 00 * * * /bin/sh /server/scripts/cut_nginx_log.sh >/dev/null 2&1**不记录不需要的访问日志**
location ~ .*\.(js|jpg|JPG|jpeg|JPEG|css|bmp|gif|GIF)$ { access_log off; } drwxr-xr-x 2 root root 4096 5月 5 21:09 logs/ //主进程是root 是可以写入logs
最小化apache目录及文件权限
- 所有站点目录的用户和组都应为root
- 所有目录权限是755
- 所有文件权限是644
网站服务的用户不能用root
限制ip访问
locaion ~ ^/hequan/ { allow 192.168.10.0/24; deny all; }
报错显示
error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } -rw-r--r-- 1 root root 537 4月 3 19:53 50x.html
tmpfs是一种基于内存的文件系统
vim /etc/rc.local mount -t tmpfs -o size=16m tmpfs /tmp vim /etc/fstab df -hT Filesystem Type Size Used Avail Use% Mounted on tmpfs tmpfs 100M 0 100M 0% /tmp
php_flag engine off // apache不解析PHP
企业级nginx服务优化(三 )
Apache+防盗链
apache worker/prefork /application/apache/bin/apachectl -l | sed -n '/worker\|prefork/p' worker.c Server MPM: Worker ./configure --with-mpm=worke //编译时指定,,默认是prefork
prefork 默认
使用多个子进程,每个子进程只有一个线程
效率高,稳定,安全,比worker消耗资源多
vim /application/apache/conf/extra/httpd-mpm.conf <IfModule mpm_prefork_module> StartServers 10 //服务启动进程数 MinSpareServers 10 //最小空闲数量 MaxSpareServers 15 //最大空闲数量 ServerLimit 2000 MaxClients 1000 //最大进程 并发 MaxRequestsPerChild 5000 //子进程处理的最大进程数 0=不限制 </IfModule> ps -ef | grep http| grep -v grep | wc -l //查看并发连接 6
worker 线程与进程的结合
vim /application/apache/conf/extra/httpd-mpm.conf <IfModule mpm_worker_module> StartServers 2 MaxClients 2000 //并发的客户端连接数量 ServerLimit 25 //总进程数 MinSpareThreads 50 MaxSpareThreads 200 ThreadLimit 200 ThreadsPerChild 100 // 持续的每个服务器的工作线程数量 MaxRequestsPerChild 0 // 单个子进程累计最多处理到少个请求,默认0,不限制的意思 </IfModule> MaxClient <= ServerLimit* ThreadsPerChild MaxClient %ThreadsPerChild =0
cat /application/apache/conf/extra/httpd-default.conf
Timeout 300 KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 5 UseCanonicalName Off AccessFileName .htaccess ServerTokens Full ServerSignature On HostnameLookups Off
并发连接数
pstree -a | grep http |grep -v grep | wc -l
110
apache web 服务防盗链
<Directory "/usr/local/apache2/htdocs/cfan/pic/"> RewriteEngine on RewriteCond %{HTTP_REFERER} !^http://网站域名/.*$ [NC] RewriteRule .*\.(gif|jpg)$ http://代替图标 [R,NC] </Directory>
Nginx防盗链的配置
location ~* \.(gif|jpg|png|swf|flv|bmp)$ { valid_referers none blocked *.hequan.com hequan z.com; if ($invalid_referer) { #rewrite ^/ http://www.hequan .com/403.html; return 403; } }
企业级nginx服务优化(四 )伪静态+php.ini
apache伪静态
打开apache的配置文件httpd.conf
1.把#LoadModule rewrite_module modules/mod_rewrite.so前面的#去掉。 2.找到 # # AllowOverride controls what directives may be placed in .htaccess files. # It can be “All”, “None”, or any combination of the keywords: # Options FileInfo AuthConfig Limit # AllowOverride None 把 AllowOverride None 改为 AllowOverride All
Discuz伪静态配置文件
Apache Web Server(独立主机用户)
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page\%3D$4&page=$3&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/blog-([0-9]+)-([0-9]+)\.html$ $1/home.php?mod=space&uid=$2&do=blog&id=$3&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3&%1 RewriteCond %{QUERY_STRING} ^(.*)$ RewriteRule ^(.*)/([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ $1/plugin.php?id=$2:$3&%1 </IfModule>
正则表达式匹配,其中:
代码如下:
~ 为区分大小写匹配
~* 为不区分大小写匹配
!~和!~*分别为区分大小写不匹配及不区分大小写不匹配
文件及目录匹配,其中:
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录
-x和!-x用来判断文件是否可执行
flag标记有:
last 相当于Apache里的[L]标记,表示完成rewrite
break 终止匹配, 不再匹配后面的规则
redirect 返回302临时重定向 地址栏会显示跳转后的地址
permanent 返回301永久重定向 地址栏会显示跳转后的地址
Discuz伪静态配置文件
Nginx Web Server rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last; rewrite ^([^\.]*)/article-([0-9]+)-([0-9]+)\.html$ $1/portal.php?mod=view&aid=$2&page=$3 last; rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last; rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last; rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last; rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last; rewrite ^([^\.]*)/blog-([0-9]+)-([0-9]+)\.html$ $1/home.php?mod=space&uid=$2&do=blog&id=$3 last; rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3 last; rewrite ^([^\.]*)/([a-z]+[a-z0-9_]*)-([a-z0-9_\-]+)\.html$ $1/plugin.php?id=$2:$3 last; if (!-e $request_filename) { return 404; }
CDN
php php.ini php-fpm.com-------nginx+fcgi php.ini 338 safe_mode = On // 安全模式打开 344 safe_mode_gid = Off 385 disable_functions = system,passthru,exec,shell_exec,popen,p hpinfo //关闭危险函数,如果打开的安全模式,就不用了 435 expose_php = Off //关闭php版本信息在http头中的泄露 703 register_globals = Off //默认关闭全局环境变量 756 magic_quotes_gpc = On //打开 防止SQL注入 538 display_errors = Off //错误信息关闭,测试时开启 643 error_log = /app/logs/php_errors.log // 上面打开,下面才可以 444 max_execution_time = 30 //脚本最大允许执行时间 秒 465 memory_limit = 128M //脚本申请到的最大内存字节数 454 max_input_time = 60 //脚本等待输入数据最长时间 891 upload_max_filesize = 2M //最大上传文件 894 max_file_uploads = 20 //1个请求最大上传文件数量 902 allow_url_fopen = Off //禁止打开远程地址 854 cgi.fix_pathinfo=0 //防止nginx文件类型错误解析漏洞 1461 session.save_handler = memcache 1490 session.save_path = "tcp://192.168.10.11:11211" //为memcached数据库缓存的ip及端口
CGI 公共网关接口
PastCGI php-fpm
php5.3以上: –enable-fpm
php5.2 –enable-fastcgi –enable-fpm –enalbe-force-cgi
# cat php-fpm.conf | grep -v “^;” php-fpm.conf | grep -v “^$” | less
[global]
pid = /opt/php5.6/var/run/php-fpm.pid
error_log = /opt/php5.6/var/log/php-fpm.log
log_level = notice
rlimit_files = 2048
events.mechanism = epoll
[www]
user = www
group = www
listen = /dev/shm/php-cgi.sock
listen.backlog = 65535
pm = dynamic #如何控制子进程,选项有static和dynamic
pm.max_children = 20 #静态方式下开启的php-fpm进程数量
pm.start_servers = 5 #动态方式下的起始php-fpm进程数量
pm.min_spare_servers = 5 #动态方式下的最小php-fpm进程数
pm.max_spare_servers = 20 #动态方式下的最大php-fpm进程数量
pm.max_requests = 1024 #php-fpm子进程能处理的最大请求数
一个php-fpm进程大约消耗20MB-30MB内存
区别:
如果pm设置为 static,那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程。
如果pm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效。
系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程,
然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数。