SO_REUSEADDR和SO_REUSEPORT具體作用是什么詳情可以參考這篇文章:
http://www.reibang.com/p/a23b7e8a4c6a
這里貼一些關(guān)鍵信息:
SO_REUSEADDR
- 作用一
- 在為Socket B設(shè)置了SO_REUSEADDR以后澈缺,判斷沖突的方式就變了。只要地址不是正好(exactly)相同,那么多個(gè)Socket就能綁定到同一ip上。比如0.0.0.0和192.168.0.100,雖然邏輯意義上前者包含了后者颜矿,但是0.0.0.0泛指所有本地ip,而192.168.0.100特指某一ip,兩者并不是完全相同辜限,所以Socket B嘗試綁定的時(shí)候,不會(huì)再報(bào)EADDRINUSE严蓖,而是綁定成功薄嫡。
- 作用二
- 綁定TIME_WAIT狀態(tài)的地址
- 一個(gè)非常現(xiàn)實(shí)的問(wèn)題是颗胡,假如一個(gè)systemd托管的service異常退出了毫深,留下了TIME_WAIT狀態(tài)的socket,那么systemd將會(huì)嘗試重啟這個(gè)service毒姨。但是因?yàn)槎丝诒徽加醚颇瑁瑫?huì)導(dǎo)致啟動(dòng)失敗,報(bào)錯(cuò):“Address already in use”弧呐,造成兩分鐘的服務(wù)空檔期闸迷,systemd也可能在這期間放棄重啟服務(wù)。但是在設(shè)置了SO_REUSEADDR以后俘枫,處于TIME_WAIT狀態(tài)的地址也可以被綁定腥沽,就杜絕了這個(gè)問(wèn)題。因?yàn)門(mén)IME_WAIT其實(shí)本身就是半死狀態(tài)鸠蚪,雖然這樣重用TIME_WAIT可能會(huì)造成不可預(yù)料的副作用今阳,但是在現(xiàn)實(shí)中問(wèn)題很少發(fā)生师溅,所以也忽略了它的副作用。
SO_REUSEPORT
- SO_REUSEPORT干的其實(shí)是大眾期望SO_REUSEADDR能夠干的事盾舌,將多個(gè)socket綁定到同一ip和端口墓臭。并且它要求所有綁定同一ip/port的socket都設(shè)置了SO_REUSEPORT。不過(guò)可能有的操作系統(tǒng)并沒(méi)有這個(gè)option妖谴。
golang中的實(shí)現(xiàn):
主要是通過(guò)golang.org/x/sys/unix包來(lái)設(shè)置socket屬性窿锉,有其他包已經(jīng)做好了兼容各個(gè)操作系統(tǒng)的封裝 https://github.com/gogf/greuseport