成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

502問題怎么排查?你學會了嗎?

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
后端服務(wù)端應(yīng)用如果發(fā)生崩潰,nginx在訪問服務(wù)端時會收到服務(wù)端返回的RST報文,然后給客戶端返回502報錯。502并不是服務(wù)端應(yīng)用發(fā)出的,而是nginx發(fā)出的。因此發(fā)生502時,后端服務(wù)端很可能沒有沒有相關(guān)的502日志,需要在nginx側(cè)才能看到這條502日志。

剛工作那會,有一次,上游調(diào)用我服務(wù)的老哥說,你的服務(wù)報"502錯誤了,快去看看是為什么吧"。

當時那個服務(wù)里正好有個調(diào)用日志,平時會記錄各種200,4xx狀態(tài)碼的信息。于是我跑到服務(wù)日志里去搜索了一下502這個數(shù)字,毫無發(fā)現(xiàn)。于是跟老哥說,"服務(wù)日志里并沒有502的記錄,你是不是搞錯啦?"

現(xiàn)在想來,多少有些不好意思。

不知道有多少老哥是跟當時的我是一樣的,這篇文章,就來聊聊502錯誤是什么?

我們從狀態(tài)碼是什么開始聊起。

HTTP狀態(tài)碼

我們平時在瀏覽器里逛的某寶和某度,其實都是一個個前端網(wǎng)頁。

一般來說,前端并不存儲太多數(shù)據(jù),大部分時候都需要從后端服務(wù)器那獲取數(shù)據(jù)。

于是前后端之間需要通過TCP協(xié)議去建立連接,然后在TCP的基礎(chǔ)上傳輸數(shù)據(jù)。

而TCP是基于數(shù)據(jù)流的協(xié)議,傳輸數(shù)據(jù)時,并不會為每個消息加入數(shù)據(jù)邊界,直接使用裸的TCP進行數(shù)據(jù)傳輸會有"粘包"問題。

因此需要用特地的協(xié)議格式去對數(shù)據(jù)進行解析。于是在此基礎(chǔ)上設(shè)計了HTTP協(xié)議。詳細的內(nèi)容可以看我之前寫的《既然有HTTP協(xié)議,為什么還要有RPC》。

比如,我想要看某個商品的具體信息,其實就是前端發(fā)的HTTP請求中傳入商品的id,后端返回的HTTP響應(yīng)中返回商品的價格,商店名,發(fā)貨地址的信息等。

圖片

通過id獲取商品詳情

這樣,表面上,我們是在刷著各種網(wǎng)頁,實際上背后正有多次HTTP消息在不斷進行收發(fā)。

圖片

用戶在網(wǎng)上瀏覽商品

但問題就來了,上面提到的都是正常情況,如果有異常情況呢,比如前端發(fā)的數(shù)據(jù),根本就不是個商品id,而是一張圖片,這對于后端服務(wù)端來說是不可能給出正常響應(yīng)的,于是就需要設(shè)計一套HTTP狀態(tài)碼,用來標識這次HTTP請求響應(yīng)流程是否正常。通過這個可以影響瀏覽器的行為。

比方說一切正常,那服務(wù)端返回個200?狀態(tài)碼,前端收到后,可以放心使用響應(yīng)的數(shù)據(jù)。但如果服務(wù)端發(fā)現(xiàn)客戶端發(fā)的東西異常,就響應(yīng)個4xx?狀態(tài)碼,意思是這是個客戶端的錯誤,4xx里頭的xx可以根據(jù)錯誤的類型,再細分成各種碼,比如401?是客戶端沒權(quán)限,404?是客戶端請求了一個根本不存在的網(wǎng)頁。反過來,如果是服務(wù)器有問題,就返回5xx狀態(tài)碼。

圖片

4xx和5xx的區(qū)別

但問題就來了。

服務(wù)端都有問題了,搞嚴重點,服務(wù)器可能直接就崩潰了,那它還怎么給你返回狀態(tài)碼?

是的,這種情況,服務(wù)端是不可能給客戶端返回狀態(tài)碼的。所以說,一般情況下5xx的狀態(tài)碼其實并不是服務(wù)器返回給客戶端的。

它們是由網(wǎng)關(guān)返回的,常見的網(wǎng)關(guān),比如nginx。

nginx的作用

回到前后端交互數(shù)據(jù)的話題上,如果前端用戶少,那后端處理起請求來,游刃有余。但隨著用戶越來越多,后端服務(wù)器受資源限制,cpu或者內(nèi)存都可能會嚴重不足,這時候解決方案也很簡單,多搞幾臺一樣的服務(wù)器,這樣就能將這些前端請求均攤給幾個服務(wù)器,從而提升處理能力。

但要實現(xiàn)這樣的效果,前端就得知道后端具體有哪些個服務(wù)器,并一一跟他們建立TCP連接。

圖片

前端與多個服務(wù)器之間建立連接

也不是不行,但就是麻煩。

但這時候如果能有個中間層擋在它們中間就好了,這樣客戶端只需要跟中間層連接,中間層再和服務(wù)器建立連接。

于是,這個中間層就成了這幫服務(wù)器的一個代理人一樣,客戶端有啥事都找代理人,只管發(fā)出自己的請求,再由代理人去找某個服務(wù)器去完成響應(yīng)。整個過程下來,客戶端只知道自己的請求被代理人幫忙搞定了,但代理人具體找了那個服務(wù)器去完成,客戶端并不知道,也不需要知道。

像這種,屏蔽掉具體有哪些服務(wù)器的代理方式就是所謂的反向代理。

圖片

反向代理

反過來,屏蔽掉具體有哪些客戶端的代理方式,就是所謂的正向代理。

而這個中間層的角色,一般由nginx這類網(wǎng)關(guān)來充當。

另外,由于背后的服務(wù)器可能性能配置各不相同,有些4核8G,有些2核4G,nginx能為它們加上不同的訪問權(quán)重,權(quán)重高的多轉(zhuǎn)發(fā)點請求,通過這個方式實現(xiàn)不同的負載均衡策略。

nginx返回5xx狀態(tài)碼

有了nginx這一中間層后,客戶端從直連服務(wù)端,變成客戶端直連nginx,再由nginx直連服務(wù)端。從一個TCP連接變成兩個TCP連接。

于是,當服務(wù)器發(fā)生異常時,nginx發(fā)送給服務(wù)器的那條TCP連接就不能正常響應(yīng),nginx在得到這一信息后,就會返回5xx錯誤碼給客戶端,也就是說5xx的報錯,其實是由nginx識別出來,并返回給客戶端的,服務(wù)端本身,并不會有5xx的日志信息。所以才會出現(xiàn)文章開頭的一幕,上游收到了我服務(wù)的502報錯,但我在自己的服務(wù)日志里卻搜索不到這一信息。

產(chǎn)生502的常見原因

在rfc7231中有關(guān)于502錯誤碼的官方解釋是

502 Bad Gateway
The 502 (Bad Gateway) status code indicates that the server, while acting as a gateway or proxy, received an invalid response from an inbound server it accessed while attempting to fulfill the request.

翻譯一下就是,502 (Bad Gateway) 狀態(tài)代碼表示服務(wù)器在充當網(wǎng)關(guān)或代理時,在嘗試滿足請求時從它訪問的入站服務(wù)器接收到無效響應(yīng)。

汝聽,人言否?

這對于大部分編程小白來說,不僅沒解釋到問題,反而只會冒出更多的問號。比如,這上面提到的無效響應(yīng)到底指的是什么?

我來解釋下,它其實是說,502其實是由網(wǎng)關(guān)代理(nginx)發(fā)出的,是因為網(wǎng)關(guān)代理把客戶端的請求轉(zhuǎn)發(fā)給了服務(wù)端,但服務(wù)端卻發(fā)出了無效響應(yīng),而這里的無效響應(yīng),一般是指TCP的RST?報文或四次揮手的FIN報文。

四次揮手估計大家背的很熟了,所以略過,我們來重點說下RST報文是什么。

RST是什么?

我們都知道TCP正常情況下斷開連接是用四次揮手,那是正常時候的優(yōu)雅做法。

但異常情況下,收發(fā)雙方都不一定正常,連揮手這件事本身都可能做不到,所以就需要一個機制去強行關(guān)閉連接。

RST 就是用于這種情況,一般用來異常地關(guān)閉一個連接。它是TCP包頭中的一個標志位,在收到置這個標志位的數(shù)據(jù)包后,連接就會被關(guān)閉,此時接收到 RST的一方,在應(yīng)用層會看到一個 connection reset? 或  connection refused 的報錯。

圖片

TCP報頭RST位

而之所以發(fā)出RST報文,一般有兩個常見原因。

服務(wù)端過早斷開連接

nginx與服務(wù)端之間有一條TCP連接,在nginx將客戶端請求轉(zhuǎn)發(fā)給服務(wù)端時,他兩之間按道理會一直保持這條連接,直到服務(wù)端將結(jié)果正常返回后,再斷開連接。

但如果服務(wù)端過早斷開連接,而nginx?卻還繼續(xù)發(fā)消息過去,nginx就會收到服務(wù)端內(nèi)核返回的RST報文或四次揮手的FIN報文,迫使nginx那邊的連接結(jié)束。

過早斷開連接的原因常見的有兩個。

第一個是,服務(wù)端設(shè)置的超時時間過短。不管是用的哪種編程語言,一般都有現(xiàn)成的HTTP庫?,服務(wù)端一般都會有幾個timeout?參數(shù),比如golang的HTTP服務(wù)框架里有個寫超時(WriteTimeout?),假設(shè)設(shè)置了2s?,那它的含義就是,服務(wù)端在收到請求后需要在2s內(nèi)處理完并將結(jié)果寫到響應(yīng)中,如果等不到,就會將連接給斷掉。

比如你的接口處理時間是5s?,而你的WriteTimeout?卻只有2s?,在沒等到響應(yīng)寫完之前,HTTP框架就會主動將連接給斷開。nginx此時就有可能收到四次揮手的FIN報文?(有些框架也可能發(fā)RST報文),然后斷開連接,于是客戶端就會收到一個502報錯。

遇到這種問題,將WriteTimeout的時間調(diào)大一些就好了。

圖片

FIN與502的關(guān)系

第二個原因,也是造成502狀態(tài)碼最常見的原因,就是服務(wù)端應(yīng)用進程崩了(crash)。

服務(wù)端崩了,也就是當前沒有一個進程在監(jiān)聽服務(wù)器端口,而此時你卻嘗試向一個不存在的端口發(fā)數(shù)據(jù),服務(wù)器的linux內(nèi)核協(xié)議棧就會響應(yīng)一個RST數(shù)據(jù)包。同樣,這時候nginx也會給客戶端一個502。

圖片

RST和502

在開發(fā)過程中,這種情況是最常見的。

現(xiàn)在我們大部分的服務(wù)器都會將掛掉的服務(wù)重啟,因此我們需要判斷下服務(wù)是否曾經(jīng)崩潰過。

如果你有對服務(wù)端的cpu或者內(nèi)存做過監(jiān)控,可以看下CPU或內(nèi)存的監(jiān)控圖是否出現(xiàn)過斷崖式的突然下跌。如果有,十有八九百,就是你的服務(wù)端應(yīng)用程序曾經(jīng)崩潰過。

圖片

cpu突然暴跌

除此之外你還通過下面的命令,看下進程上次的啟動時間是什么時候。

ps -o lstart {pid}

比如我要看的進程id是13515,命令就需要像下面這樣。

# ps -o lstart 13515
STARTED
Wed Aug 31 14:28:53 2022

可以看到它上次的啟動時間是8月31日,這個時間如果跟你印象中的操作時間有差距,那說明進程可能是崩了之后被重新拉起了。

遇到這種問題,最重要的是找出崩潰的原因,崩潰的原因就多種多樣了,比如,對未初始化的內(nèi)存地址進行寫操作,或者內(nèi)存訪問越界(數(shù)組arr長度明明只有2,代碼卻讀arr[3])。

這種情況幾乎都是程序有代碼邏輯問題,崩潰一般也會留下代碼堆棧,可以根據(jù)堆棧報錯去排查問題,修復之后就好了。比如下面這張圖是golang的報錯堆棧信息,其他語言的也類似。

圖片

報錯堆棧

不打印堆棧的情況

但有一些情況,有時候根本不留下堆棧。

比如內(nèi)存泄露導致進程占用內(nèi)存越來越多,最后導致超過服務(wù)器的最大內(nèi)存限制,觸發(fā)OOM(out of memory)?, 進程直接就被操作系統(tǒng)kill掉。

還有更隱蔽的,代碼邏輯里隱藏了主動退出進程的操作。比如golang的日志打印里有個方法叫l(wèi)og.Fatalln()?,打印完日志還會順便執(zhí)行os.Exit()直接退出進程,對源碼不了解的新手很容易犯這個錯。

圖片

打印完順便還退出進程

如果你很明確,你的服務(wù)沒有崩過。那繼續(xù)往下看。

網(wǎng)關(guān)將請求打到了一個不存在的IP上

nginx是通過配置的形式來代理多個服務(wù)器。這個配置一般是放在 /etc/nginx/nginx.conf 中。

打開它,你可能會看到類似下面這樣的信息。

upstream xiaobaidebug.top {
server 10.14.12.19:9235 weight=2;
server 10.14.16.13:8145 weight=5;
server 10.14.12.133:9702 weight=8;
server 10.14.11.15:7035 weight=10;
}

上面配置的含義是,如果客戶端訪問xiaobaidebug.top域名,nginx就會將客戶端的請求轉(zhuǎn)發(fā)到下面的4個服務(wù)器ip上,ip邊上還有個weight權(quán)重,權(quán)重越高,被轉(zhuǎn)發(fā)到的次數(shù)就越多。

可以看出,nginx具有相當豐富的配置能力。但要注意的是,這些個文件是需要自己手動配置的。對于服務(wù)器少,且不怎么變化的情況,這當然沒問題。

但現(xiàn)在已經(jīng)是云原生時代了,很多公司內(nèi)部都有自己的云產(chǎn)品,服務(wù)自然也會上云。一般來說每次更新服務(wù),都可能會將服務(wù)部署到一臺新的機器上。而這個ip也會隨著改變,難道每發(fā)布一次服務(wù),都需要手動去nginx上改配置嗎?這顯然不現(xiàn)實。

如果能在服務(wù)啟動時,讓服務(wù)主動將自己的ip告訴nginx,然后nginx自己生成這樣的一個配置并重新加載,那事情就簡單多了。

為了實現(xiàn)這樣一個服務(wù)注冊的功能,不少公司都會基于nginx進行二次開發(fā)。

但如果這個服務(wù)注冊功能有問題,比方說服務(wù)啟動后,新服務(wù)沒注冊上,但老服務(wù)已經(jīng)被銷毀了。這時候nginx還將請求打到老服務(wù)的IP上,由于老服務(wù)所在的機器已經(jīng)沒有這個服務(wù)了,所以服務(wù)器內(nèi)核就會響應(yīng)RST,nginx收到RST后回復502給客戶端。

圖片

實例已經(jīng)銷毀但配置沒刪IP

要排查這種問題也不難。

這個時候,你可以看下nginx側(cè)是否有打印相關(guān)的日志,看下轉(zhuǎn)發(fā)的IP端口是否符合預(yù)期。

如果不符合預(yù)期,可以去找找做這個基礎(chǔ)組件的同事,進行一波友好的交流。

總結(jié)

HTTP狀態(tài)碼用來表示響應(yīng)結(jié)果的狀態(tài),其中200是正常響應(yīng),4xx是客戶端錯誤,5xx是服務(wù)端錯誤。

客戶端和服務(wù)端之間加入nginx,可以起到反向代理和負載均衡的作用,客戶端只管向nginx請求數(shù)據(jù),并不關(guān)心這個請求具體由哪個服務(wù)器來處理。

后端服務(wù)端應(yīng)用如果發(fā)生崩潰,nginx在訪問服務(wù)端時會收到服務(wù)端返回的RST報文,然后給客戶端返回502報錯。502并不是服務(wù)端應(yīng)用發(fā)出的,而是nginx發(fā)出的。因此發(fā)生502時,后端服務(wù)端很可能沒有沒有相關(guān)的502日志,需要在nginx側(cè)才能看到這條502日志。

如果發(fā)現(xiàn)502,優(yōu)先通過監(jiān)控排查服務(wù)端應(yīng)用是否發(fā)生過崩潰重啟,如果是的話,再看下是否留下過崩潰堆棧日志,如果沒有日志,看下是否可能是oom或者是其他原因?qū)е逻M程主動退出。如果進程也沒崩潰過,去排查下nginx的日志,看下是否將請求打到了某個不知名IP端口上。?

責任編輯:武曉燕 來源: 小白debug
相關(guān)推薦

2024-09-30 09:05:46

Linux網(wǎng)絡(luò)延遲

2023-12-12 08:02:10

2022-07-26 08:03:27

Kubernetes節(jié)點磁盤

2023-01-02 08:20:14

MySQL數(shù)據(jù)庫

2024-10-29 08:08:44

2023-12-05 07:12:39

優(yōu)化排查性能

2024-01-19 08:25:38

死鎖Java通信

2024-02-04 00:00:00

Effect數(shù)據(jù)組件

2023-07-26 13:11:21

ChatGPT平臺工具

2023-01-10 08:43:15

定義DDD架構(gòu)

2023-08-01 12:51:18

WebGPT機器學習模型

2024-01-02 12:05:26

Java并發(fā)編程

2022-10-13 08:02:13

死鎖運算系統(tǒng)

2023-06-27 07:21:51

前端開發(fā)坑點

2022-11-11 08:29:24

C語言中文字符代碼

2023-10-10 11:04:11

Rust難點內(nèi)存

2024-05-06 00:00:00

InnoDBView隔離

2024-07-31 08:39:45

Git命令暫存區(qū)

2023-01-30 09:01:54

圖表指南圖形化

2022-07-08 09:27:48

CSSIFC模型
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲国产aⅴ成人精品无吗 国产精品永久在线观看 | 日韩不卡视频在线观看 | 特级毛片爽www免费版 | 亚洲激精日韩激精欧美精品 | 日韩视频区 | 久久国产高清 | 一区二区三区欧美在线 | 在线一区二区三区 | 中文字幕在线一区 | 国产精品99久久久久久动医院 | 婷婷综合久久 | 国产精品中文字幕在线观看 | 久久精品国产清自在天天线 | 黄色一级电影免费观看 | 国产99久久精品一区二区300 | 国产日韩一区二区三免费高清 | 香蕉视频黄色 | 久久久精品一区二区三区 | 国产一区亚洲二区三区 | 91资源在线观看 | 日本在线观看视频 | 91视视频在线观看入口直接观看 | 99tv| 亚洲欧美综合精品久久成人 | 国产成人精品久久二区二区91 | 欧洲性生活视频 | 日韩三级在线 | 少妇一区在线观看 | 国产av毛片| 在线观看中文字幕视频 | 欧美日韩国产三级 | 极品国产视频 | 久久久精品一区二区三区四季av | 亚洲一区二区在线免费观看 | 一区二区三区中文字幕 | 欧美白人做受xxxx视频 | 毛片1| 成人看片在线观看 | 在线免费av观看 | 蜜桃在线播放 | 亚洲国产精品一区二区久久 |