Java thread per connection model vs NIO

后端 未结 7 1440
悲&欢浪女
悲&欢浪女 2020-12-12 14:58

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

In addition, if you were to use threads per connection, would

相关标签:
7条回答
  • 2020-12-12 15:35

    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.

    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.

    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.

    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.

    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.

    0 讨论(0)
  • 2020-12-12 15:40

    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.

    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'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

    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'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.

    0 讨论(0)
  • 2020-12-12 15:44

    NIO benefits should be taken with a grain of salt.

    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.

    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.

    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.

    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.

    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.

    0 讨论(0)
  • 2020-12-12 15:45

    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.

    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.

    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

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

    Quite nice that Netty supports both!

    0 讨论(0)
  • 2020-12-12 15:50

    There are actually 3 solutions:

    1. Multiple threads
    2. One thread and NIO
    3. Both solutions 1 and 2 at the same time

    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.


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

    • 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.
    • 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.

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

    • 10 000 connections
    • 2 CPUs with 2 cores each
    • only 100 threads will be block at any given time

    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.


    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.

    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.

    0 讨论(0)
  • 2020-12-12 15:55

    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

    0 讨论(0)
提交回复
热议问题