异步线程 TCP 服务器
我想用 C# 创建一个高性能服务器,它可能需要大约 10k 客户端。现在我开始用 C# 编写一个 TcpServer,并为每个客户端连接打开一个新线程。我还使用一个线程来接受连接。到目前为止一切顺利,工作正常。
服务器必须反序列化 AMF 传入对象,执行一些逻辑(例如保存玩家的位置)并发送回一些对象(序列化对象)。我不担心序列化/反序列化部分 atm。
我主要担心的是,我将拥有大量具有 10k 个客户端的线程,并且我在某处读到过,操作系统只能容纳几百个线程。
是否有任何关于编写像样的异步线程服务器的资源/文章?是否还有其他可能性或者 10k 线程可以正常工作吗?我看过谷歌,但我找不到太多关于设计模式或清楚解释它的方法的信息
I want to create a high performance server in C# which could take about ~10k clients. Now i started writing a TcpServer with C# and for each client-connection i open a new thread. I also use one thread to accept the connections. So far so good, works fine.
The server has to deserialize AMF incoming objects do some logic ( like saving the position of a player ) and send some object back ( serializing objects ). I am not worried about the serializing/deserializing part atm.
My main concern is that I will have a lot of threads with 10k clients and i've read somewhere that an OS can only hold like a few hunderd threads.
Are there any sources/articles available on writing a decent async threaded server ? Are there other possibilties or will 10k threads work fine ? I've looked on google, but i couldn't find much info about design patterns or ways which explain it clearly
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
你会遇到很多问题。
由于多种原因,您无法启动 10,000 个线程。它会破坏内核调度程序。如果您运行的是 32 位,则默认堆栈地址空间 1MB 意味着 10k 线程将保留大约 10GB 的地址空间。这会失败。
您也不能使用简单的选择系统。从本质上讲,select 的套接字数量是 O(N)。对于 10k 套接字,这很糟糕。
您可以使用 IO 完成端口。这就是他们设计的场景。据我所知,没有稳定的、托管的 IO Completion 端口库。您必须使用 P/Invoke 或托管 C++ 编写自己的代码。玩得开心。
You're going to run into a number of problems.
You can't spin up 10,000 threads for a couple of reasons. It'll trash the kernel scheduler. If you're running a 32-bit, then the default stack address space of 1MB means that 10k threads will reserve about 10GB of address space. That'll fail.
You can't use a simple select system either. At it's heart, select is O(N) for the number of sockets. With 10k sockets, that's bad.
You can use IO Completion Ports. This is the scenario they're designed for. To my knowledge there is no stable, managed IO Completion port library. You'll have to write your own using P/Invoke or Managed C++. Have fun.
编写高效多线程服务器的方法是使用 I/O 完成端口(每个请求使用一个线程效率相当低,正如 @Marcelo 提到的)。
如果您使用 .NET 套接字类的异步版本,则可以免费获得它。请参阅此问题有指向文档的指针。
The way to write an efficient multithreaded server is to use I/O completion ports (using a thread per request is quite inefficient, as @Marcelo mentions).
If you use the asynchronous version of the .NET socket class, you get this for free. See this question which has pointers to documentation.
您想要研究使用 IO 完成端口 。您基本上有一个线程池和一个 IO 操作队列。
You want to look into using IO completion ports. You basically have a threadpool and a queue of IO operations.
您肯定不希望每个请求都有一个线程。即使您的客户端较少,创建和销毁线程的开销也会削弱服务器的性能,而且您不可能达到 10,000 个线程;操作系统调度程序在那之前很久就会惨死。
网上有许多关于 C# 异步服务器编程的文章(例如 这里)。只需谷歌一下即可。
You definitely don't want a thread per request. Even if you have fewer clients, the overhead of creating and destroying threads will cripple the server, and there's no way you'll get to 10,000 threads; the OS scheduler will die a horrible death long before then.
There are numerous articles online about asynchronous server programming in C# (e.g., here). Just google around a bit.