/ PHP

piwik页面卡住问题追查记录

今天无聊就折腾了下piwik,但是发现有概率页面会504,查看nginx日志是php执行超时,而且第一次504之后,后面的所有页面访问全部都是504,重启php-fpm之后又可以正常访问了。

于是打开php-fpm的slowlog,在页面504的时候slowlog里也打出了对应的调用栈:

script_filename = /home/www/online/website/piwik/index.php [0x00007fbec1568f48] session_start() /home/www/online/website/piwik/libs/Zend/Session.php:469 [0x00007fbec1568370] start() /home/www/online/website/piwik/core/Session.php:113 [0x00007fbec1567e68] start() /home/www/online/website/piwik/core/FrontController.php:416 [0x00007fbec1567a08] prepareDispatch() /home/www/online/website/piwik/core/FrontController.php:502 [0x00007fbec15675f8] doDispatch() /home/www/online/website/piwik/core/FrontController.php:84 [0x00007fbec15671d0] dispatch() /home/www/online/website/piwik/core/dispatch.php:34 [0x00007fbec15669a0] +++ dump failed

看来是执行session_start的时候卡住了,php的session是有锁机制的,如果某个页面开启了session,并且该请求尚未结束,则后续该session的请求就会全部锁住,等待之前的请求结束。

也就是说piwki页面卡住的原因是之前的某次请求没有结束,但是是哪个请求没有结束呢?因为没有看piwik的代码,而且504是有概率出现的,并不是访问了某个特定的页面后才504,问题追到这里就遇到了瓶颈。

鼓捣了半天之后突然想到,那个没有结束的请求肯定会打在php的slowlog里面,于是重新检查了一下,果真在一堆session的slowlog中发现了不一样的日志:

script_filename = /home/www/online/website/piwik/index.php [0x00007fbec1568c40] curl_exec() /home/www/online/website/piwik/core/Http.php:483 [0x00007fbec1568798] sendHttpRequestBy() /home/www/online/website/piwik/core/Http.php:94 [0x00007fbec15685e0] sendHttpRequest() /home/www/online/website/piwik/core/Http.php:720 [0x00007fbec1567e00] fetchRemoteFile() /home/www/online/website/piwik/plugins/ExampleRssWidget/RssRenderer.php:46 [0x00007fbec1567be8] get() /home/www/online/website/piwik/plugins/ExampleRssWidget/Controller.php:25 [0x00007fffe0d3cf00] rssPiwik() unknown:0 [0x00007fbec1567788] call_user_func_array() /home/www/online/website/piwik/core/FrontController.php:531 [0x00007fbec1567378] doDispatch() /home/www/online/website/piwik/core/FrontController.php:84 [0x00007fbec1566f50] dispatch() /home/www/online/website/piwik/core/dispatch.php:34 [0x00007fbec1566720] +++ dump failed

看上去是个curl调用http请求,追了下里面的代码,发现是个公共的类,并不是固定请求某个url,这也简单,在curl_exec()之前加个打日志的代码,把curl请求的url记录下来。

于是又随便点了记下piwik的页面,发现有记录了一个url:http://feeds.feedburner.com/Piwik

看上去是rss的url,直接在piwik的grep这个url,结果如下:

./plugins/ExampleRssWidget/Controller.php: $rss = new RssRenderer('http://feeds.feedburner.com/Piwik'); ./plugins/ExampleRssWidget/Controller.php: $rss = new RssRenderer('http://feeds.feedburner.com/PiwikReleases');

是个插件的代码。

进到piwik的后台,直接把ExampleRssWidget这个插件禁用。问题解决!

PS:中国的国情啊……………………

piwik页面卡住问题追查记录
Share this