gpt4 book ai didi

c# - UDP 服务器 - 异步调用是否值得额外的复杂性?

转载 作者:行者123 更新时间:2023-11-30 17:18:28 27 4
gpt4 key购买 nike

我正在编写需要处理大量客户端的 UDP 服务器。

协议(protocol)非常简单 - 一个 UDP 数据包到达并被解码。它可能需要一个小的确认包。结果通常存储在数据库中。

目前我正在使用单线程 UDP 服务器设计。它通过阻塞接收调用等待数据,对数据进行一些相当快速的处理,然后将其放入队列中,以便缓慢的数据库工作可以由后台的另一个进程完成。

我可以使用异步 UDP 调用(BeginReceieve、EndReceive),但我想知道我是否会在性能方面获得任何好处?

很多人说“如果你想要可伸缩性,你需要使用异步调用”。好像是领受了智慧。我以前用过twisted,所以我不怕异步设计。

我明白为什么对于 TCP,甚至是一些更复杂的 UDP 协议(protocol),异步是好的。它有助于避免 TCP 服务器中每个连接一个线程。但我的协议(protocol)并不真正需要等待,除非因为没有数据到达而无事可做。

据我了解,如果不需要阻塞,异步调用将同步完成,或者将从线程池启动一个后台线程,该线程将等待数据并在数据存在或发送完成时调用您的回调,或者您正在执行的任何操作完成时。

我想我可能会“意外地”获得一点 yield ,因为当需要阻塞接收时,所产生的相当快的解码将在工作线程而不是主线程中完成。然而,据我所知,接收只会在没有太多数据要处理时阻塞,即当这样的最小增益最无用时。此外,如果值得的话,不用异步也可以达到同样的效果。

所以,我的主线程正在做 4 件事中的一件 - 阻塞等待数据、接收数据、处理数据或发送数据。我认为异步可能从主线程中删除的唯一其他位是实际接收或发送数据包所花费的时间,但我不知道这些完成的速度有多快 - 例如,如果 UDP 发送由驱动程序排队,或者如果阻塞调用实际上是在等待数据在线。

谁能告诉我在这里使用异步调用是否真的有好处,如果有,你能解释一下原因吗?

谢谢!

最佳答案

因为您使用 UDP,所以您的发送永远不会阻塞,并且您不需要多路复用多个套接字(或者如果需要,也只需少量)。

所以一个线程只做所有事情可能没问题。

就我个人而言,我认为使用一些花哨的异步框架是过早的优化。如果您的服务器范围没有改变(例如,它需要将其他请求发送到其他服务器),这将非常容易。


然而,当您将内容保存到数据库中时,数据库的速度可能会任意慢(如果数据库很忙,即使是单行插入也可能需要很长时间)。您绝对不应该与网络同步进行数据库插入,除非您有一些持久性保证。

丢失一些数据库插入有什么关系吗?您可以将它们在内存中排队(如果服务器出现故障,它们就会丢失)。您可以将它们排在磁盘上并同步文件(但这可能需要一个像样的 IO Controller ),然后同步发送响应。

异步数据库 API 通常不存在(我不知道你是否有),所以如果你的线程在数据库写入时被阻塞,它会阻塞整个任务。但是,如果您要满足耐久性保证,那么您就真的无能为力了。

如果您的规范说“当接收方收到确认时,数据肯定会被持久存储”,那么您必须同步执行数据库操作。

关于c# - UDP 服务器 - 异步调用是否值得额外的复杂性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5733432/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com