TCP/IP - 使用每个客户端的线程方法解决C10K

Str*_*101 32 concurrency multithreading tcp c10k

在阅读着名的C10k文章并在网上搜索自编写之后事情如何演变之后,我想知道今天的标准服务器是否有可能使用每个连接的线程处理> 10000个并发连接(可能与一个线程池的帮助,以避免创建/终止进程).


一些可能影响问题解决方法的细节:

  1. 输入,中间处理和输出.
  2. 每个连接的长度.
  3. 服务器的技术规格(核心,处理器,RAM等......)
  4. 将此系统与AIO,轮询,绿色线程等替代技术相结合......

显然我不是这方面的专家,所以任何评论或建议都将受到高度赞赏:)

nos*_*sid 59

绝对.标准服务器可以使用每个连接一个线程的模型处理超过10K的并发连接.我已经构建了这样一个应用程序,五年前,它在标准Linux服务器上运行时每个进程的并发连接数超过50K.如今,应该可以在当前硬件上运行具有超过250K并发连接的相同应用程序.

要记住的只有几件事:

  • 使用线程池重用线程.如果不使用线程,则无需终止线程,因为资源使用应针对峰值负载进行优化.
  • 堆栈大小:默认情况下,每个Linux线程为其堆栈保留8 MB.对于10K线程,总计高达80 GB.您应该将默认堆栈大小设置为64k到512k之间的某个值,这不是问题,因为大多数应用程序不需要更深的调用堆栈.
  • 如果连接是短暂的,则通过使用该选项在同一端点上创建多个套接字来优化新连接SO_REUSEPORT.
  • 增加用户限制:( open files默认1.024),max user processes
  • 增加系统限制,例如/proc/sys/kernel/pid_max(默认为32K)/proc/sys/kernel/threads-max,和/proc/sys/vm/max_map_count(默认为65K).

上面提到的应用程序最初设计为仅处理2K并发连接.但是,随着使用的增长,我们不必对代码进行重大更改,以便扩展到50K连接.

  • 这本质上是使用线程调度系统作为数据包调度系统:线程调度器根据到达的数据确定接下来调用哪个`read()`。显然,它有效,但有更多可扩展的设计。 (2认同)

Max*_*kin 21

您可能希望最近关于这个主题的后续行动:1000万个并发连接的秘密 - 内核是问题,而不是解决方案.

  • 多么神奇的文章!我想我可以从中学到很多东西,谢谢:) (2认同)

Pau*_*eau 5

服务器的常用方法是:(a)每个连接的线程(通常使用线程池),或(b)单线程异步 IO(通常使用 epoll 或 kqueue)。我的想法是,这些方法的某些元素可以并且通常应该结合使用异步 IO(使用 epoll 或 kqueue),然后将连接请求移交给线程池进行处理。这种方法将异步 IO 的高效分派与线程池提供的并行性相结合。

我已经写了这样一个服务器(在 C++ 中),它在 Linux 上使用 epoll,在 FreeBSD 和 OSX 上使用 kqueue 以及线程池。我只需要按照它的节奏运行它以进行繁重的测试,做一些代码清理,然后把它扔到 github 上(希望很快)。

  • 也许是我有点困惑,但我认为 `epoll` 并不完全是异步的。经过一些研究,我发现几篇文章说`AIO` 与线程池结合使用效果更好,而`epoll` 与单线程结合使用效果更好:[比较aio 和epoll](http://lkml.indiana.edu/hypermail /linux/kernel/0305.2/0697.html)。 (2认同)