8

I can create multiple threads for supporting multi-client feature in socket programming; that's working fine. But if 10,000 clients want to be connected, my server cannot create so many threads.

How can I manage the threads so that I can listen to all these clients simultaneously?

Also, if in this case the server wants to send something to a particular client, then how is it possible?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
  • This is already answered: http://stackoverflow.com/questions/592303/asynchronous-io-in-java – mparaz Mar 31 '09 at 15:58
  • There are some great NIO non-blocking recommendations below but for the sake of summarizing, let me state it clearly: When you expect a few clients, you could go the one-thread per socket way. But when you expect 10K clients, and I would argue (depending on I/O and CPU loads) that if you expect anything over 100 clients you NEED TO GO THE NIO WAY (non-blocking IO). Even if your OS preempts 1000 times per second, could you imagine the task of handling 10K clients? It makes no sense to go with blocking sockets with that many clients! – Jeach Jul 12 '12 at 03:53

9 Answers9

11

You should investigate Java's NIO ("New I/O") library for non-blocking network programming. NIO was designed to solve precisely the server scalability problem you are facing!

Chris Peterson
  • 2,377
  • 1
  • 21
  • 24
8

Highly scalable socket programming in Java requires the selectable channels provided in the "New I/O", or NIO packages. By using non-blocking IO, a single thread can service many sockets, tending only to those sockets that are ready.

One of the more scalable open-source NIO applications is the Grizzly component of the Glassfish application server. Jean-Francois Arcand has written a number of informative, in-depth blog posts about his work on the project, and covers many subtle pitfalls in writing this kind of software with NIO.

If the concept of non-blocking IO is new to you, using existing software like Grizzly, or at least using it as a starting point for your adaptation, might be very helpful.

charego
  • 137
  • 9
erickson
  • 265,237
  • 58
  • 395
  • 493
6

The benefits of NIO are debatable. See Paul Tyma's blog entries here and here.

Julien Chastang
  • 17,592
  • 12
  • 63
  • 89
4

A thread-per-connection threading model (Blocking Socket I/O) will not scale too well. Here's an introduction to Java NIO which will allow you to use non-blocking socket calls in java: http://today.java.net/cs/user/print/a/350

As the article states, there are plenty of frameworks available so you don't have to roll your own.

Peter
  • 5,793
  • 4
  • 27
  • 31
  • Thanks Peter, Its an useful link. Can you help me for such type of links where I can get more details. –  Mar 31 '09 at 05:37
  • There are sample code in the JDK for this model. Note: you cannot exceed the number of users your server will support. You may need more servers. – Peter Lawrey Mar 31 '09 at 19:39
2

As previously mentioned, 10.000 clients is not easy. For java, NIO (possibly augmented with a separate threadpool to handle each request without blocking the NIO thread) is usual way to handle a large amount of clients.

As mentioned, depending on implementation, threads might actually scale, but it depends a lot on how much interaction there is between client connections. Massive threads are more likely to work if there is little synchronization between the threads.

That said, NIO is notoriously difficult to get 100% right the first time you implement it.

I'd recommend either trying out, or at least looking at the source for the Naga NIO lib at naga.googlecode.com. The codebase for the lib is small compared to most other NIO frameworks. You should be able to quickly implement a test to see if you can get 10.000 clients up and running.

(The Naga source also happens to be free to modify or copy without attributing the original author)

Nuoji
  • 3,438
  • 2
  • 21
  • 35
1

This is not a simple question, but for a very in depth (sorry, not in java though) answer see this: http://www.kegel.com/c10k.html


EDIT

Even with nio, this is still a difficult problem. 10000 connections is a tremendous resource burden on the machine, even if you are using non-blocking sockets. This is why large web sites have server farms and load balancers.

grieve
  • 13,220
  • 10
  • 49
  • 61
1

Why don't you process only a certain amount of requests at a time.

Let's say you want to process a maximum of 50 requests at a time (for not creating too many threads)

You create a threadpool of 50 threads.

You put all the requests in a Queue (accept connections, keep sockets open), and each thread, when it is done, gets the next request then process it.

This should scale more easily.

Also, if the need arise, it will be easier to do load balancing, since you could share your queues for multiple servers

Martin
  • 5,954
  • 5
  • 30
  • 46
0

Personally I would rather use create a custom I/O non blocking setup, for example using one thread to accept clients and using one other thread to process them (checking if any input is available and writing data to the output if necessary).

0

You'll have to figure out why your application is failing at 10,000 threads.

  1. Is there a hard limit to the number of threads in the JVM or the OS? If so, can it be lifted?

  2. Are you running out of memory? Try configuring a smaller stack size per thread, and/or add more memory to the server.

  3. Something else? Fix it.

Only once you have determined the source of the problem will you be able to fix it. In theory 10,000 threads should be OK but at that level of concurrency it requires some extra tuning of the JVM and operating system if you want it to work out.

You can also consider NIO but I think it can work fine with threads as well.

Dobes Vandermeer
  • 8,463
  • 5
  • 43
  • 46
  • I have a hard time digesting your comments (10K threads should be fine)? I challenge you to write a small program which does a single task. Benchmark it well and keep that number safe. Then, create 10K threads and start that same task in each thread, while also benchmarking it. No matter which OS you use, you will probably have thread-starvation! – Jeach Jul 12 '12 at 04:01
  • Hi Jeach, the task at hand here is "wait for I/O", there's no processing to be done. The OS doesn't do any context switching to threads that are waiting for I/O. The OS doesn't allocate physical memory to areas of the stack that are not in use. – Dobes Vandermeer Jul 13 '12 at 06:35