异步服务器设计

本文关键字:服务器 异步 | 更新日期: 2023-09-27 18:17:09

我们有一个服务器接收来自500-1500个GPS设备的数据。每台设备每10-30秒发送一个包含1-4个GPS坐标的数据包。服务器是异步设计的,侦听器使用Begin- EndAccept处理连接,使用Begin- EndReceive处理通信。一旦接收到数据包,数据就被处理并存储在数据库中。

对于很少的设备(500-700个设备),这只需要50毫秒,并且我们有少于50个并发线程在运行,并且实际的CPU使用率(20-40%)。但是,当服务器受到连接(1000+)的压力时,线程数量会激增到500-600,CPU使用率也会下降到几个%。处理时间也增加到几分钟。

异步设计是否不适合以这种速率发送许多小数据包的特定场景,或者可能是代码中的问题?

我们目前必须在三个服务器上分配负载以容纳所有设备,并且它们都是托管在Hyper-V服务器上的具有6个cpu和4GB内存的vm。

解决方案:

我从人们的回答中找到的解决方案是,使用。net并行库立即将其作为任务调度,因为这在跨多个内核调度线程时要聪明得多:

void EndReceive(IAsyncResult res)
{
   Task.Factory.StartNew((object o) => { HandleReceive(o as IAsyncResult); }, res, TaskCreationOptions.PreferFairness);
}

现在线程数很少超过50

异步服务器设计

听起来像是在应用程序的某个地方,您正在使用非异步IO,其中您阻塞了操作的结果。您可能在许多地方使用了适当的异步,例如从服务器到客户机的主连接,但在连接到数据库或类似的东西时可能没有使用。这种异步和非异步的混合可能是创建这么多线程的原因。

通过确保你有没有阻塞IO,它应该确保你不会有很多线程池线程无所事事,这似乎是你所处的情况。

您在服务器上做什么操作?

如果它们是 cpu限制的,那么拥有比内核更多的线程是没有用的,增加更多的线程可能会使你的服务器混乱,一堆线程像狗一样战斗;)

在这种情况下,您应该幸运地使用简单的处理循环,每个核心一个。

我从来没有同时处理过这么多的请求,但是你可以尝试创建尽可能多的线程,因为你的cpu上有核心,然后实现一个排队系统。您的线程将每次消耗一个设备的坐标。这样的话,我猜你的CPU将在全速使用…