日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HAProxy高并发问题解决

發布時間:2023/12/31 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HAProxy高并发问题解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

HAProxy現網問題解決

1問題描述

RMI上線后,現網的接口總是報告異常。

?

2問題分析

通過對RMI源碼的理解,這個是在RMI客戶端那邊沒有可用的連接時,需要創建一個新的連接,但是連接失敗。

?

網絡問題一般抓包可以定位,于是通過抓包發現失敗的連接有個共同的現象,就是在5秒鐘被HAProxy主動關閉,考慮到HAProxy的配置有個connectTimeout參數為5秒,應該是HAProxy連接后端的RMI服務器時失敗。

?

通過抓包也驗證了這一點,因為在5秒鐘內,并沒有搜到從HAProxy發起的對后端的SYN報文(除了check導致的握手)

?

于是大膽懷疑問題出在HAProxy這邊,否則至少HAProxy應該發起主動連接才對。

此時猜測HAProxy沒有拿到可用的服務器。

?

3?HAProxy定位

3.1?connect(...)

剛開始懷疑是HAProxy沒有拿到可用的服務器,那么從哪里入手解決問題呢?

考慮到如果HAProxy如果需要對遠程服務器建立連接的話,肯定需要調用connect(...)這個C語言的API,所以全文搜索connect(....)

?

在函數

中可以看到調用了connect(...)

?

3.2?tcpv4_connect_server的指定

查看tcpv4_connect_server的調用棧

?

?

上面這個代碼是在event_accept函數中,也就是說在session中的client建立時,指定sessionserver端的connect函數,然后后面某個地方觸發了tcpv4_connect_server函數。

?

3.3?tcpv4_connect_server的調用

到這里就很清楚了,通過調用connect_server函數,然后根據之前指定的連接函數來觸發之,由于我們在3.2中指定了tcpv4_connect_server函數,所以觸發它,tcpv4_connect_server函數中又調用了connect函數,所以需要跟蹤connect_server函數。

?

3.4?connect_server的調用

查看調用棧,

通過類似的調用機制,嘗試定位問題。

更詳細的調用棧就不一一列出。

3.4?修改源碼添加自定義日志

?

為了定位問題的準確性,修改HAProxy1.4.23】源碼,在每一個session創建和后續行為都添加了自己的日志,同時每個日志行都添加了session的唯一ID.

這樣就可以跟蹤每個會話的具體行為。

?

日志格式如下:

?

3.5?srv_dynamic_maxconn

通過日志,我們發現,其實并不是HAProxy拿不到可用的服務器,而是拿到了之后,通過這個函數動態計算這個服務器當前的動態maxconn.

?跟蹤下代碼:

?

?

unsigned?int?srv_dynamic_maxconn(const?struct?server?*s,struct?session*?session)

{

?

??

unsigned?int?max;

?

if?(s->proxy->beconn?>=?s->proxy->fullconn)

{

/*?no?fullconn?or?proxy?is?full?*/

max?=?s->maxconn;

}

else?if?(s->minconn?==?s->maxconn)

{ ???

????/*?static?limit?*/

max?=?s->maxconn;

}

else?

{

???????max?=?MAX(s->minconn,

???????s->proxy->beconn?*?s->maxconn?/?s->proxy->fullconn);

?

}

?

if?((s->state?&?SRV_WARMINGUP)?&&

????now.tv_sec?<?s->last_change?+?s->slowstart?&&

????now.tv_sec?>=?s->last_change)?{

unsigned?int?ratio;

ratio?=?100?*?(now.tv_sec?-?s->last_change)?/?s->slowstart;

max?=?MAX(1,?max?*?ratio?/?100);

}

return?max;

}

于是在此段代碼中添加日志,發現在螞蟻窩環境下,每次此函數都返回1.

于是問題就知道出在什么地方了,這里返回1,導致每次對于某個后端服務器來說,

第一個請求建立連接會被響應,而后續的2,3.。。都被拒絕。

?

再查看日志,完全驗證了這一點。

4?解決方案

既然知道了問題所在,那么怎么解決?

必然是通過此函數的邏輯來解決。

?

查看srv_dynamic_maxconn函數,發現如果在配置中可以有2種方法解決

1?minconn設置為較大的一個參數

2直接設置為minconnmaxconn一樣,徹底去掉最小限制,對于并發量按照maxconn來配置。

?

針對第2種情況,代碼中可以看到

也就是如果二者大小一樣的話,max就返回s->maxconn。這樣也沒有問題。

?

5?HAProxy作者的郵件交流

既然是開源軟件,那么就可以直接跟作者交流。

?

下面是跟作者的郵件交流。

5.1?發送郵件描述問題

5.2?對方回復

?

?

?

?

?

5.3?再次發送驗證答案

于是發送自己的答案過去,看對方對我們的解決方案的評價,同時不忘熱情贊美對方的軟件之流行度。

?

?

5.4?對方的最終回應

也就是說,作者認為直接去掉minconn參數更好,于是我們在haproxy.cfg的配置中去掉了這個參數,通過日志打印,minconn的值會等于maxconn參數,也就是走了static?limit這個分支。

至此問題得以解決,HAProxy的理解比之前更進一步。

?

6?后記

1?碰到問題,迎難而上,尤其是在有源碼的情況下,直接debug或者看源碼,肯定可以解決問題。一般在linuxc采用gdb,java采用jdb都可逐行跟蹤,非常方便準確!

?

2?開源軟件,網上有很多別人踩過的坑,可以嘗試搜索是否已經有解決方案。

?

3?相對于所解決的問題,方法論非常重要,這個也需要經驗的積累,比如本文中HAProxy問題的定位其實就在于connect(...)?api的入口定位,整理出調用棧,然后添加日志逐步定位問題。

?

?

?

?

?

?

轉載于:https://my.oschina.net/qiangzigege/blog/470431

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的HAProxy高并发问题解决的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。