36

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


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

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

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

4

3 回答 3

68

绝对地。标准服务器可以使用每个连接一个线程的模型处理超过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 连接。

于 2013-07-21T10:11:58.663 回答
24

您可能会喜欢最近关于该主题的后续文章:1000 万并发连接的秘密 - 内核是问题,而不是解决方案

于 2013-07-11T14:08:25.520 回答
5

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

我写了一个有趣的服务器(在 C++ 中),它在 Linux 上使用 epoll,在 FreeBSD 和 OSX 上使用 kqueue 以及线程池。我只需要通过它的速度运行它进行大量测试,做一些代码清理,然后把它扔到 github 上(希望很快)。

于 2013-07-11T14:01:38.727 回答