欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入分析nginx+php-fpm服務(wù)HTTP狀態(tài)碼502

 更新時間:2019年07月19日 11:33:38   作者:leezhxing  
這篇文章主要介紹了深入分析nginx+php-fpm服務(wù)HTTP狀態(tài)碼502,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

我們的一個web項目,由于新上城市增多,導(dǎo)致訪問量增大,DB壓力增大,作為提供接口的業(yè)務(wù)方,最近被下游反饋大量請求“502”。

502,bad gateway,一般都是upstream(這里就是php)出錯,對于php,造成502的原因常見的就是腳本執(zhí)行超過timeout設(shè)置時間,或者timeout設(shè)置過大,導(dǎo)致php進程長時間不能被釋放,沒有空閑worker進程來接客。

我們的項目就是php執(zhí)行時間設(shè)置過短導(dǎo)致的,對于這種情況,可以先適當增大php的執(zhí)行時間,先保證清除502,優(yōu)化的事情畢竟要花更多的時間。

控制php執(zhí)行時間的選項有兩個,在php.ini中 max_execution_time 和php-fpm中 request_terminate_timeout,其中 request_terminate_timeout 可以覆蓋 max_execution_time,所以如果不想改全局的php.ini,那只改php-fpm的配置就可以了。

下邊我就來詳細的分析一下為什么php腳本執(zhí)行超出設(shè)置時間會導(dǎo)致nginx返回502。

先來布景,讓問題復(fù)現(xiàn):

nginx和php分別只啟動一個worker,方便追蹤。

php-fpm的request_terminate_timeout設(shè)置為3S。

測試腳本test.php

sleep(20);
echo 'ok';

go go go:

在瀏覽器訪問www.v.com/test.php,3S后如期出現(xiàn)...404???what???

出師不利啊,趕緊看看nginx的配置文件

這個location配置是當發(fā)生5xx錯誤時跳轉(zhuǎn)到一個好看點的界面,但是我在/usr/share/nginx/html下并沒有50x.html這個文件。所以搞了個404出來。這不是很影響我判斷問題的準確性?直接注釋掉!再次訪問,等待3S,終于'正常'的界面出來了。

環(huán)境好了,下邊就上套路,按照web問題的排查套路走一遍,先看看錯誤日志吧:

nginx:

報錯都是 recv() failed (104: Connection reset by peer。

recv時失敗了,連接被重置了。為啥連接被重置了?難道一言不合。

我們在看看php-fpm的錯誤日志:

(注意php-fpm中php_admin_value[error_log]選項指定php的錯誤日志,會覆蓋php.ini中的。但是這里不是看php的錯誤,而是看php-fpm的錯誤。php-fpm的錯誤日志由php-fpm.conf中的error_log選項指定。)

每一次請求都是產(chǎn)生2個WARNING和1個NOTICE:

WARNING:腳本執(zhí)行超時了,終止了。

WARNING:子進程收到SIGTERM信號退出了。

NOTICE:啟了一個新的子進程(因為我設(shè)置的pm.min_spare_servers = 1)

看來如果php的worker進程執(zhí)行超時,不僅終止腳本執(zhí)行,而且worker進程也會退出??磥韓ginx的報錯連接被重置是因為php的worker進程退出了(在TCP連接中一方如果斷掉的話會發(fā)送RST給另一方)

通過日志已經(jīng)可以知道php腳本執(zhí)行超時,worker子進程退出,導(dǎo)致nginx報錯Connection reset by peer,下邊我們通過strace來看看php和nginx的情況:

php:

1.accept一個nginx的連接請求(socket,bind,listen都在master中完成 ),可以看到nginx的端口是47039,從FD0中讀取數(shù)據(jù),就是從標準輸入中,這個是fast-cgi協(xié)議規(guī)定的。accept之后的已連接描述符是3。

2.從FD3中讀取nginx傳遞過來的數(shù)據(jù),fastcgi協(xié)議格式,接收了856字節(jié)。為什么read5次呢?

因為fastcgi協(xié)議數(shù)據(jù)包是8字節(jié)對齊,由包頭和包體組成。并且都是會先發(fā)一個request數(shù)據(jù)包,包含一些請求ID,版本,typpe等信息(包頭包體各占8字節(jié)),再發(fā)一個params數(shù)據(jù)包,傳遞get參數(shù)和環(huán)境變量(包頭8字節(jié),包體變長),最后發(fā)送一個沒有包體只有包頭的params數(shù)據(jù)包,表示參數(shù)發(fā)送結(jié)束(包頭8字節(jié))。所以前3個read用來讀出request包的包頭和包體,還有params包的包頭,第四個read是讀取真正的數(shù)據(jù),最后一個read是讀取最后一個params包的包頭。所以nginx傳遞的數(shù)據(jù)應(yīng)該是8+8+8+856+8=896字節(jié)(和下邊nginx的傳輸bytes能對應(yīng)上)。注意如果是post方式,還會發(fā)送stdin數(shù)據(jù)包。

3.設(shè)置休眠20S,就是php程序中的sleep(20),之后由于進程被終止了,所以后邊就沒啦。strace程序也退出啦。

nginx:

1.accept到瀏覽器的請求,可以看到瀏覽器端的端口是56434,IP是192.168.1.105,已建立連接的FD是3。

2.從FD3中接收數(shù)據(jù),HTTP協(xié)議。

3.創(chuàng)建一個socket,F(xiàn)D21,用于和php建立連接。

4.連接到FD21,可以看到連接的是本機的9000端口,這里nginx和php-fpm使用IP socket連接方式,nginx和php-fpm部署在一臺機器上可以考慮unix domain socket。

5.向FD21寫入數(shù)據(jù),fast-cgi協(xié)議格式,我們看到寫入的長度是896,和上邊的php接收的長度是對應(yīng)的。

6.recvfrom函數(shù)從FD21中返回 ECONNRESET (Connection reset by peer)

7.向FD9中寫入錯誤信息,可以推斷FD9就是nginx錯誤日志的文件描述符。

8.關(guān)閉和FD21的連接。

9.向FD3寫入502 Bad Gateway,就是返回給瀏覽器的信息。

10.向FD8寫入一條訪問日志,可以推斷FD8就是nginx訪問日志的文件描述符。

來驗證一下nginx訪問日志和錯誤日志的推斷??梢钥吹降拇_是FD8,F(xiàn)D9,并處于寫入模式。

那么在這個過程中整個網(wǎng)絡(luò)包的傳輸我們不妨也看一下:

通過tcpdump抓包,用神器看比較方便。

因為只想看nginx和php的通訊,在上邊又知道nginx的端口是47039,可以通過tcp.srcport==47039過濾出對應(yīng)的包。

可以看到nginx和php-fpm數(shù)據(jù)交互的過程:47039->9000建立三次握手,接著向9000發(fā)送數(shù)據(jù),9000回復(fù)ACK,3S后9000回復(fù)RST。沒毛病。

注意:

SYN,F(xiàn)IN各占一個序列號

ACK,RST不占序列號(28,29兩個包的reqnum和acknum都是相同的)

序列號是每一字節(jié)加1(29包發(fā)送896字節(jié),同時29包seq為4219146879,30包的ack為4219147775,正好相差896)

RST不需要回復(fù)。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何讓Nginx支持中文文件名具體設(shè)置步驟

    如何讓Nginx支持中文文件名具體設(shè)置步驟

    想讓Nginx支持中文文件名首先得讓你的系統(tǒng)有中語語言包,設(shè)置前可以執(zhí)行:locale 看一下,如果顯示是en_US.UTF-8,即是正常,不用按下面的步驟設(shè)置
    2013-06-06
  • Nginx設(shè)置日志打印post請求參數(shù)的方法

    Nginx設(shè)置日志打印post請求參數(shù)的方法

    這篇文章主要介紹了Nginx設(shè)置日志打印post請求參數(shù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • nginx配置教程之a(chǎn)dd_header的坑詳解

    nginx配置教程之a(chǎn)dd_header的坑詳解

    這篇文章主要給大家介紹了關(guān)于nginx配置教程之a(chǎn)dd_header坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-02-02
  • nginx使用rewrite報錯的解決

    nginx使用rewrite報錯的解決

    本文主要介紹了nginx使用rewrite報錯的解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • Nginx跨域訪問配置方式(Web反向代理跨域訪問配置)

    Nginx跨域訪問配置方式(Web反向代理跨域訪問配置)

    這篇文章主要介紹了Nginx跨域訪問配置方式(Web反向代理跨域訪問配置),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • 詳解Nginx 虛擬主機配置的三種方式(基于IP)

    詳解Nginx 虛擬主機配置的三種方式(基于IP)

    Nginx配置虛擬主機支持3種方式主要有基于IP的虛擬主機配置,基于端口的虛擬主機配置,基于域名的虛擬主機配置。本文主要介紹了基于IP配置的實現(xiàn),感興趣的小伙伴們可以參考一下
    2018-10-10
  • Nginx 虛擬主機配置的三種方式(基于域名)

    Nginx 虛擬主機配置的三種方式(基于域名)

    Nginx配置虛擬主機支持3種方式:基于IP的虛擬主機配置,基于端口的虛擬主機配置,基于域名的虛擬主機配置。本文主要介紹了基于域名的實現(xiàn),感興趣的小伙伴們可以參考一下
    2018-10-10
  • nginx訪問動態(tài)接口報錯404Not Found問題解決

    nginx訪問動態(tài)接口報錯404Not Found問題解決

    本文主要介紹了nginx訪問動態(tài)接口報錯404Not Found問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-03-03
  • nginx做代理時如何修改querystring方法詳解

    nginx做代理時如何修改querystring方法詳解

    這篇文章主要介紹了nginx做代理時如何修改querystring的方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 手把手教你利用Nginx搭建屬于自己的服務(wù)器

    手把手教你利用Nginx搭建屬于自己的服務(wù)器

    最近總是想搭建自己的網(wǎng)站,奈何皮夾里空空如也,服務(wù)器也租不起,更別說域名了,于是我就尋思能否自己搭建個服務(wù)器,還不要錢呢,本文就來手把手教你如何實現(xiàn)吧
    2023-08-08

最新評論