Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple JVMs vs concurrent tasks [closed]

I am porting fat Java client code to a server architecture with a lean client.

The server needs to run one instance of the code for each client. The code is multithreaded and runs for long times (weeks) but has only occasional interaction with the client. The number of clients will be in the thousands. Each client needs ~20MB of heap.

I have now two options,

  1. start a separate JVM on the server for each client
  2. modify my code so that all requests and calculation is done in shared space for each client (like in a web-application)

I can see pros and cons for each. For multiple JVMs:

Pros:

  • processes are separate, if one hangs just kill it and restart. All others won't care.
  • resources can be limited, so that one client cannot eat up all CPU / Memory
  • easily distributed on several machines

Cons:

  • the complete JRE class library is loaded multiple times
  • not the Java EE way of doing things
  • will every client need to talk over a separate port?

Are there any best practices which you recommend?

Do you know of any good reference book / article on the subject?

Is there a framework which uses only one JVM but runs several copies of code as if it was separate process space (with limited resources etc)?

like image 287
Philipp Avatar asked Oct 12 '22 09:10

Philipp


2 Answers

It is sadly not possible to limit resources on a Thread basis in a single JVM. However, I would nontheless try to port your app into a single JVM, because of the following reasons:

  • If one thread uses much CPU, you can still kill it (interrupt() is your friend), if you code the tasks correctly.
  • If more than one client works concurrently with other client, I assume they have to share the CPU anyway.
  • Threads run for several weeks? You should split the tasks in subtasks anyway, so you can recover from restarts and continue your work where you left.
  • Only in a single app clients can share a communication server port.
  • Memory consumption must somehow be limited programmatically. For databases that means that queries have to be limited to a fixed number of results, or something similar.
  • If every process needs only 20MB of heap, you need much less resources with a single app. The overhead per JVM is about 30MB I believe, and scheduling 1000 threads might be more performant than scheduling 1000 processes by the operating system.
  • You will have a single monitoring console for your processes for free, if you code your apps to provide information over JMX. Much harder to monitor if you start a single process for each task.

Go with the single app approach, unless you really do not have any control over which tasks can be started by your users.

like image 134
Daniel Avatar answered Oct 25 '22 07:10

Daniel


You could create a web service/proxy service which starts a JVM for each client, shuts them down. This would give you the ability to kill off requests/JVM from long running clients.

The proxy server can give the clients one port they need to talk to as the server forwards requests to the running JVM for that client.

BTW: If you have many clients running CPU intensive jobs, you only have so many cores to go around. You may find the JVMs need to run across multiple machines to support all the clients.

like image 29
Peter Lawrey Avatar answered Oct 25 '22 08:10

Peter Lawrey