2013年8月17日星期六

PHP 连接 Mongo DB 神奇错误(找到根源,未找到说法)

       问题描述:测试环境的配置都是从线上的环境copy 下来的,nginx php 配置不存在问题,但开发反应经常出现页面之间返回代码或者页面显示一半代码一半内容。截图如下:
         32966958.jpg 
        或者浏览器直接返回这部分代码:
object(MongoCursorException)#9 (9) { ["message":protected]=> string(21) "couldn't send command" ["string":"Exception":private]=> string(0) "" ["code":protected]=> int(19) ["file":protected]=> string(50) "/diska/htdocs/i2012/include/class.MongoAdapter.php" ["line":protected]=> int(321) ["trace":"Exception":private]=> array(9) { [0]=> array(6) { ["file"]=> string(50) 
…………………………中间就省略吧["host":"MongoCursorException":private]=> string(18) "10.11.80.123:27015" ["fd":"MongoCursorException":private]=> int(592) } 
       DBA直接把结论说的很明白:"这问题我没空,也用不着我。" 看着人就头大,测试过连接,包括数据库的,都没
有问题,把nginx 的upstream 关掉后,仍然会出现此问题,把php 代码中的mongo 组换成一个,还是会出现此问题,
纠结。由于所有的配置都是参考正式环境的,测试的每台机器的配置分配的可怜死了,512 内存,还运行一坨的东西。
       抱怨归抱怨,问题还是得找出来,不然coder 也会抱怨我。出问题,找原因最是一件麻烦事,花了两个多小时时间
专注于服务器的nginx 和php 日志上,都没办法找到出口。意外之中的收获是:每次重启php-fpm 后,发现访问变得正
常,大概5分钟左右的时间,不访问,就会出现上面两种错误中的一种了。刚开始也想跟开发说这算一个下下策,写个
计划任务,没5分钟重启一次php 就完事了吗?
       这种掩盖错误的方法我是觉得对不住这份工钱,继续找原因。按照前面发现问题可能是在php-fpm 上,那就追踪一
下php-fpm 的进程及tcp 连接情况。但通过lsof 和netstat 观察到的结果,tcp 的连接 和 TIME_WAIT等都很快的被释放掉
了,这样貌似这个超时就不大可能是 php-fpm 。
       再一次陷于被动无头绪的状态。这问题也放了一天。(用计划任务重启的方式满足正常访问)
       第三天抽空,带出一个疑问想再看看情况:这个5分钟左右的超时到底是哪来的?php和nginx 绝对可以排除,那就
肯定是mongo 上的。找DBA 要了系统的相关信息,登录发现:

[root@localhost ~]# netstat -tlnup |grep 27011
tcp        0      0 10.11.80.106:27011          0.0.0.0:*                   LISTEN      13689/haproxy 

haproxy.cfg  超时配置(就是这里啦,5分钟)
defaults
    mode        tcp
    log         global
    option      dontlognull
    timeout connect 10000 #
    timeout client 300000  #
    timeout server 300000
    maxconn     60000

        说实话,看到上面的,我一愣,竟然用了haproxy 在这里。线上的环境是没有的,瞎搞,想骂人的冲动都有了。但
还是把原因找到为先。看了一下haproxy 的配置,把php代码中端口换成mongo 的监听端口后,问题解决。
        按照通常处理问题的方法,接下来的应该是件容易活,可是,去直到现在还未能找到haproxy 为何不能代理mongo
的原因,记忆深刻,mark 一下,我心还在,希望后面尽快能够研究出来。有高人看到此贴,望能说出一二。

没有评论:

发表评论