天天看點

解決phpMyAdmin在nginx+php-fpm模式下無法使用的問題

昨天接到一個網友的問題,說yum安裝nginx+php-fpm+mysql+phpmyadmin後,發現phpmyadmin無法打開,一直報502錯誤已經抓狂半天了,本着幫助别人快樂自己的原則,遠端幫他看了一下, 現記錄和總結如下,問題解決思路的總結放在文章最後,問題解決思路總結也是本文的重點。

問題環境:centos6通過yum安裝的nginx+php-fpm+mysql+phpmyadmin

問題描述:安裝完成後發現nginx沒有問題,而phpmyadmin無法打開,提示502錯誤

問題解決過程

檢視問題環境的安裝包:

nginx-filesystem-1.0.15-12.el6.noarch

nginx-1.0.15-12.el6.x86_64

rrdtool-php-1.3.8-7.el6.x86_64

php-pear-1.9.4-4.el6.noarch

php-devel-5.3.3-46.el6_6.x86_64

php-mbstring-5.3.3-46.el6_6.x86_64

php-mcrypt-5.3.3-3.el6.x86_64

php-5.3.3-46.el6_6.x86_64

php-tidy-5.3.3-46.el6_6.x86_64

php-pecl-memcache-3.0.5-4.el6.x86_64

php-xmlrpc-5.3.3-46.el6_6.x86_64

php-xmlseclibs-1.3.1-3.el6.noarch

php-common-5.3.3-46.el6_6.x86_64

php-pdo-5.3.3-46.el6_6.x86_64

php-xml-5.3.3-46.el6_6.x86_64

php-fpm-5.3.3-46.el6_6.x86_64

php-cli-5.3.3-46.el6_6.x86_64

php-mysql-5.3.3-46.el6_6.x86_64

php-eaccelerator-0.9.6.1-1.el6.x86_64

php-gd-5.3.3-46.el6_6.x86_64

根據nginx報的502錯誤,可以初步判斷是upstream出現了問題,再提到upstream之前,先列一下nginx的配置檔案(去掉注釋,我已經将nginx記錄錯誤日志的級别從預設級别提升到info)。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<code>user              nginx;   </code>

<code>worker_processes  1;</code>

<code>error_log  </code><code>/var/log/nginx/error</code><code>.log info;</code>

<code>pid        </code><code>/var/run/nginx</code><code>.pid;</code>

<code>events {   </code>

<code>    </code><code>worker_connections  1024;    </code>

<code>}</code>

<code>http {   </code>

<code>    </code><code>include       </code><code>/etc/nginx/mime</code><code>.types;    </code>

<code>    </code><code>default_type  application</code><code>/octet-stream</code><code>;</code>

<code>    </code><code>client_max_body_size 10m;</code>

<code>    </code><code>log_format  main  </code><code>'$remote_addr - $remote_user [$time_local] "$request" '</code>   

<code>                      </code><code>'$status $body_bytes_sent "$http_referer" '</code>    

<code>                      </code><code>'"$http_user_agent" "$http_x_forwarded_for"'</code><code>;</code>

<code>    </code><code>access_log  </code><code>/var/log/nginx/access</code><code>.log  main;</code>

<code>    </code><code>sendfile        on;   </code>

<code>    </code><code>keepalive_timeout  65;  </code>

<code>    </code><code>include </code><code>/etc/nginx/conf</code><code>.d/*.conf;</code>

由于此配置檔案中沒有顯式寫明任何server,是以需要檢視一下include /etc/nginx/conf.d/*.conf; 所包含的預設server檔案,即/etc/nginx/conf.d/default.conf,去掉注釋

20

21

22

23

24

25

26

27

<code>cat</code> <code>/etc/nginx/conf</code><code>.d</code><code>/default</code><code>.conf    </code>

<code>server {    </code>

<code>    </code><code>listen       80 default_server;    </code>

<code>    </code><code>server_name  _;  </code>

<code>    </code><code>include </code><code>/etc/nginx/default</code><code>.d/*.conf;</code>

<code>    </code><code>location / {   </code>

<code>        </code><code>root   </code><code>/usr/share/nginx/html</code><code>;    </code>

<code>        </code><code>index  index.php index.html index.htm;    </code>

<code>    </code><code>}</code>

<code>    </code><code>error_page  404              </code><code>/404</code><code>.html;   </code>

<code>    </code><code>location = </code><code>/404</code><code>.html {    </code>

<code>    </code><code>}  </code>

<code>    </code><code>error_page   500 502 503 504  </code><code>/50x</code><code>.html;    </code>

<code>    </code><code>location = </code><code>/50x</code><code>.html {    </code>

<code>     </code><code>location ~ [^/]\.php(/|$) {   </code>

<code>                </code><code>fastcgi_split_path_info ^(.+?\.php)(/.*)$;    </code>

<code>                </code><code>if</code> <code>(!-f $document_root$fastcgi_script_name) {    </code>

<code>                        </code><code>return</code> <code>404;    </code>

<code>                </code><code>}    </code>

<code>                </code><code>fastcgi_pass 127.0.0.1:9000;    </code>

<code>                </code><code>fastcgi_index index.php;    </code>

<code>                </code><code>include fastcgi_params;    </code>

<code>     </code><code>}    </code>

初步判斷,此nginx的配置确實沒有問題,應該是php-fpm或者php本身的問題(縮小問題範圍)。

查閱nginx日志檔案(/var/log/nginx/error.log),發現如下提示,确定是php-fpm的問題,fastcgi也算是對upstream的一種代理

<code>2015</code><code>/08/14</code> <code>17:05:32 [notice] 9645</code><code>#0: using the "epoll" event method   </code>

<code>2015</code><code>/08/14</code> <code>17:05:32 [notice] 9645</code><code>#0: nginx/1.0.15    </code>

<code>2015</code><code>/08/14</code> <code>17:05:32 [notice] 9645</code><code>#0: built by gcc 4.4.7 20120313 (red hat 4.4.7-11) (gcc)     </code>

<code>2015</code><code>/08/14</code> <code>17:05:32 [notice] 9645</code><code>#0: os: linux 2.6.32-504.el6.x86_64    </code>

<code>2015</code><code>/08/14</code> <code>17:05:32 [notice] 9645</code><code>#0: getrlimit(rlimit_nofile): 65535:65535    </code>

<code>2015</code><code>/08/14</code> <code>17:05:32 [notice] 9646</code><code>#0: start worker processes    </code>

<code>2015</code><code>/08/14</code> <code>17:05:32 [notice] 9646</code><code>#0: start worker process 9648    </code>

<code>2015</code><code>/08/14</code> <code>17:05:36 [error] 9648</code><code>#0: *1 recv() failed (104: connection reset by peer) while reading response header from upstream, client: 192.168.1.228, server: 192.168.1.101, request: "get / http/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "192.168.1.101"    </code>

<code>2015</code><code>/08/14</code> <code>17:09:22 [error] 9648</code><code>#0: *4 recv() failed (104: connection reset by peer) while reading response header from upstream, client: 192.168.1.228, server: 192.168.1.101, request: "get / http/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "192.168.1.101"    </code>

<code>2015</code><code>/08/14</code> <code>17:11:23 [error] 9648</code><code>#0: *7 recv() failed (104: connection reset by peer) while reading response header from upstream, client: 192.168.1.228, server: 192.168.1.101, request: "get / http/1.1", upstream: "fastcgi://127.0.0.1:9000", host: "192.168.1.101"    </code>

<code>2015</code><code>/08/14</code> <code>17:11:33 [info] 9648</code><code>#0: *9 client closed prematurely connection while reading client request line, client: 192.168.1.228, server: 192.168.1.101</code>

建立一個能打開phpinfo的檔案,檢視php檔案能否正确解析(進一步縮小問題範圍)

發現php-fpm能正常解析php檔案,裡面的各個php元件都顯示正常

檢視phpmyadmin的版本,查閱官方網站的文檔看看是否支援php5.3.3,發現目前的phpmyadmin支援,是以應該不是phpmyadmin的問題

開始檢查php-fpm的日志(/var/log/php-fpm/error.log),發現如下所示:

<code>[14-aug-2015 16:34:53] notice: fpm is running, pid 9522   </code>

<code>[14-aug-2015 16:34:53] notice: ready to handle connections    </code>

<code>[14-aug-2015 16:43:54] warning: [pool www] child 9527 exited on signal 11 (sigsegv) after 541.401349 seconds from start    </code>

<code>[14-aug-2015 16:43:55] notice: [pool www] child 9614 started    </code>

<code>[14-aug-2015 16:44:00] warning: [pool www] child 9526 exited on signal 11 (sigsegv) after 547.107407 seconds from start    </code>

<code>[14-aug-2015 16:44:00] notice: [pool www] child 9615 started    </code>

<code>[14-aug-2015 17:05:36] warning: [pool www] child 9523 exited on signal 11 (sigsegv) after 1843.098829 seconds from start    </code>

<code>[14-aug-2015 17:05:36] notice: [pool www] child 9649 started</code>

這個日志顯然不足以提供足夠的資訊來解決問題,是以修改php-fpm和php.ini對日志級别的一些參數配置,以提升日志級别,擷取詳細的錯誤資訊。

搜尋配置檔案的中log關鍵字,或者根據文檔或資料修改,一些方法或步驟如下:

/etc/php-fpm.conf檔案,将日志級别從notice改動到debug

<code>log_level = debug</code>

/etc/php-fpm.d/www.conf檔案,将php worker的标準輸出和錯誤輸出從/dev/null 重定向到主要的錯誤日志中,即/var/log/php-fpm/error.log

<code>catch_workers_output = </code><code>yes</code>

/etc/php.ini檔案

<code>error_reporting = e_all &amp; ~e_deprecated</code>

<code>display_errors = on</code>

<code>display_startup_errors = on</code>

<code>log_errors = on</code>

<code>track_errors = on</code>

<code>html_errors = on</code>

再次重新啟動php-fpm,發現worker中的詳細錯誤:

<code>[14-aug-2015 17:09:18] notice: fpm is running, pid 9672   </code>

<code>[14-aug-2015 17:09:18] notice: ready to handle connections    </code>

<code>[14-aug-2015 17:09:22] warning: [pool www] child 9673 said into stderr: </code><code>"[fri aug 14 17:09:22 2015"</code>    

<code>[14-aug-2015 17:09:22] warning: [pool www] child 9673 said into stderr: </code><code>"] [notice] eaccelerator(9673): php crashed on opline 30 of pma_url_getcommon() at /usr/share/nginx/html/libraries/url_generating.lib.php:188"</code>    

<code>[14-aug-2015 17:09:22] warning: [pool www] child 9673 said into stderr: </code><code>""</code>    

<code>[14-aug-2015 17:09:22] warning: [pool www] child 9673 exited on signal 11 (sigsegv) after 4.286828 seconds from start    </code>

<code>[14-aug-2015 17:09:22] notice: [pool www] child 9679 started    </code>

<code>[14-aug-2015 17:11:23] warning: [pool www] child 9675 said into stderr: </code><code>"[fri aug 14 17:11:23 2015"</code>    

<code>[14-aug-2015 17:11:23] warning: [pool www] child 9675 said into stderr: </code><code>"] [notice] eaccelerator(9675): php crashed on opline 30 of pma_url_getcommon() at /usr/share/nginx/html/libraries/url_generating.lib.php:188"</code>

錯誤資訊中提到eaccelerator這個php子產品,是以先确定一下是不是由于這個子產品有問題,是以,先将此子產品禁用,方法是将/etc/php.d/eaccelerator.ini檔案更改個字尾名稱,例如mv /etc/php.d/eaccelerator.ini /etc/php.d/eaccelerator.ini~,然後重新開機php-fpm,再校驗一下結果,發現問題已經解決。

可能是eaccelerator與phpmyadmin沖突的原因,是以要想使用phpmyadmin可以将此子產品禁用,或者安裝時跳過這個包。

注釋:eaccelerator是一個自由開放源碼php加速器,優化和動态内容緩存,提高了php腳本的緩存性能,使得php腳本在編譯的狀态下,對伺服器的開銷幾乎完全消除。它還有對腳本起優化作用,以加快其執行效率。使php程式代碼執效率能提高1-10倍。(來自bdbk)

問題解決思路總結

第0條,溝通是診斷故障的關鍵,詳細了解問題始末,例如部署方案,步驟,做了哪些操作等

第一,根據經驗判斷,nginx+php-fpm+phpmyadmin是很牢靠的組合,是以判斷這是個例問題,而不是批量問題,是以直接開始動手,登入到系統中檢視安裝的軟體包,nginx、php和phpmyadmin版本都是要檢視的,此步驟有助于根據掌握的知識和經驗,初步判斷是否互相相容,是否有未修複bug等。

第二,執行nginx -t檢查nginx的配置檔案有無顯式錯誤,檢查nginx運作狀态

第三,執行php-fpm -t檢查php-fpm的配置檔案有無顯式錯誤,檢查php-fpm的運作狀态

第四,檢查錯誤日志,先檢查nginx的錯誤日志,因為它是“第一現場”,再檢查php-fpm日志,因為它是“第二現場”

第五,如果日志提示明顯,則按照日志提示,修改相應的配置檔案,再次驗證問題

第六,如果依然有問題,則本步驟就是解決問題的最關鍵的步驟,需要提升記錄日志的級别,這也就是為什麼有debug為什麼叫做調試,将nginx的日志級别提升到info(為什麼不能提升到debug,nginx編譯時有個--debug選項,不确定時可以不用),将php的日志級别提升到debug,打開所有的php調試開關

第七,重新啟動nginx和php-fpm後,配置檔案生效,重新打開網頁重制問題,再次打開日志,根據日志提示内容再次,修改相應的配置檔案,再次驗證問題

第八,如果反複修改無果後,該查閱官方手冊就查閱官方手冊,該google 搜尋就google搜尋,該回報bug就回報bug,如果持續無果,則換種解決問題的方式,尋找正确的解決方案,參照如下:

參考已有的成功的版本組合,更換版本組合或者修改配置檔案,消除環境差異性,适用于快速解決問題

将yum安裝改為編譯安裝,或者yum安裝更少的包,以最小化的安裝方式将問題範圍縮減到最小,進而确定問題,提升解決問題的能力,适用于研究和學習

最後補充一句:隻要出現的問題能夠重制,而不是随機出現,則就一定能很好的解決,是以不要慌,也不要浮躁,更不要放棄,甚至可以緩一緩後再冷靜處理。

--end--