SO_REUSEADDR vs SO_REUSEPORT

BSD

SO_REUSEADDR

效果1:
0.0.0.0:21127.0.0.1:21可以同时绑定

效果2:
对于TCP连接,绑定到某个特定IP+port时,可以忽略其time_wait状态

注意:该选项只对调用bind()的新套接字有效,与正在占用地址的套接字是否使用了该选项无关。

SO_REUSEPORT

效果:允许多个套接字绑定到相同的IP+port

注意:必须前一个套接字也设置了该选项才行。

对于组播,这两个选项的作用是一样的。

Linux

Linux < 3.9

没有SO_REUSEPORT选项。

注意:

  1. 如果有TCP套接字绑定了0.0.0.0:21并处于监听状态,就不能再绑定127.0.0.1:21
  2. reuseaddr与reuseport的作用相似,如果前一个套接字设置了SO_REUSEADDR,后面的套接字也设置这个选项就可以绑定相同的地址和端口

Linux >= 3.9

引入了SO_REUSEPORT

特殊效果:可实现负载均衡

注意:前后两个套接字所属进程必须有相同的有效UID。

Nginx惊群效应

惊群效应

父进程创建套接字,绑定并监听;所有子进程accept,然后epoll。此时新连接到来,所有子进程均被唤醒,造成不必要竞争,称为惊群效应。

解决方法

accept_mutex

所有子进程在accpet之前先取accept_mutex,成功取到锁的才会调用accept。实质上是把惊群推迟到空闲时间,在新连接到来时不发生惊群,提升新连接响应速度。

reuseport

Linux >= 3.9

父进程不创建套接字,每个子进程各自创建自己的,绑定到相同地址并监听。新连接到来时,内核将连接请求交付到某一个套接字上,从而避免了惊群。

EPOLLEXCLUSIVE

Linux >= 4.5 && nginx >= 1.11.3

epoll支持EPOLLEXCLUSIVE选项,如果有多个进程监听同一个套接字,则epoll只唤醒其中一个进程,也从根源上避免了惊群。

参考资料

https://stackoverflow.com/questions/14388706/how-do-so-reuseaddr-and-so-reuseport-differ


展望
1 声望0 粉丝