【发布时间】:2014-07-07 16:28:05
【问题描述】:
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用于 TCP -
echo data | nc -U /tmp/socket1用于 Unix 域套接字
使用 TCP 时,传入的客户端将平衡到两个服务器。使用 Unix 域套接字,传入的客户端都连接到最后启动的服务器。
【问题讨论】:
-
你引用的文章的第一句话:
One of the features merged in the 3.9 development cycle was TCP and UDP support for the SO_REUSEPORT socket option。它似乎只支持 TCP 和 UDP。 -
我没有确切的答案,但看起来内核无法对 UNIX 套接字进行负载平衡。这有很多有用的信息:stackoverflow.com/questions/14388706/…
-
@AlexShkop 谢谢! FWIW,我可以在 UDS 上设置选项,这将允许多个进程打开同一个 UDS(监听)。如果未设置该选项,则不允许这样做。但是,它不会进行负载平衡。我正在寻找一个支持观察到的行为或展示如何进行 LB 平衡共享 UDS 的权威答案。
标签: python linux sockets networking tcp