簡(jiǎn)單說(shuō)下SO_REUSEPORT的應(yīng)用場(chǎng)景撕瞧, 為什么會(huì)用他于样? 然而在講解SO_REUSEPORT之前屡律,需要先說(shuō)下我們常用的網(wǎng)絡(luò)模型挪圾。
在多核時(shí)代烹看,一般主流的web服務(wù)器都使用 SO_REUSEADDR模式。 以下是比較典型的多進(jìn)程/多線程服務(wù)器模型洛史。
首先需要單線程/單進(jìn)程listen一個(gè)端口上惯殊,然后由多個(gè)工作進(jìn)程/線程去accept()在同一個(gè)服務(wù)器套接字上。
簡(jiǎn)單說(shuō)就是也殖,一個(gè)linten, 多個(gè)accept
性能瓶頸:
第一個(gè)性能瓶頸土思,單線程listener,在處理高速率海量連接時(shí)忆嗜,一樣會(huì)成為瓶頸
第二個(gè)性能瓶頸己儒,多線程訪問(wèn)server socket鎖競(jìng)爭(zhēng)嚴(yán)重。
那么怎么解決捆毫? 這里先別扯什么分布式調(diào)度,集群xxx的 , 就拿單機(jī)來(lái)說(shuō)問(wèn)題闪湾。在Linux kernel 3.9帶來(lái)了SO_REUSEPORT特性,她可以解決上面(單進(jìn)程listen绩卤,多工作進(jìn)程accept() )的問(wèn)題.
多個(gè)listen.每個(gè)對(duì)應(yīng)一個(gè)accept. 由內(nèi)核去負(fù)載均衡將鏈接分不到具體的一個(gè)服務(wù)器socket上途样。
看圖說(shuō)話,對(duì)比SO_REUSADDR的模型濒憋,我想你應(yīng)該看懂SO_REUSEPORT是個(gè)什么東西了何暇。SO_REUSEPORT是支持多個(gè)進(jìn)程或者線程綁定到同一端口,提高服務(wù)器程序的吞吐性能凛驮,具體來(lái)說(shuō)解決了下面的幾個(gè)問(wèn)題:
? ? ? ? ? 允許多個(gè)套接字 bind()/listen() 同一個(gè)TCP/UDP端口
? ? ? ? ? 每一個(gè)線程/進(jìn)程擁有自己的服務(wù)器套接字
? ? ? ? ? 在服務(wù)器套接字上沒(méi)有了鎖的競(jìng)爭(zhēng)裆站,因?yàn)槊總€(gè)進(jìn)程一個(gè)服務(wù)器套接字
? ? ? ? ? 內(nèi)核層面實(shí)現(xiàn)負(fù)載均衡
? ? ? ? ? 安全層面,監(jiān)聽(tīng)同一個(gè)端口的套接字只能位于同一個(gè)用戶下
我這邊用python做了一個(gè)關(guān)于pythonSO_REUSEPORT服務(wù)端測(cè)試.? 測(cè)試之前,已經(jīng)要確定你的linux內(nèi)核版本是3.9, 在mac下進(jìn)行so_reuseport測(cè)試宏胯,貌似不會(huì)提示端口被綁定羽嫡,但是后啟動(dòng)的進(jìn)程會(huì)阻塞.
file:pythonreuseport.py
nohup ? pythonreuseport.py&
nohup ? pythonreuseport.py&
nohup ? pythonreuseport.py&
nohup ? pythonreuseport.py&
nohup ? pythonreuseport.py&
有些文章說(shuō),在python下多進(jìn)程綁定同一個(gè)端口肩袍,也就是有人常說(shuō)的prefork杭棵,他其實(shí)也是單個(gè)進(jìn)程去listen監(jiān)聽(tīng)端口,剩余的worker去accept獲取用戶請(qǐng)求而已.? 如果想用python實(shí)現(xiàn)真正的多進(jìn)程綁定在多一個(gè)端口了牛,那只能是用so_reuseport模式 颜屠。