处理传入消息的最佳方式是什么?
我正在为一个在线游戏编写一个服务器,最终应该能够处理 1,000-2,000 个客户端。我发现做到这一点的 3 种方法基本上是:
- 1 线程/连接(阻塞)
- 创建客户端列表,并循环它们(非阻塞)
- 选择(基本上是一次为所有客户端提供阻塞语句,并带有可选超时?
)过去我使用过 1,但众所周知,它的扩展性不好。 2 还可以,但我有一种复杂的感觉,一个客户在技术上能够让其他人冻结。 3 听起来很有趣(比 2 好一点),但我听说它不适合太多连接。 那么,最好的方法是什么(在 D 中)?还有其他选择吗?
I'm writing a server for an online game, that should be able to handle 1,000-2,000 clients in the end. The 3 ways I found to do this were basically:
- 1 thread/connection (blocking)
- Making a list of clients, and loop through them (non-blocking)
- Select (Basically a blocking statement for all clients at once with optional timeout?)
In the past I've used 1, but as we all know, it doesn't scale well. 2 is okay, but I have mixed feelings, about one client technically being able to make everyone else freeze. 3 sounds interesting (a bit better than 2), but I've heard it's not suitable for too many connections.
So, what would be the best way to do it (in D)? Are there other options?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常的方法最接近 3:使用更高性能的
select
替代方案进行异步编程,例如 Linux 上的poll
或epoll
系统调用, Windows 上的 IOCP 或包装它们的更高级别的库。 D 不直接支持它们,但您可以找到为它们提供支持的 D 绑定或第 3 方 D 库(例如 Tango)。更高性能的服务器(例如 nginx)每个 CPU 核心使用一个线程/进程,并在该线程/进程内使用异步事件处理。
The usual approach is closest to 3: asynchronous programming with a higher-performance
select
alternative, such as thepoll
orepoll
system calls on Linux, IOCP on Windows, or higher-level libraries wrapping them. D does not support them directly, but you can find D bindings or 3rd-party D libraries (e.g. Tango) providing support for them.Higher-performance servers (e.g. nginx) use one thread/process per CPU core, and use asynchronous event handling within that thread/process.
需要考虑的一种选择是使用一个线程来运行 select/pole/epoll 但不处理结果。相反,它将已知有结果的连接排队,并让线程池从中获取数据。如果检查是否已读入完整请求的成本较低,则可以在具有非阻塞 IO 的轮询线程中执行此操作,并且仅对完整请求进行排队。
我不知道除了(可能)线程间通信和排队之外,D 是否提供任何支持。
One option to consider is to have a single thread that runs the select/pole/epoll but not process the results. Rather it queues up connections known to have results and lets a thread pool feed from that. If checking that a full request has been read in is cheap, you might do that in the poll thread with non-blocking IO and only queue up full requests.
I don't know if D provides any support for any of that aside from (possibly) the inter-thread communication and queuing.