Linux内核> = 3.9允许通过设置SO_REUSEPORT
来共享内核负载平衡进程之间的套接字:http://lwn.net/Articles/542629/
如何将其用于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个实例,并通过多次运行以下项进行测试:
echo data | nc localhost 8888
for TCP echo data | nc -U /tmp/socket1
用于Unix域套接字使用TCP时,传入的客户端将与两台服务器保持平衡。使用Unix域套接字,传入的客户端都连接到最后启动的服务器。
答案 0 :(得分:6)
此特定内核补丁在此处记录:
从修补文件列表中可以看出,修补程序仅影响了net/ipv4
和net/ipv6
套接字。 Unix域套接字在net/unix
中实现。所以,答案是:不,SO_REUSEPORT不适用于AF_UNIX类型的套接字。
答案 1 :(得分:2)
一个小补丁,在UNIX套接字was posted上添加了对SO_REUSEPORT
的支持,但已被拒绝。但是,这个补丁并没有在多个套接字上实现负载均衡,如果套接字文件已经存在,它只会导致bind()
不失败。
此用例被视为
从用户的角度来看,这是一个非常奇怪的角落案例
因此,仍有可能通过SO_REUSEPORT
实现UNIX套接字负载平衡的不同补丁被接受。