7

我将创建一个网络系统,可以处理 7000+ tcp 套接字客户端和5KB/s输入(客户端发送)。我研究了这个问题:Link>>。他们说“创建 1024 个线程来处理 1024 个客户端”。我知道有一个名为“select()”的方法而且我认为我无法打开 7000+ 线程来处理 7000+ 客户端,因为我的处理器(或服务器)只有 8CPU,这意味着 7000+ 线程是一个大错误。现在我想我会创建 ~1000 个线程,我会处理这个线程中的每 7 个套接字组。但现在的问题是:如果我有相同的应用程序但我有 2CPU 处理器,我无法通过 1000 个线程获得最大性能,我应该创建(也许)500 个线程。否则,如果我有 8CPU 处理器,我无法获得最大值。1000 个线程的性能,我需要创建(也许)2000 个线程来处理套接字。我如何理解“这个处理器可以处理 X 线程”?这是真的吗?

编辑:我想我可以创建一个正在观看节目的分析器。即,每个线程都记录“我在 X 秒内完成了我的工作”。和分析器处理这些消息并决定创建一个线程或杀死一个线程。但是如何理解线程(或 CPU)的状态呢?

4

2 回答 2

12

单个服务器无法处理 35 Gb/秒的流量(即使有,也会非常昂贵)。

我解决这个问题的方法是:

  • 了解 API
  • 了解协议,选择最适合工作的协议
  • 了解压缩、安全方面(加密、身份验证)、许可
  • 弄清楚如何对服务器进行负载平衡
  • 编写原型服务器和客户端
  • 在服务器上产生一些负载并了解单个实例的限制
  • 将 N 个服务器隐藏在负载均衡器后面并观察它们的行为

您想从第一行代码集中关注的事情:

  • 你将如何水平扩展它
  • 你的绩效指标是什么

编辑

所以它以KB为单位,这要好得多:)。我仍然建议提前考虑 LB。

有不同的技术和协议可以帮助您编写高效的应用程序。从个人经验来看,我更喜欢 HTTP 而不是 TCP。有许多好的负载均衡器可用,添加压缩、加密、身份验证是几天的事情。

我还听说如果您执行任何 IO 操作来处理客户端请求,node.js的速度会非常快。

我编写的服务器是 ASP.NET Web API 应用程序,每个处理速度为几 MB/秒。将服务器隐藏在负载均衡器后面很简单(我使用了HAProxynginx,但肯定还有很多其他可用的。我也使用 C++ 套接字服务器,它的开发时间要长得多。我的观点是,如果你可以使用高级语言,比低级语言更喜欢它。这将缩短您的开发时间(在我的情况下是 10 倍!)并使生活更轻松。

于 2013-09-02T15:41:29.900 回答
0

第一个问题是服务器是做什么的?在每个客户端请求期间是 cpu bound 还是 IO bound?

如果它受 CPU 限制,那么尝试并行处理它们几乎没有意义,因为您没有比服务器上的核心数量更多的并发性。在这种情况下,您最好创建与服务器上的内核一样多的线程,并尽可能快地串行处理输入。

如果服务器进程是 IO 绑定的,那么您需要确定每个处理客户端请求的线程将空闲多长时间,这将使您了解创建多少线程是有意义的。这是经典的方法,但正如其他人所指出的,在这种情况下,更现代的方法是使用异步编程库。对于 Windows 上的 C++,这将是 PPL。

更新

您似乎非常热衷于保持低级别,因此要直接解决原始问题的核心,即如何计算核心可以支持多少线程。

首先,您将为线程调用的任何阻塞调用创建包装函数(记录每个线程被阻塞的时间)。从这些指标中,您可以确定平均线程占用率,并且一旦您知道粗略计算最佳线程数就很容易了。

thread_occupancy = (thread_run_time - thread_blocked_time) / thread_run_time
optimal_thread_count = num_cores / thread_occupancy

您可能希望至少增加 0.1 (10%) 到 thread_occupancy 以覆盖线程切换开销。

但是,正如其他人所说,这种经典的多线程方法只适用于几十个线程。一旦操作系统必须控制大约一百个线程的调度,那么调度开销就会增加,以至于添加更多线程不会带来任何好处。但是,发生这种情况的点高度依赖于系统和软件,因此您只需进行一些测试即可达到最佳状态。

如果您的操作是 IO 绑定的,以至于您希望同时处理数百或数千个请求,那么您别无选择,只能使用异步处理来处理每个线程的多个请求,这通常要求使用异步库。在这种情况下,通常每个内核都有一个线程在异步库的控制下完全占用。这可能由库本身处理,或者您可能需要手动设置它,但无论哪种方式都不需要运行时控制线程数,因此您可以像那里的纯多线程方法一样监控线程占用率你对这些信息没什么用。

于 2013-09-02T15:49:26.157 回答