SO_REUSEPORT選項[1]
概述
SO_REUSEPOR
這個socket選項可以讓你將多個socket綁定在同一個監聽端口,然后讓內核給你自動做負載均衡,將請求平均地讓多個線程進行處理。
安全性考慮
- 第一個進程必須enable了這個選項之后,后續的進程才可以通過enable這個選項將socket綁定到同一個端口上。
- 綁定到同一個端口的進程的effective user id必須一致。
上述規定是為了避免hijacking:惡意用戶通過監聽相同的端口來獲取用戶信息。
在沒有SO_REUSEPORT的年代
在SO_REUSEPORT沒有出現之前,多線程編程一般有兩種獲取到來的請求。
- 指派一條線程專門進行accept,獲取socket后分派給worker線程。這種方法使得進行accept的線程成為了單點,容易成為性能的瓶頸。
- 多個線程同時進行accept。這種方法的問題是每一個線程accept成功的概率不均勻,導致負載不均衡。
SO_REUSEPORT的負載均衡算法
使用(remote_ip, remote_port, local_ip, local_port)
來進行哈希,因此可以保證同一個client的包可以路由到同一個進程。但是,當一個listen的進程加進來或者terminate的時候,由于沒有實現一致性哈希
,結果可能導致有些請求由于路由到另外一個進程上,client-server的三次握手過程可能會被重置。
-
本文內容主要來自https://lwn.net/Articles/542629/ ?