I am developing a server application in java (SE) + some open source libraries. This is a game, so I think it will have to be updated sometimes. As long as the app is tracking the state of the clients, using it, and also supports client sessions (in a form of dedicated threads), and singletons, which store references to these player instances, I would like to reload the JVM process (installing a new version of jar file for example), so that some of the classes and instances are not erased by GC, but hooked into the new process started.
Probable Situation:
I have a game version 1.0 running on the server. I need to add some new features in 1.2. But 100 players are fighting each other. I need to install version-1.2, players might feel some lag, but they should be able to continue with their fight even though the version of the jar has changed.
How can that be done?
Take a look at JRebel authors' nice summary on the topic:
http://zeroturnaround.com/blog/reloading_java_classes_401_hotswap_jrebel/#!/
You could look at things like OSGI and class-loading tricks and see if you can achieve what you need, however maybe there is a simpler approach which is a bit safer too.
You could have 2 servers running behind a simple load balancer and when you need to do such maintenance you start routing all new games to Server A only. When all the games on server B finish (and no new games have started because all are going to server A) you stop server B and do whatever maintenance you need to do together with any tests to verify everything is OK before you introduce it back into the 'cluster'.
You then do the same thing and route new games to server B, so that when all games on server A finish you cans switch that off too and do the maintenance.
You will need to develop this simple load balancer which just acts as a connection router but is aware of your game sessions. Maybe you also need to have some information synchronisation between each server instance (if there is any need of communicating lists of players online, chat messages etc., depends what features you have).
First thing to note is that your current game state might be inconsistent with new version. So not all modifications could be installed like this. You can use remote caching system with master/slave configuration. So that all session is stored on remote machine and while one server is stopped, second server can continue working with the same state. First you put down slave, update it and start. Then switch roles and put down second server for update.
Related
I have a JavaFX application, when the user closes the window, I want to destroy all of the JavaFX related resources and only have a tray icon, where the user can then reopen the application.
I have many background threads running, which should stay running when the GUI is closed. I have tried using Platform.exit() however it has no impact on the RAM usage of the program.
What is the best way to accomplish this? My goal is to reduce the impact on the system from my program as much as possible when the application is closed, but still running all of the background threads.
One option is to run the application as a separate process, launching the process when you want to create the application and exiting the process when the application is no longer needed (so completing a full application lifecycle). That way you will be absolutely sure that the application is not consuming any resources when it is not being used, because it won't be running.
How you would accomplish the launching and any communication between your tray service and the application would be up to you. You can research various mechanisms and, if you decide to go this route, ask some new follow up questions on accomplishing certain aspects of the task.
Some example routes you could look at are the ProcessBuilder, which is admittedly a pretty finicky and horrible API or the new Process API updates that will be available with Java 9. If wish to ensure at most a single instance of the application process is ever used, there are solutions for that. If you need to send a signal to the running application process, you could use something like RMI or run a basic HTTP REST server in your application and send messages into that.
As an aside, years ago there used to be some ongoing work on building multi-process JVMs, but there was never any wide uptake of the idea for Java. Though most modern browser clients, such as Chrome and Firefox, are multi-process architectures, the linked articles give some insight into this architecture, some of the potential implications of it and why it used for those applications.
Before going such a route, I would advise you to ensure that such an approach is truly necessary for your application (as pointed out by user npace in comments).
I'm running a J2SE application that is somewhat trusted (Minecraft) but will likely contain completely un-trusted (and likely even some hostile) plugins.
I'd like to create a plugin that can access the GPIO pins on the Raspberry PI.
Every solution I've seen requires that such an app be given sudo-superpowers because gpio is accessed through direct memory access.
It looks like the correct solution is to supply a command-line option like this:
-Djava.security.policy=java.policy
which seems to default you to no permissions (even access to files and high ports), then add the ones your app needs back in with the policy file.
In effect you seem to be giving Java "sudo" powers and then trusting java's security model to only give appropriate powers out to various classes. I'm guessing this makes the app safe to run with sudo--is this correct?
Funny that I've been using Java pretty much daily since 1.0 and never needed this before... You learn something new every day.
[Disclaimer: I'm not very convinced by the Java security model.]
The way I would solve this is to have the code that needs to access the hardware run as a separate privileged process, then have your Java application run as an unprivileged process and connect to the privileged process to have it perform certain actions on its behalf.
In the privileged process, you should check with maximum distrust each request whether it is safe to execute. If you are afraid that other unprivileged processes might connect to the daemon too and make it execute commands it shouldn't, you could make its socket owned by a special group and setgid() the Java application to that group by a tiny wrapper written in C before it is started.
Unix domain sockets are probably the best choice but if you want to chroot() the Java application, a TCP/IP socket might be needed.
I am designing a server application, that is supposed to crunch a lot of data continuously and present results on demand using web interface.
The operating scheme goes roughly like this:
An electronic sensor array constantly spills data into ramdisk through USB
A "flusher" application processes data as fast as it can and loads it into db (staging area)
Using triggers, db performs calculations on data and stores results in another schema (data area)
Client webapp can display processed data in graphs/reports etc. on demand
The solution would ideally look like this:
Database server - PostgreSQL
Have an administration web interface, that can monitor the flusher (i.e. records processed per hour or something like that) and if implemented as separate daemon, control it.
Flusher and Client applications written in Java, ideally using J2EE
Now the problem that keeps bugging me and I can't find the answer: How to go about writing the flusher component, i.e. a process that constantly runs in background in J2EE.
By scouring the web, basically three possibilities emerged:
a) Write the flusher as message driven bean and control it from master application using JMS. However: I don't like the idea of having a MDB running constantly, I'm not even sure that that's possible
b) Write the flusher as EJB and control it using Timer/Scheduling service. However: the events are not really timed, it just needs to run in infinite loop until told not to do so, just seems wrong usage of the technology.
c) Write the flusher as separate java application, run it as OS service (Linux or Windows) and control using startup scripts through ProcessBuilder invoked from EJB. To monitor it's status, use JMS. However: this just seems to me as overly complicated solution, platform dependent and maybe even unreliable and as EJB should not spawn/manage it's own threads, which ProcessBuilder basically does, it just seem wrong.
Basically, none of these look right to me and I cannot figure out, what would we the right solution in the Java/J2EE world.
Thank you
Thomas
I would write the "Flusher" app as a stand alone Java process. Perhaps use something like Java Service Wrapper to turn it into a service for your OS. I'm not very familiar with the options for interfacing with a RAM disk via Java, but you're either going to end up with an InputStream which you can keep open for the life of the process and continually read from, or you're going to continually poll from inside a while loop. It's perfectly ok to do something like the following:
private volotile boolean stopFlag;
...
while(!stopFlag) {
processNextInput();
}
Then you would have some other mechanism in another thread that could set stopFlag to true when you wanted to terminate the process.
As for monitoring the flusher JMX seems like a good solution. That's exactly what it was intended for. You would create an MBean that would expose any kind of status or statistics you wanted and then other processes could connect to that MBean and query for that data.
The "Client" app would then be a simple servlet application which does reporting on your database and provides a pretty front end for the MBean from your flusher. Alternatively you could just monitor the flusher using a JMX console and not even involve the client with that piece of the system.
I don't think EJBs really make sense for this system. I'm somewhat biased against EJBs, so take my advice with a grain of salt, but to me I don't really see a need for them in this application.
I have an application running on a JBoss server. We need update the application time to time.
However, the JBoss is not allowed stop(restart) during update for business reason. How do I handle this tricky situation? Thanks!
2 cases:
If the application is deployed in
multi servers in cluster mode.
If the application is deployed in a
single machine.
If you can't stop the application even for a moment then you probably need to:
To run both versions at the same time.
Direct new users to the new version and allow existing user sessions to continue against the old version
To be able to detect that the old version is no longer in use and hence can be stopped.
Each of the above is, in principle, possible but specifics of the applcations can present serious obstacles.
Many organisations simply take the view that there can be a small hiatus in service, for example at 2:00 AM on a Sunday morning. They warn users "system going down", then stop the old version and start the new. This is much simpler than providing 100% up-time.
One trick with this approach is that it may be possible (I know it can be done in WebSphere, don't know about JBOSS) to deply the new version of the app but not activate it. When an app takes several minutes to deploy and start this can shorten the down time.
It's a common problem, and web apps can't really "updated" at runtime (unless it's a hotdeploy environment). Perhaps you want something like LiveRebel?
LiveRebel
Would you like to update your
application in production with zero
downtime? Avoid the tedious and
error-prone application update
roll-outs? Roll back unsuccessful
updates with a press of a button? Then
sign up to receive an invitation as
soon as it’s available.
We have a application that should always be running. Does anyone know of a way to create an automated way of monitoring to see if this application is running (possibly using a batch file)? If it is not running, then send an email notification and start the application?
Nagios is generally what's used by systems administrators that I've come across. You can script it to do whatever check you need and alert based on a variety of conditions. Works well with cacti so you can graph stuff too :)
If you want to ensure that your service always restarts should it die you could use supervise from daemontools.
Alternative to Nagios is zabbix
You don't mention an OS but if you're looking for something on Windows, Application Monitor might be a good start.
If you're on Linux, monit look pretty useful.
Most monitoring systems have a built-in test which watches the process list to check that everything that should be running is running.
We use Hobbit, it has a configurable table of processes which should be running (and the number of instances, red/yellow alert etc).
We are now heading to release our service that can do some monitoring tasks that usually are hard to handle by Nagios or other similar tools. We provide instant notifications (email, SMS) when:
a) your application/service does not respond for some time
b) some conditions are met (e.g. time of execution of some part of logic > X, number of emails sent < Y or whatever you want)
This is absoltely easy to use when compared to Nagios or others and it does not require installation. We spent a lot of time to make it user-friendly
As I mentioned this will be released very soon (will come back and give you the information). If you are interested in our approach we invite you to beta tests of our application (there will be some promotion for participants).