如何将网络套接字连接发送到龙卷风中的不同进程?

How to send web socket connection to different process in tornado?

我正在使用 tornado 来实现带有网络套接字的服务器。我有一些多核 CPU,我也想使用另一个 CPU。所以我虽然使用 python multiprocess 模块。我想接受主进程的连接并使用其他进程发送数据。我的问题是:

  1. 是否可以在进程之间共享套接字信息?
  2. 使用 pickling 更好还是我可以使用其他方法?
  3. 如果我使用 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

我收到错误 recvfromconnect 有什么原因吗?

我会回答第一个问题:

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 中发送数据是非阻塞的;您必须确保您自己的代码也是非阻塞的(使用异步接口或线程池)。