【问题标题】:What's the best way to handle incoming messages?处理传入消息的最佳方式是什么?
【发布时间】:2012-01-26 21:57:10
【问题描述】:

我正在为一个在线游戏编写服务器,它最终应该能够处理 1,000-2,000 个客户端。我发现的 3 种方法基本上是:

  1. 1 个线程/连接(阻塞)
  2. 制作客户端列表并循环访问它们(非阻塞)
  3. Select(基本上是一次针对所有客户端的阻塞语句,可选超时?)

过去我使用过 1,但众所周知,它不能很好地扩展。 2 还可以,但我有复杂的感觉,一个客户在技术上能够让其他人冻结。 3 听起来很有趣(比 2 好一点),但我听说它不适合太多的连接。 那么,最好的方法是什么(在 D 中)?还有其他选择吗?

【问题讨论】:

  • 你能做 2 并将消息传递到工作线程池吗?
  • 我想我可以。但我不知道 D 中有内置线程池,而且我从未实现过类似的东西。
  • 很有趣,谢谢。一种可能性是,遍历所有客户端,但使用 foreach 并行。不会消除风险,但会加快速度。

标签: sockets network-programming d


【解决方案1】:

通常的方法最接近于 3:使用更高性能的 select 替代方案进行异步编程,例如 Linux 上的 poll 或 epoll 系统调用、Windows 上的 IOCP 或包装它们的更高级别的库。 D 不直接支持它们,但您可以找到为它们提供支持的 D 绑定或 3rd 方 D 库(例如 Tango)。

更高性能的服务器(例如 nginx)每个 CPU 核心使用一个线程/进程,并在该线程/进程中使用异步事件处理。

【讨论】:

  • 听起来 select 没问题,但过时了。不幸的是,我还没有找到这样的绑定,而且我不知道 D2 有完整的 Tango 端口。
  • 我认为非官方的或多或少是完整的:github.com/SiegeLord/Tango-D2/tree/d2port/tango/io/selector
  • select 对于大量套接字也比新的慢。
  • 啊,谢谢。虽然这个类似乎也只在 Windows 上使用 select 。但至少 (e)poll on *nix。你认为什么大? 100? 1,000?一万?
  • 从个人经验我不能说太多。由于这个问题不是 D 特有的,所以网上有很多研究信息,例如这里:kegel.com/c10k.html
【解决方案2】:

要考虑的一个选项是让一个线程运行 select/pole/epoll 但不处理结果。相反,它将已知有结果的连接排队,并让线程池从中提供数据。如果检查是否已读入完整请求很便宜,您可以在具有非阻塞 IO 的轮询线程中执行此操作,并且仅将完整请求排队。

除了(可能)线程间通信和排队之外,我不知道 D 是否提供任何支持。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-24
    • 2010-09-09
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 2012-10-06
    • 2021-07-22
    相关资源
    最近更新 更多