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/ ↩