每个连接模型的Java线程与NIO

时间:2022-06-19 20:58:41

Is the non-blocking Java NIO still slower than your standard thread per connection asynchronous socket?

非阻塞Java NIO是否仍然比每个连接异步套接字的标准线程慢?

In addition, if you were to use threads per connection, would you just create new threads or would you use a very large thread pool?

另外,如果你每个连接使用线程,你会创建新线程还是使用非常大的线程池?

I'm writing an MMORPG server in Java that should be able to scale 10000 clients easily given powerful enough hardware, although the maximum amount of clients is 24000 (which I believe is impossible to reach for the thread per connection model because of a 15000 thread limit in Java). From a three year old article, I've heard that blocking IO with a thread per connection model was still 25% faster than NIO (namely, this document http://www.mailinator.com/tymaPaulMultithreaded.pdf), but can the same still be achieved on this day? Java has changed a lot since then, and I've heard that the results were questionable when comparing real life scenarios because the VM used was not Sun Java. Also, because it is an MMORPG server with many concurrent users interacting with each other, will the use of synchronization and thread safety practices decrease performance to the point where a single threaded NIO selector serving 10000 clients will be faster? (all the work doesn't necessary have to be processed on the thread with the selector, it can be processed on worker threads like how MINA/Netty works).

我正在用Java编写一个MMORPG服务器,应该能够在足够强大的硬件下轻松扩展10000个客户端,尽管最大客户端数量是24000(我相信由于15000线程,每个连接模型的线程无法达到Java中的限制)。从一篇三年前的文章中,我听说用每个连接模式的线程阻止IO仍然比NIO快25%(即,这个文档http://www.mailinator.com/tymaPaulMultithreaded.pdf),但是可以这一天还能实现吗?从那以后Java发生了很大的变化,我听说在比较现实生活场景时结果是有问题的,因为使用的VM不是Sun Java。此外,因为它是一个MMORPG服务器,许多并发用户互相交互,使用同步和线程安全实践会降低性能,以至于为10000个客户端提供服务的单线程NIO选择器会更快吗? (所有工作都不必在带有选择器的线程上处理,它可以在工作线程上处理,就像MINA / Netty的工作方式一样)。

Thanks!

6 个解决方案

#1


20  

NIO benefits should be taken with a grain of salt.

NIO的好处应该是一粒盐。

In a HTTP server, most connections are keep-alive connections, they are idle most of times. It would be a waste of resource to pre-allocate a thread for each.

在HTTP服务器中,大多数连接是保持活动连接,它们大多数时间都处于空闲状态。为每个预先分配线程将浪费资源。

For MMORPG things are very different. I guess connections are constantly busy receiving instructions from users and sending latest system state to users. A thread is needed most of time for a connection.

对于MMORPG来说,事情是非常不同的。我猜连接总是忙于接收用户的指令并向用户发送最新的系统状态。大多数时候都需要一个线程来进行连接。

If you use NIO, you'll have to constantly re-allocate a thread for a connection. It may be a inferior solution, to the simple fixed-thread-per-connection solution.

如果使用NIO,则必须不断为连接重新分配线程。对于简单的每线程固定线程解决方案,它可能是一个较差的解决方案。

The default thread stack size is pretty large, (1/4 MB?) it's the major reason why there can only be limited threads. Try reduce it and see if your system can support more.

默认的线程堆栈大小非常大(1/4 MB?),这是为什么只能有限的线程的主要原因。尝试减少它,看看你的系统是否可以支持更多。

However if your game is indeed very "busy", it's your CPU that you need to worry the most. NIO or not, it's really hard to handle thousands of hyper active gamers on a machine.

但是,如果您的游戏确实非常“忙碌”,那么您最需要担心的是CPU。 NIO与否,在机器上处理成千上万的超级游戏玩家真的很难。

#2


12  

There are actually 3 solutions:

实际上有3种解决方案:

  1. Multiple threads
  2. One thread and NIO
  3. 一个线程和NIO

  4. Both solutions 1 and 2 at the same time
  5. 解决方案1和2同时进行

The best thing to do for performance is to have a small, limited number of threads and multiplex network events onto these threads with NIO as new messages come in over the network.

对性能而言,最好的做法是在NIO通过网络传入新消息时,在这些线程上使用少量有限数量的线程和多路复用网络事件。


Using NIO with one thread is a bad idea for a few reasons:

将NIO与一个线程一起使用是一个坏主意,原因如下:

  • If you have multiple CPUs or cores, you will be idling resources since you can only use one core at a time if you only have one thread.
  • 如果您有多个CPU或核心,那么您将闲置资源,因为如果您只有一个线程,则一次只能使用一个核心。

  • If you have to block for some reason (maybe to do a disk access), you CPU is idle when you could be handling another connection while you're waiting for the disk.
  • 如果由于某种原因(可能要进行磁盘访问)而必须阻塞,那么当您在等待磁盘时可以处理另一个连接时,CPU处于空闲状态。


One thread per connection is a bad idea because it doesn't scale. Let's say have:

每个连接一个线程是一个坏主意,因为它不能扩展。让我们说:

  • 10 000 connections
  • 10 000个连接

  • 2 CPUs with 2 cores each
  • 2个CPU,每个2核

  • only 100 threads will be block at any given time
  • 在任何给定时间只会阻止100个线程

Then you can work out that you only need 104 threads. Any more and you're wasting resources managing extra threads that you don't need. There is a lot of bookkeeping under the hood needed to manage 10 000 threads. This will slow you down.

然后你可以计算出你只需要104个线程。更多,你浪费资源管理你不需要的额外线程。管理10000个线程需要大量的簿记。这会让你慢下来。


This is why you combine the two solutions. Also, make sure your VM is using the fastest system calls. Every OS has its own unique system calls for high performance network IO. Make sure your VM is using the latest and greatest. I believe this is epoll() in Linux.

这就是你结合这两种解决方案的原因。此外,请确保您的VM使用最快的系统调用。每个操作系统都有自己独特的系统调用,用于高性能网络IO。确保您的VM使用最新且最好的。我相信这是Linux中的epoll()。

In addition, if you were to use threads per connection, would you just create new threads or would you use a very large thread pool?

另外,如果你每个连接使用线程,你会创建新线程还是使用非常大的线程池?

It depends how much time you want to spend optimizing. The quickest solution is to create resources like threads and strings when needed. Then let the garbage collection claim them when you're done with them. You can get a performance boost by having a pool of resources. Instead of creating a new object, you ask the pool for one, and return it to the pool when you're done. This adds the complexity of concurrency control. This can be further optimized with advance concurrency algorithms like non-blocking algorithms. New versions of the Java API have a few of these for you. You can spend the rest of your life doing these optimizations on just one program. What is the best solution for your specific application is probably a question that deserves its own post.

这取决于您希望花多少时间进行优化。最快的解决方案是在需要时创建线程和字符串等资源。然后让垃圾收集在你完成它们时声明它们。您可以通过拥有一个资源池来提升性能。您不需要创建新对象,而是要求池中的一个,并在完成后将其返回池中。这增加了并发控制的复杂性。这可以通过非阻塞算法等高级并发算法进一步优化。新版本的Java API为您提供了一些新功能。您可以在余生中仅在一个程序上进行这些优化。什么是您的特定应用程序的最佳解决方案可能是一个值得自己发布的问题。

#3


9  

If you willing to spend any amount of money on powerful enough hardware why limit yourself to one server. google don't use one server, they don't even use one datacenter of servers.

如果您愿意在功能强大的硬件上花费任何金钱,那么为什么要将自己限制在一台服务器上。谷歌不使用一台服务器,他们甚至不使用一个服务器数据中心。

A common misconception is that NIO allows non-blocking IO therefor its the only model worth benchmarking. If you benchmark blocking NIO you can get it 30% faster than old IO. i.e. if you use the same threading model and compare just the IO models.

一个常见的误解是NIO允许非阻塞IO,因此它是唯一值得基准测试的模型。如果您对阻止NIO进行基准测试,则可以比旧IO快30%。即如果您使用相同的线程模型并仅比较IO模型。

For a sophisticated game, you are far more likely to run out of CPU before you hit 10K connections. Again it is simpler to have a solution which scales horizontally. Then you don't need to worry about how many connections you can get.

对于复杂的游戏,在达到10K连接之前,你更有可能耗尽CPU。同样,有一个水平扩展的解决方案更简单。然后,您无需担心可以获得多少连接。

How many users can reasonably interact? 24? in which case you have 1000 independent groups interacting. You won't have this many cores in one server.

有多少用户可以合理地互动? 24?在这种情况下,您有1000个独立的组进行交互。您将不会在一台服务器中拥有这么多核心。

How much money per users are you intending to spend on server(s)? You can buy an 12 core server with 64 GB of memory for less than £5000. If you place 2500 users on this server you have spent £2 per user.

您打算在服务器上花费多少钱?您可以购买带有64 GB内存的12核服务器,价格低于5000英镑。如果您在此服务器上放置2500个用户,则每个用户花费2英镑。

EDIT: I have a reference http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html which is mine. ;) I had this reviewed by someone who is a GURU of Java Networking and it broadly agreed with what he had found.

编辑:我有一个参考http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html这是我的。 ;)我是由Java Networking GURU的人审核过的,并且广泛同意他所发现的内容。

#4


3  

If you have busy connections, which means they constantly send you data and you send them back, you may use non-Blocking IO in conjunction with Akka.

如果您有繁忙的连接,这意味着他们不断向您发送数据并将其发回,您可以将非阻止IO与Akka结合使用。

Akka is an open-source toolkit and runtime simplifying the construction of concurrent and distributed applications on the JVM. Akka supports multiple programming models for concurrency, but it emphasizes actor-based concurrency, with inspiration drawn from Erlang. Language bindings exist for both Java and Scala.

Akka是一个开源工具包和运行时,简化了JVM上并发和分布式应用程序的构建。 Akka支持多种编程模型以实现并发,但它强调基于actor的并发性,其灵感来自Erlang。 Java和Scala都存在语言绑定。

Akka's logic is non-blocking so its perfect for asynchronous programming. Using Akka Actors you may remove Thread overhead.

But if your socket streams block more often, I suggest using Blocking IO in conjunction with Quasar

Akka的逻辑是非阻塞的,因此非常适合异步编程。使用Akka Actors,您可以删除线程开销。但是如果您的套接字流更频繁地阻塞,我建议将Blocking IO与Quasar结合使用

Quasar is an open-source library for simple, lightweight JVM concurrency, which implements true lightweight threads (AKA fibers) on the JVM. Quasar fibers behave just like plain Java threads, except they have virtually no memory and task-switching overhead, so that you can easily spawn hundreds of thousands of fibers – or even millions – in a single JVM. Quasar also provides channels for inter-fiber communications modeled after those offered by the Go language, complete with channel selectors. It also contains a full implementation of the actor model, closely modeled after Erlang.

Quasar是一个开源库,用于简单,轻量级的JVM并发,它在JVM上实现真正的轻量级线程(AKA光纤)。 Quasar光纤的行为与纯Java线程一样,除了它们几乎没有内存和任务切换开销,因此您可以在一个JVM中轻松生成数十万个光纤 - 甚至数百万个光纤。 Quasar还提供光纤通信的通道,模仿Go语言提供的通道,并配有通道选择器。它还包含演员模型的完整实现,紧密模仿Erlang。

Quasar's logic is blocking, so you may spawn, say 24000 fibers waiting on different connections. One of positive points about Quasar is, fibers can interact with plain Threads very easily. Also Quasar has integrations with popular libraries, such as Apache HTTP client or JDBC or Jersey and so on, so you may use benefits of using Fibers in many aspects of your project.
You may see a good comparison between these two frameworks here.

Quasar的逻辑是阻塞,所以你可能会产生,比如在不同的连接上等待24000个光纤。关于Quasar的一个积极观点是,纤维可以非常容易地与普通螺纹相互作用。此外,Quasar还与流行的库集成,例如Apache HTTP客户端或JDBC或Jersey等,因此您可以在项目的许多方面使用Fibers。您可以在这里看到这两个框架之间的良好比较。

#5


1  

As most of you guys are saying that the server is bound to be locked up in CPU usage before 10k concurrent users are reached, I suppose it is better for me to use a threaded blocking (N)IO approach considering the fact that for this particular MMORPG, getting several packets per second for each player is not uncommon and might bog down a selector if one were to be used.

正如大多数人所说,在达到10k并发用户之前,服务器必然会被锁定在CPU使用率中,我想我最好使用线程阻塞(N)IO方法,考虑到这个特定的事实。 MMORPG,每个玩家每秒获得几个数据包并不罕见,如果要使用选择器,可能会使选择器陷入困境。

Peter raised an interesting point that blocking NIO is faster than the old libraries while irreputable mentioned that for a busy MMORPG server, it would be better to use threads because of how many instructions are received per player. I wouldn't count on too many players going idle on this game, so it shouldn't be a problem for me to have a bunch of non-running threads. I've come to realize that synchronization is still required even when using a framework based on NIO because they use several worker threads running at the same time to process packets received from clients. Context switching may prove to be expensive, but I'll give this solution a try. It's relatively easy to refactor my code so that I could use a NIO framework if I find there is a bottleneck.

Peter提出了一个有趣的观点,即阻止NIO比旧库更快,而无可争辩地提到,对于繁忙的MMORPG服务器,由于每个播放器接收了多少指令,因此最好使用线程。我不会指望太多的玩家在这个游戏上闲置,所以对我来说,拥有一堆非运行线程应该不是问题。我已经意识到,即使使用基于NIO的框架,仍然需要同步,因为它们使用多个工作线程同时运行来处理从客户端接收的数据包。上下文切换可能证明是昂贵的,但我会尝试这个解决方案。重构我的代码相对容易,这样如果发现存在瓶颈,我就可以使用NIO框架。

I believe my question has been answered. I'll just wait a little bit more in order to receive even more insight from more people. Thank you for all your answers!

我相信我的问题已得到解答。我会等一下,以便从更多人那里获得更多的洞察力。谢谢你的所有答案!

EDIT: I've finally chosen my course of action. I actually was indecisive and decided to use JBoss Netty and allow the user to switch between either oio or nio using the classes

编辑:我终于选择了我的行动方案。我实际上是优柔寡断,决定使用JBoss Netty并允许用户使用类在oio或nio之间切换

org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;

Quite nice that Netty supports both!

非常好,Netty支持两者!

#6


1  

You might get some inspiration from the former Sun sponsored project, now named Red Dwarf. The old website at http://www.reddwarfserver.org/ is down.
Github to the rescue: https://github.com/reddwarf-nextgen/reddwarf

您可能会从前Sun赞助的项目中获得一些灵感,现在名为Red Dwarf。旧网站http://www.reddwarfserver.org/已关闭。 Github救援:https://github.com/reddwarf-nextgen/reddwarf

#1


20  

NIO benefits should be taken with a grain of salt.

NIO的好处应该是一粒盐。

In a HTTP server, most connections are keep-alive connections, they are idle most of times. It would be a waste of resource to pre-allocate a thread for each.

在HTTP服务器中,大多数连接是保持活动连接,它们大多数时间都处于空闲状态。为每个预先分配线程将浪费资源。

For MMORPG things are very different. I guess connections are constantly busy receiving instructions from users and sending latest system state to users. A thread is needed most of time for a connection.

对于MMORPG来说,事情是非常不同的。我猜连接总是忙于接收用户的指令并向用户发送最新的系统状态。大多数时候都需要一个线程来进行连接。

If you use NIO, you'll have to constantly re-allocate a thread for a connection. It may be a inferior solution, to the simple fixed-thread-per-connection solution.

如果使用NIO,则必须不断为连接重新分配线程。对于简单的每线程固定线程解决方案,它可能是一个较差的解决方案。

The default thread stack size is pretty large, (1/4 MB?) it's the major reason why there can only be limited threads. Try reduce it and see if your system can support more.

默认的线程堆栈大小非常大(1/4 MB?),这是为什么只能有限的线程的主要原因。尝试减少它,看看你的系统是否可以支持更多。

However if your game is indeed very "busy", it's your CPU that you need to worry the most. NIO or not, it's really hard to handle thousands of hyper active gamers on a machine.

但是,如果您的游戏确实非常“忙碌”,那么您最需要担心的是CPU。 NIO与否,在机器上处理成千上万的超级游戏玩家真的很难。

#2


12  

There are actually 3 solutions:

实际上有3种解决方案:

  1. Multiple threads
  2. One thread and NIO
  3. 一个线程和NIO

  4. Both solutions 1 and 2 at the same time
  5. 解决方案1和2同时进行

The best thing to do for performance is to have a small, limited number of threads and multiplex network events onto these threads with NIO as new messages come in over the network.

对性能而言,最好的做法是在NIO通过网络传入新消息时,在这些线程上使用少量有限数量的线程和多路复用网络事件。


Using NIO with one thread is a bad idea for a few reasons:

将NIO与一个线程一起使用是一个坏主意,原因如下:

  • If you have multiple CPUs or cores, you will be idling resources since you can only use one core at a time if you only have one thread.
  • 如果您有多个CPU或核心,那么您将闲置资源,因为如果您只有一个线程,则一次只能使用一个核心。

  • If you have to block for some reason (maybe to do a disk access), you CPU is idle when you could be handling another connection while you're waiting for the disk.
  • 如果由于某种原因(可能要进行磁盘访问)而必须阻塞,那么当您在等待磁盘时可以处理另一个连接时,CPU处于空闲状态。


One thread per connection is a bad idea because it doesn't scale. Let's say have:

每个连接一个线程是一个坏主意,因为它不能扩展。让我们说:

  • 10 000 connections
  • 10 000个连接

  • 2 CPUs with 2 cores each
  • 2个CPU,每个2核

  • only 100 threads will be block at any given time
  • 在任何给定时间只会阻止100个线程

Then you can work out that you only need 104 threads. Any more and you're wasting resources managing extra threads that you don't need. There is a lot of bookkeeping under the hood needed to manage 10 000 threads. This will slow you down.

然后你可以计算出你只需要104个线程。更多,你浪费资源管理你不需要的额外线程。管理10000个线程需要大量的簿记。这会让你慢下来。


This is why you combine the two solutions. Also, make sure your VM is using the fastest system calls. Every OS has its own unique system calls for high performance network IO. Make sure your VM is using the latest and greatest. I believe this is epoll() in Linux.

这就是你结合这两种解决方案的原因。此外,请确保您的VM使用最快的系统调用。每个操作系统都有自己独特的系统调用,用于高性能网络IO。确保您的VM使用最新且最好的。我相信这是Linux中的epoll()。

In addition, if you were to use threads per connection, would you just create new threads or would you use a very large thread pool?

另外,如果你每个连接使用线程,你会创建新线程还是使用非常大的线程池?

It depends how much time you want to spend optimizing. The quickest solution is to create resources like threads and strings when needed. Then let the garbage collection claim them when you're done with them. You can get a performance boost by having a pool of resources. Instead of creating a new object, you ask the pool for one, and return it to the pool when you're done. This adds the complexity of concurrency control. This can be further optimized with advance concurrency algorithms like non-blocking algorithms. New versions of the Java API have a few of these for you. You can spend the rest of your life doing these optimizations on just one program. What is the best solution for your specific application is probably a question that deserves its own post.

这取决于您希望花多少时间进行优化。最快的解决方案是在需要时创建线程和字符串等资源。然后让垃圾收集在你完成它们时声明它们。您可以通过拥有一个资源池来提升性能。您不需要创建新对象,而是要求池中的一个,并在完成后将其返回池中。这增加了并发控制的复杂性。这可以通过非阻塞算法等高级并发算法进一步优化。新版本的Java API为您提供了一些新功能。您可以在余生中仅在一个程序上进行这些优化。什么是您的特定应用程序的最佳解决方案可能是一个值得自己发布的问题。

#3


9  

If you willing to spend any amount of money on powerful enough hardware why limit yourself to one server. google don't use one server, they don't even use one datacenter of servers.

如果您愿意在功能强大的硬件上花费任何金钱,那么为什么要将自己限制在一台服务器上。谷歌不使用一台服务器,他们甚至不使用一个服务器数据中心。

A common misconception is that NIO allows non-blocking IO therefor its the only model worth benchmarking. If you benchmark blocking NIO you can get it 30% faster than old IO. i.e. if you use the same threading model and compare just the IO models.

一个常见的误解是NIO允许非阻塞IO,因此它是唯一值得基准测试的模型。如果您对阻止NIO进行基准测试,则可以比旧IO快30%。即如果您使用相同的线程模型并仅比较IO模型。

For a sophisticated game, you are far more likely to run out of CPU before you hit 10K connections. Again it is simpler to have a solution which scales horizontally. Then you don't need to worry about how many connections you can get.

对于复杂的游戏,在达到10K连接之前,你更有可能耗尽CPU。同样,有一个水平扩展的解决方案更简单。然后,您无需担心可以获得多少连接。

How many users can reasonably interact? 24? in which case you have 1000 independent groups interacting. You won't have this many cores in one server.

有多少用户可以合理地互动? 24?在这种情况下,您有1000个独立的组进行交互。您将不会在一台服务器中拥有这么多核心。

How much money per users are you intending to spend on server(s)? You can buy an 12 core server with 64 GB of memory for less than £5000. If you place 2500 users on this server you have spent £2 per user.

您打算在服务器上花费多少钱?您可以购买带有64 GB内存的12核服务器,价格低于5000英镑。如果您在此服务器上放置2500个用户,则每个用户花费2英镑。

EDIT: I have a reference http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html which is mine. ;) I had this reviewed by someone who is a GURU of Java Networking and it broadly agreed with what he had found.

编辑:我有一个参考http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html这是我的。 ;)我是由Java Networking GURU的人审核过的,并且广泛同意他所发现的内容。

#4


3  

If you have busy connections, which means they constantly send you data and you send them back, you may use non-Blocking IO in conjunction with Akka.

如果您有繁忙的连接,这意味着他们不断向您发送数据并将其发回,您可以将非阻止IO与Akka结合使用。

Akka is an open-source toolkit and runtime simplifying the construction of concurrent and distributed applications on the JVM. Akka supports multiple programming models for concurrency, but it emphasizes actor-based concurrency, with inspiration drawn from Erlang. Language bindings exist for both Java and Scala.

Akka是一个开源工具包和运行时,简化了JVM上并发和分布式应用程序的构建。 Akka支持多种编程模型以实现并发,但它强调基于actor的并发性,其灵感来自Erlang。 Java和Scala都存在语言绑定。

Akka's logic is non-blocking so its perfect for asynchronous programming. Using Akka Actors you may remove Thread overhead.

But if your socket streams block more often, I suggest using Blocking IO in conjunction with Quasar

Akka的逻辑是非阻塞的,因此非常适合异步编程。使用Akka Actors,您可以删除线程开销。但是如果您的套接字流更频繁地阻塞,我建议将Blocking IO与Quasar结合使用

Quasar is an open-source library for simple, lightweight JVM concurrency, which implements true lightweight threads (AKA fibers) on the JVM. Quasar fibers behave just like plain Java threads, except they have virtually no memory and task-switching overhead, so that you can easily spawn hundreds of thousands of fibers – or even millions – in a single JVM. Quasar also provides channels for inter-fiber communications modeled after those offered by the Go language, complete with channel selectors. It also contains a full implementation of the actor model, closely modeled after Erlang.

Quasar是一个开源库,用于简单,轻量级的JVM并发,它在JVM上实现真正的轻量级线程(AKA光纤)。 Quasar光纤的行为与纯Java线程一样,除了它们几乎没有内存和任务切换开销,因此您可以在一个JVM中轻松生成数十万个光纤 - 甚至数百万个光纤。 Quasar还提供光纤通信的通道,模仿Go语言提供的通道,并配有通道选择器。它还包含演员模型的完整实现,紧密模仿Erlang。

Quasar's logic is blocking, so you may spawn, say 24000 fibers waiting on different connections. One of positive points about Quasar is, fibers can interact with plain Threads very easily. Also Quasar has integrations with popular libraries, such as Apache HTTP client or JDBC or Jersey and so on, so you may use benefits of using Fibers in many aspects of your project.
You may see a good comparison between these two frameworks here.

Quasar的逻辑是阻塞,所以你可能会产生,比如在不同的连接上等待24000个光纤。关于Quasar的一个积极观点是,纤维可以非常容易地与普通螺纹相互作用。此外,Quasar还与流行的库集成,例如Apache HTTP客户端或JDBC或Jersey等,因此您可以在项目的许多方面使用Fibers。您可以在这里看到这两个框架之间的良好比较。

#5


1  

As most of you guys are saying that the server is bound to be locked up in CPU usage before 10k concurrent users are reached, I suppose it is better for me to use a threaded blocking (N)IO approach considering the fact that for this particular MMORPG, getting several packets per second for each player is not uncommon and might bog down a selector if one were to be used.

正如大多数人所说,在达到10k并发用户之前,服务器必然会被锁定在CPU使用率中,我想我最好使用线程阻塞(N)IO方法,考虑到这个特定的事实。 MMORPG,每个玩家每秒获得几个数据包并不罕见,如果要使用选择器,可能会使选择器陷入困境。

Peter raised an interesting point that blocking NIO is faster than the old libraries while irreputable mentioned that for a busy MMORPG server, it would be better to use threads because of how many instructions are received per player. I wouldn't count on too many players going idle on this game, so it shouldn't be a problem for me to have a bunch of non-running threads. I've come to realize that synchronization is still required even when using a framework based on NIO because they use several worker threads running at the same time to process packets received from clients. Context switching may prove to be expensive, but I'll give this solution a try. It's relatively easy to refactor my code so that I could use a NIO framework if I find there is a bottleneck.

Peter提出了一个有趣的观点,即阻止NIO比旧库更快,而无可争辩地提到,对于繁忙的MMORPG服务器,由于每个播放器接收了多少指令,因此最好使用线程。我不会指望太多的玩家在这个游戏上闲置,所以对我来说,拥有一堆非运行线程应该不是问题。我已经意识到,即使使用基于NIO的框架,仍然需要同步,因为它们使用多个工作线程同时运行来处理从客户端接收的数据包。上下文切换可能证明是昂贵的,但我会尝试这个解决方案。重构我的代码相对容易,这样如果发现存在瓶颈,我就可以使用NIO框架。

I believe my question has been answered. I'll just wait a little bit more in order to receive even more insight from more people. Thank you for all your answers!

我相信我的问题已得到解答。我会等一下,以便从更多人那里获得更多的洞察力。谢谢你的所有答案!

EDIT: I've finally chosen my course of action. I actually was indecisive and decided to use JBoss Netty and allow the user to switch between either oio or nio using the classes

编辑:我终于选择了我的行动方案。我实际上是优柔寡断,决定使用JBoss Netty并允许用户使用类在oio或nio之间切换

org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory;

Quite nice that Netty supports both!

非常好,Netty支持两者!

#6


1  

You might get some inspiration from the former Sun sponsored project, now named Red Dwarf. The old website at http://www.reddwarfserver.org/ is down.
Github to the rescue: https://github.com/reddwarf-nextgen/reddwarf

您可能会从前Sun赞助的项目中获得一些灵感,现在名为Red Dwarf。旧网站http://www.reddwarfserver.org/已关闭。 Github救援:https://github.com/reddwarf-nextgen/reddwarf