Search code examples
javaplayframework-2.0lagom

Running Multiple Lagom Application in a Single Process


We built multiple microservices based on Lagom which are independently deployable, on our cloud setup we deploy like that, but on some onpremise setup it become and issue to run multiple Lagom Services in diff. process.

We were able to run multiple Lagom Based Applications in a Single Process by hacking into the Play class which stops one application if another is started by hacking into the Play scala:

val globalApp = app.globalApplicationEnabled

if (globalApp && _currentApp != null && _currentApp.globalApplicationEnabled) {
  logger.info("Stopping current application")
  stop(_currentApp)
}

I updated this to:

val globalApp = app.globalApplicationEnabled

if (globalApp && _currentApp != null && _currentApp.globalApplicationEnabled) {
  logger.info("Stopping current application")
}

My question: is this right to do, what possible impact in lagom applications or any other way to up multiple services in a Single Process


Solution

  • You shouldn't need that hack, you should be able to just add this to each of your applications application.conf:

    play.allowGlobalApplication = false
    

    This will turn Play's global application support off, which will mean in the above if condition, globalApp will be false and so it won't stop the current application when you start a second application.

    If you have any problems doing this, eg if you get exceptions saying that something is trying to access the global application, then you've likely found a bug in Lagom and/or Play, which you can report to their issue trackers.

    The consequences of running multiple Lagom's in one process are:

    • They can crash each other, by consuming too much memory, creating too many threads, etc.
    • If one is compromised by a hacker, they'll both be compromised.
    • You can't configure them individually using system properties, since they'll both pickup the same system properties. You'll need to be careful when you start them up to ensure that they get their own configuration files. This isn't hard to do, but the APIs are not very well documented.
    • There may be some other configuration files that other libraries try to read that will end up being shared between them - unless you give each application its own classloader, which is entirely feasible to do (Lagom devmode does this).
    • I assume you're using Scala, but if you're using Java, you will need to be careful of which modules get enabled in each application by explicitly disabling the ones you don't need, or give very separate classloaders to each app, since Play's approach to providing modules using Guice is based on what modules are on the classpath. This isn't a problem in Scala because modules get enabled by explicitly mixing them into your application cake.

    There's probably some other things to be aware of, but I can't think of them right now.