首页 文章

可以在Unix域套接字上使用SO_REUSEPORT吗?

提问于
浏览
6

Linux内核> = 3.9允许通过设置 SO_REUSEPORT 来共享具有内核负载 balancer 的进程之间的套接字:http://lwn.net/Articles/542629/

How can this be used for sockets of type AF_UNIX?

看来,它只适用于TCP,而不适用于Unix域套接字 .

这是一个Python测试程序:

import os
import socket

if not hasattr(socket, 'SO_REUSEPORT'):
   socket.SO_REUSEPORT = 15

if True:
   # using TCP sockets
   # works. test with: "echo data | nc localhost 8888"
   s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
   s.bind(('', 8888))
else:
   # using Unix domain sockets
   # does NOT work. test with: "echo data | nc -U /tmp/socket1"
   s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
   s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
   try:
      os.unlink("/tmp/socket1")
   except:
      pass
   s.bind("/tmp/socket1")

s.listen(1)
while True:
   conn, addr = s.accept()
   print('Connected to {}'.format(os.getpid()))
   data = conn.recv(1024)
   conn.send(data)
   conn.close()

启动2个实例,并通过多次运行以下测试:

用于TCP的

  • echo data | nc localhost 8888

  • echo data | nc -U /tmp/socket1 用于Unix域套接字

使用TCP时,传入的客户端将与两台服务器保持 balancer . 使用Unix域套接字,传入的客户端都连接到最后启动的服务器 .

2 回答

  • 6

    这个特定的内核补丁在这里记录:

    http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=c617f398edd4db2b8567a28e899a88f8f574798d

    从修补文件列表中可以看出,该修补程序仅影响 net/ipv4net/ipv6 套接字 . Unix域套接字在 net/unix 中实现 . 所以,答案是:不,SO_REUSEPORT不适用于AF_UNIX类型的套接字 .

  • 2

    一个小补丁,在UNIX套接字was posted上添加了对 SO_REUSEPORT 的支持,但已被拒绝 . 但是这个补丁并没有在多个套接字上实现负载均衡,如果套接字文件已经存在,它只会导致 bind() 不会失败 .

    这个用例被认为是

    从用户的角度来看,这是一个非常奇怪的角落案例

    因此,仍然有可能通过 SO_REUSEPORT 实现UNIX套接字负载 balancer 的不同补丁将被接受 .

相关问题