如何将网络套接字连接发送到龙卷风中的不同进程?
How to send web socket connection to different process in tornado?
我正在使用 tornado 来实现带有网络套接字的服务器。我有一些多核 CPU,我也想使用另一个 CPU。所以我虽然使用 python multiprocess
模块。我想接受主进程的连接并使用其他进程发送数据。我的问题是:
- 是否可以在进程之间共享套接字信息?
- 使用
pickling
更好还是我可以使用其他方法?
- 如果我使用
pickling
,它创建的额外的重复文件描述符将影响 OS 可以处理的文件描述符的数量,或者它是否与进程之间共享的文件描述符相同?
解释:
会有很多传入连接,并且会有很多来自客户端的消息,所以我不希望主事件循环卡在发送数据中。这就是为什么我尝试使用不同的进程将数据发送到连接。
strace 的输出
我已经开始 strace
并给出了我将数据发送到 Web 套接字的进程 ID。 strace
的输出如下所示:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
91.01 0.019570 0 441736 sendto
3.60 0.000774 0 29314 read
3.14 0.000675 0 30623 clock_gettime
1.15 0.000248 0 2909 write
0.96 0.000206 0 11855 epoll_wait
0.13 0.000029 0 1534 680 recvfrom
0.00 0.000000 0 17 open
0.00 0.000000 0 34 close
0.00 0.000000 0 17 stat
0.00 0.000000 0 17 fstat
0.00 0.000000 0 34 poll
0.00 0.000000 0 39 mmap
0.00 0.000000 0 26 munmap
0.00 0.000000 0 408 brk
0.00 0.000000 0 134 ioctl
0.00 0.000000 0 34 socket
0.00 0.000000 0 34 17 connect
0.00 0.000000 0 300 setsockopt
0.00 0.000000 0 17 getsockopt
0.00 0.000000 0 200 fcntl
0.00 0.000000 0 17 gettimeofday
0.00 0.000000 0 1185 epoll_ctl
0.00 0.000000 0 178 78 accept4
------ ----------- ----------- --------- --------- ----------------
100.00 0.021502 520662 775 total
我收到错误 recvfrom
和 connect
有什么原因吗?
我会回答第一个问题:
is it possible to share the socket information between processes?
可能取决于 OS,但是 Linux 至少有两种可能:
当主进程接受一个新的TCP连接时,它可以派生一个新的子进程来处理它。 fork 后,新的子进程将具有与主进程相同的套接字文件描述符。
使用 UNIX 域套接字将套接字的文件描述符从主进程传递到其他进程。这需要使用 SCM_RIGHTS 控制消息和辅助数据。检查 this.
不,Tornado 不支持这个。有像 SCM_RIGHTS
这样的技术可以将文件描述符传输到其他进程,但这会在其他进程中为您提供原始套接字,而不是 Tornado websocket 对象(并且没有支持的方法为此套接字构造 websocket 对象).
Tornado 的推荐方法是 运行 每个 CPU 一个进程,并通过将它们放在负载均衡器后面或使用 SO_REUSEPORT 让它们共享流量。在 Tornado 中发送数据是非阻塞的;您必须确保您自己的代码也是非阻塞的(使用异步接口或线程池)。
我正在使用 tornado 来实现带有网络套接字的服务器。我有一些多核 CPU,我也想使用另一个 CPU。所以我虽然使用 python multiprocess
模块。我想接受主进程的连接并使用其他进程发送数据。我的问题是:
- 是否可以在进程之间共享套接字信息?
- 使用
pickling
更好还是我可以使用其他方法? - 如果我使用
pickling
,它创建的额外的重复文件描述符将影响 OS 可以处理的文件描述符的数量,或者它是否与进程之间共享的文件描述符相同?
解释: 会有很多传入连接,并且会有很多来自客户端的消息,所以我不希望主事件循环卡在发送数据中。这就是为什么我尝试使用不同的进程将数据发送到连接。
strace 的输出
我已经开始 strace
并给出了我将数据发送到 Web 套接字的进程 ID。 strace
的输出如下所示:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
91.01 0.019570 0 441736 sendto
3.60 0.000774 0 29314 read
3.14 0.000675 0 30623 clock_gettime
1.15 0.000248 0 2909 write
0.96 0.000206 0 11855 epoll_wait
0.13 0.000029 0 1534 680 recvfrom
0.00 0.000000 0 17 open
0.00 0.000000 0 34 close
0.00 0.000000 0 17 stat
0.00 0.000000 0 17 fstat
0.00 0.000000 0 34 poll
0.00 0.000000 0 39 mmap
0.00 0.000000 0 26 munmap
0.00 0.000000 0 408 brk
0.00 0.000000 0 134 ioctl
0.00 0.000000 0 34 socket
0.00 0.000000 0 34 17 connect
0.00 0.000000 0 300 setsockopt
0.00 0.000000 0 17 getsockopt
0.00 0.000000 0 200 fcntl
0.00 0.000000 0 17 gettimeofday
0.00 0.000000 0 1185 epoll_ctl
0.00 0.000000 0 178 78 accept4
------ ----------- ----------- --------- --------- ----------------
100.00 0.021502 520662 775 total
我收到错误 recvfrom
和 connect
有什么原因吗?
我会回答第一个问题:
is it possible to share the socket information between processes?
可能取决于 OS,但是 Linux 至少有两种可能:
当主进程接受一个新的TCP连接时,它可以派生一个新的子进程来处理它。 fork 后,新的子进程将具有与主进程相同的套接字文件描述符。
使用 UNIX 域套接字将套接字的文件描述符从主进程传递到其他进程。这需要使用 SCM_RIGHTS 控制消息和辅助数据。检查 this.
不,Tornado 不支持这个。有像 SCM_RIGHTS
这样的技术可以将文件描述符传输到其他进程,但这会在其他进程中为您提供原始套接字,而不是 Tornado websocket 对象(并且没有支持的方法为此套接字构造 websocket 对象).
Tornado 的推荐方法是 运行 每个 CPU 一个进程,并通过将它们放在负载均衡器后面或使用 SO_REUSEPORT 让它们共享流量。在 Tornado 中发送数据是非阻塞的;您必须确保您自己的代码也是非阻塞的(使用异步接口或线程池)。