溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決

發(fā)布時(shí)間:2022-01-12 10:12:10 來(lái)源:億速云 閱讀:640 作者:iii 欄目:云計(jì)算

今天小編給大家分享一下使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來(lái)了解一下吧。

啟用 keep-alive,502 響應(yīng)增加

nginx-ingress-controller 0.20 之前的版本存在一個(gè) bug,配置模版 nginx.tmpl 中沒(méi)有在啟用 keep-alive 時(shí)清除請(qǐng)求中的 “Connection: close”,反而是為所有轉(zhuǎn)發(fā)給 upstream 的 http 請(qǐng)求加上了該請(qǐng)求頭:

使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決

image

應(yīng)該是

使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決

image

因?yàn)樵?bug 的存在, 0.20 之前的版本即使在 config-map 中配置了 keep-alive,nginx 與 pod 之間的 http 通信依舊是短連接,每產(chǎn)生一個(gè)請(qǐng)求就建立一個(gè)連接。連接利用效率低,并且大量連接處于 time-wait 狀態(tài),浪費(fèi)了數(shù)量有限的本地端口。

發(fā)現(xiàn)該問(wèn)題后,我們進(jìn)行了及時(shí)修復(fù),然后問(wèn)題來(lái)了。

nginx 的請(qǐng)求日志顯示,keep-alive 真正生效以后,502 響應(yīng)的數(shù)量有所增多,大部分業(yè)務(wù)系統(tǒng)對(duì)此不敏感,但有個(gè)別系統(tǒng)因 502 響應(yīng)而頻繁告警,這些系統(tǒng)在 keep-alive 沒(méi)有生效之前,沒(méi)有遇到 502 響應(yīng)。

調(diào)查工作開(kāi)始。

502 響應(yīng)占比很少很少,并且出現(xiàn)的時(shí)機(jī)不明,一開(kāi)始毫無(wú)頭緒,通過(guò)翻閱 nginx 的日志和分析抓取的部分報(bào)文發(fā)現(xiàn),出現(xiàn) 502 響應(yīng)時(shí),nginx 向 upstream 轉(zhuǎn)發(fā)請(qǐng)求后,立即收到了 RST 報(bào)文:連接被 pod 斷開(kāi)了。

Nginx 轉(zhuǎn)發(fā)給 Pod 的請(qǐng)求中指定了 keep-alive,連接也持續(xù)了較長(zhǎng)時(shí)間,來(lái)回有過(guò)多次請(qǐng)求了,為什么會(huì)突然被 Pod 斷開(kāi)連接呢?

各種胡思亂想之后,將目標(biāo)鎖定為在 Pod 中運(yùn)行的業(yè)務(wù)系統(tǒng)。在 Pod 中運(yùn)行的業(yè)務(wù)系統(tǒng)是一個(gè) tomcat 服務(wù),tomcat 本身就是一個(gè)請(qǐng)求代理軟件。

事實(shí)上,客戶端發(fā)起的請(qǐng)求經(jīng)過(guò)了兩次代理,第一次由 nginx 代理到 Pod 中的 tomcat,第二次由 tomcat 代理到處理該請(qǐng)求的進(jìn)程。

翻看 tomcat 的配置手冊(cè)時(shí),發(fā)現(xiàn) tomcat 有幾個(gè)和 nginx 類似的配置,它們分別指定了長(zhǎng)連接的閑置超時(shí)時(shí)間(keepAliveTimeout)和長(zhǎng)連接中的請(qǐng)求數(shù)量上限(maxKeepAliveRequest)。

使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決

image

使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決

image

很巧的是,這兩個(gè)配置項(xiàng)的默認(rèn)值和 nginx 中類似配置的默認(rèn)值相同,都是連接閑置 60s 秒后斷開(kāi),以及連接中請(qǐng)求數(shù)量達(dá)到 100 后,斷開(kāi)連接。那么問(wèn)題來(lái)了,nginx 和 tomcat 誰(shuí)會(huì)先斷開(kāi)連接?

從捕獲的報(bào)文來(lái)看,有時(shí)候是 tomcat 先斷開(kāi)的,nginx 后知后覺(jué)依舊轉(zhuǎn)發(fā)請(qǐng)求,結(jié)果收到了 RST 大禮包,繼而回應(yīng) 502。502 錯(cuò)誤碼含義正是:上游返回了非預(yù)期的數(shù)據(jù)。

隨后我們分析了另一個(gè)有同樣問(wèn)題的 python 服務(wù),這個(gè) python 服務(wù)也不是直接監(jiān)聽(tīng)端口處理請(qǐng)求的,而是用 Gunicorn 代理。查了一下 Gunicorn 的默認(rèn)配置,更夸張,它的連接閑置超時(shí)時(shí)間是 2 秒!

分析該 python 服務(wù)的報(bào)文時(shí)還在納悶,為什么它的連接很快就斷開(kāi)?一度讓我們懷疑前面的假設(shè),直到發(fā)現(xiàn)它的默認(rèn)超時(shí)時(shí)間是 2 秒,才釋然:報(bào)文顯示,連接正是在閑置 2 秒之后,被 Pod 端主動(dòng)斷開(kāi)的!

使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決

image

要避免 Pod 先斷開(kāi)連接,方法其實(shí)很簡(jiǎn)單,讓 nginx 中的相關(guān)配置小于 Pod 中的代理軟件的相關(guān)配置即可。譬如tomcat 的 maxKeepAliveRequest 是 100,那么 nginx 中配置成 99,確保連接是被 nginx 主動(dòng)斷開(kāi)的。

這里只大概說(shuō)明一下原委,查看當(dāng)時(shí)的調(diào)查記錄,點(diǎn)擊「閱讀原文」。

另外還有一個(gè) 504 的問(wèn)題,504 其實(shí)是 kube-apiserver 的配置錯(cuò)誤導(dǎo)致的,因?yàn)榕渲缅e(cuò)誤導(dǎo)致 endpoints 沒(méi)有及時(shí)更新,繼而導(dǎo)致 nginx 的配置文件沒(méi)有更新。

Nginx 的 upstream 配置中的 IP 地址早已不存在,或者已經(jīng)分配給其它 Pod,從而導(dǎo)致客戶端收到 504 響應(yīng)或者得到的是另一個(gè)服務(wù)的響應(yīng)。

以上就是“使用nginx的ingress時(shí)遇到的502問(wèn)題怎么解決”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI