mongodb连接数暴增导致 Remote server has closed the connection拒绝连接的问题处理

问题描述

线上服务器突然报Failed to connect to: 127.0.0.1:27017: Remote server has closed the connection 重启后没过多久问题依旧,通过查询得知每个php-fpm都会占用一个连接资源并不会使用后及时释放,查看线上服务,发现php-fpm进程存在600+,存在大量PPID不存在的进程

处理过程与原因分析

查看cpu和磁盘io发现没有异常,通过查看mongo日志发现有大量连接请求,因为有多处用到了mongodb,为了判断请求源,临时修改项目mongodb配置ip地址,发现请求停止,分析大量请求的原因可能是由什么系统定时任务引起, 临时暂停所有系统定时任务.

根据php-fpm进程数量初步排除mongodb自身问题,重点检查php-fpm进程产生的原因分析有如下几个:

  1. php-fpm数量由php-fpm.con配置,检查php-fpm.conf发现配置文件一切正常,可能的是由其他方式启动的php-fpm进程,并不受限制
  2. 启动的php-fpm因为异常操作导致僵死

因为有php-fpm.conf文件限制,所以判断可能是第一点引起,回想系统有地方用到了pcntl_fork方法利用子进程处理推送等操作,通过查询系统日志和php-fpm进程产生时间,发现基本都有类似子进程的操作.通过网络搜索pcntl_fork产生大量进程原因发现确实会有这种问题发生使用pcntl_fork前需要注册SIGCHLD信号.修改代码后重启php-fpm,观察效果,准备后期全部改用列队处理

后续处理

假设子进程是正常生成的并且可以被正常回收,但是如果一时刻有大量推送产生那么还是会出现上述问题,只需剥离推送代码使用列队处理即可.

 

使用到的技能

  • 通过strace -p 调试进程执行调用情况
  • 通过进程产生时间核对日志查找查找原因
  • 子进程的正确处理方式
  • php-fpm慢日志查询与设置
  • 通过追踪notice和Warning类型的日志有时会有意外收获

https ssl证书申请和部署流程

1.申请免费的StartSSL证书http://www.itbulu.com/startssl.html

2.获取startssl官方的根证书

wget http://www.startssl.com/certs/ca.pem
wget http://www.startssl.com/certs/sub.class1.server.ca.pem
#合并两个证书 cat ca.pem sub.class1.server.ca.pem >> www.wwjie.cn.crt

3.配置通过openssl安装导入,避免nginx启动时输入密码

openssl rsa -in ssl.key -out /etc/nginx/conf.d/ssl/ssl_ca.key

2.配置nginx加载证书

listen       443;
ssl    on;
ssl_certificate    /usr/local/nginx/conf/www.wwjie.cn.crt;   #你从StartSSL下载证书放的路径
ssl_certificate_key     /usr/local/nginx/conf/ssl_ca.key;  #openssl生成key路径
ssl_session_timeout 5m;

强制https

server {  
    listen  80;  
    server_name www.wwjie.com wwjie.cn;  
    rewrite ^(.*)$  https://$host$1 permanent;  
}