接到一个求助电话,说是有个阿里云上的服务器,有性能瓶颈,但又没有什么具体的数据,只是说偶尔客户端有少数链接不上,或者链接会忽然中断。个人天,最怕这种情况了,还得本身去找问题表现是什么,再去找什么缘由所致。----懒人可直接点此处,没必要辛苦看文字php
由于是线上的环境,得分两步进行。先检查,看系统或者应用存在什么明显的印迹,分析缘由和处理方法;协商何时能够处理,处理风险是什么。html
怕影响用户体验,白天还不让搞。月黑风高,家里有没暖气啊(用一块闲置显卡挖矿取暖),没办法,只好熬夜苦战一番。mysql
经过了解,该云主机带宽12M,其余方面的配置,我本身登陆看就好。nginx
既然收到带宽,就先看它了,看了好一阵,也不到10M嘛。web
其余资源配置为:
sql
(1)cpu 8core数据库
(2)内存 16G服务器
(3)硬盘 50G系统加120G外挂空间。网络
其中系统负载一直稳定不高,IO也还过得去,系统日志也无明显的报错信息。查看网络状态,TIME_WAIT相对于ESTABLESHED来讲,高了很多(由于文章为过后所写,没法再重现了)。根据经验,大体能够判断引发TIME_OUT高的缘由主要有两种:一种是系统参数(sysctl.conf)设置,另外一种就是应用服务配置。前一种比较好办,乘访问量少的时候,偷偷的修改/etc/sysctl.conf(修改前必定要记得备份哟),而后重载 sysctl -p,再执行netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}',发现TIME_OUT的数量并无减小多少。由此可知,最大的可能就在系统上边的应用。tcp
固然,做为系统管理员,不可能啥都去问人家,你上边安装了什么,都在啥目录啊,程序之间都什么关联?只要有系统登陆权限,哪能难住我们呢!敲ps auxww |more 加一点点耐心,能查个八九不离十。不就是一个nginx + php + mysql 嘛,挨个检查,应该能查到问题所在。这一回车,好多php进程呢,屏幕翻滚了好几屏。心想,没那么多链接数,跑那么多进程干啥呢?作过过滤,数一下php进程数,好家伙301个。
我有个习惯,喜欢从后边往前边查。因而就从数据库开查,show processlist,没线程链接上来,奇怪了啊。还觉得本身眼花,又执行了好几遍,仍是这样。检查mysql错误日志,数据目录,毫无所获,难道不是用这个mysql?吃个橘子压压惊,查看网络状态,看它链接到哪里去了。
竟然没用本机的mysql(不知道装这个干啥),赶忙电话问,说是购买了阿里云的mysql服务,好吧,看来这个就不用查了。
接下来,该看看nginx了。这一查,还真找到几个不顺眼的地方。按照个人习惯,若是系统上要运行多个web站点,通常都会用明确包含的方式对配置文件进行书写,这样作的好处是,看到主配置文件,就知道有多少站点;并且作维护的时候,若是某些站点要临时变动或者变动后整个web服务启动不了,就能够经过注释掉相关的那行包含(include)语句。最不喜欢谁用什么 include *.conf,你写起来省事,但是后边维护就不那么省事。
没办法,我认了。再进具体包含文件的目录,随机打开一个,截取一段以下:
包含里边嵌套包含,那好,咱们就看看它这个包含里边写的啥:
[root@iZm5e64s4c3fznr1kxv1qaZ conf]# more enable-php.conf location ~ [^/]\.php(/|$) { try_files $uri =404; fastcgi_pass unix:/tmp/php-cgi.sock; fastcgi_index index.php; include fastcgi.conf |
又有一个嵌套,狂晕啊!继续看这个fastcgi.conf,就是一个fastsgi_params文件的副本。
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param QUERY_STRING $query_string; fastcgi_param REQUEST_METHOD $request_method; fastcgi_param CONTENT_TYPE $content_type; fastcgi_param CONTENT_LENGTH $content_length; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param REQUEST_URI $request_uri; fastcgi_param DOCUMENT_URI $document_uri; fastcgi_param DOCUMENT_ROOT $document_root; fastcgi_param SERVER_PROTOCOL $server_protocol; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; fastcgi_param GATEWAY_INTERFACE CGI/1.1; fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; fastcgi_param REMOTE_ADDR $remote_addr; fastcgi_param REMOTE_PORT $remote_port; fastcgi_param SERVER_ADDR $server_addr; fastcgi_param SERVER_PORT $server_port; fastcgi_param SERVER_NAME $server_name; # PHP only, required if PHP was built with --enable-force-cgi-redirect fastcgi_param REDIRECT_STATUS 200; |
各位看官,再往下看这个文件,又来了个fastcgi_pass 127.0.0.1 ,是要用什么方式关联php呢?前边那个include指定的"fastcgi_pass unix:/tmp/php-cgi.sock;" 后边又跟这么一个是什么用意?
看到没有,这个fastcgi_pass 127.0.0.1 根本没起做用啊,多是从网上找的,胡乱粘贴一通。另外,也从php那边印证一下,确认服务是否有tcp 9000端口处于监听状态。
[root@iZm5e64s4c3fznr1kxv1qaZ ~]# netstat -anp|grep 9000|wc -l|grep -v grep 0 |
打开其它站点配置文件,全是这个搞法。得统一作规范,方便本身也是方便他人嘛!不过乱归乱,仍是能正常运行,nginx自己也不会对性能产生太大的影响。由这里能够推断,php估计也是胡乱从别的地方复制过来的配置,其内容以下:
[global] pid = /usr/local/php/var/run/php-fpm.pid error_log = /usr/local/php/var/log/php-fpm.log log_level = notice [www] listen = /tmp/php-cgi.sock listen.backlog = -1 listen.allowed_clients = 127.0.0.1 listen.owner = www listen.group = www listen.mode = 0666 user = www group = www pm = dynamic pm.max_children = 300 pm.start_servers = 80 pm.min_spare_servers = 80 pm.max_spare_servers = 300 access.log = /mnt/log/phplog/$pool.access.log access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%" pm.max_requests = 1024 request_terminate_timeout = 0 request_slowlog_timeout = 120 slowlog = /var/log/slow.log |
这几个选项值,直接与性能相关。查看php进程数,一直就是设定的数量300(主进程不算)。最大300,并且一直维持不变,新来的请求没法得到新的进程,因而就只好杀掉已经运行的(有可能用户的链接还在),相似于自杀,能够从php的日志里能够看到大量的进程自杀消息。
通常状况下,应该把最大子进程数(pm.max_children = 300)设置得大一些,最大请求数(pm.max_requests)也须要设置大一些。
把这些问题,记录好汇总之后,电话跟其余人沟通,获得答复是等相关人等在线的时候进行修正,万一业务上有问题,能够一块儿协助处理,但得等两天之后。欲知详细的操做过程,调整后的效果,请猛戳此处便可。