Running Lagom Application in Non-Dev mode

(Yanick Salzmann) #1

Hello all

After working a while with the dev mode in Lagom I was trying to figure out how to do a deployment in a non-dev environment without Kubernetes or any other container/service orchestration environment (i.e. “naked” linux VM). The idea is that new service implementations are assigned a random free port on the machine and all services inside the module are registered when each module boots up in the IMDG. Implementing the ServiceLocator interface was no problem, however I of course can only use it outside of dev mode because there is already an implementation bound. This is no problem, so I was researching how to run my services without the lagom-maven-plugin:runAll command but just service by service, however I have already failed to create an executable jar, that boots up a service implementation.

When looking through the source on github and inside the ‘dev’ package, there is a lot of code. Do I have to implement all of that myself? I saw ConductR in the documentation but I read the words “Commercial License” so that immediately makes it a no-go.

What is the starting point if I want to create an executable jar of my service implementations?


(Alan Klikic) #2

@yanick.salzmann if you want to run your service as executible you can check out SBT native packager. I know you are using maven but I do not have expirience with it.
With executable it will be rather hard to maintain cluster static configuration (if you use clustering at all).
ConductR is end of life so ignore it.

(Yanick Salzmann) #3

Hello @aklikic

Thanks for your reply. I also saw the native packager, maybe I will have to try sbt instead of maven. However for now what I have created is a class that boots up the play configuration/application and as such bootstraps Lagom. The cluster configuration (like assigning ports to newly started services) is managed by a centralized data storage.

So far that is looking good, however there are some open points for me:

  • How are the services actually registered? I have created a singleton that injects a ServiceInfo which at least correctly contains my service name that is in that module, however serviceInfo.getAcls is empty, no matter what I try (calls, pathCalls, restCalls). Also I generate a port for those services, but how do I tell Lagom that it should use that port for the service?
  • I think the dev server creates an HTTP server, I am not sure if that is something I should create too or if this is already covered by Play/Lagom.
  • For each instance that starts a unique port is generated for akka.remote.netty.tcp.port, I assume I need to create some information for the akka cluster or so?

And finally the most important question: This cannot really be the way this is intended to be used, right? So I am wondering, what is the right way? How do you deploy a Lagom application in production?


(Alan Klikic) #4

@yanick.salzmann check Running Lagom in production

(Yanick Salzmann) #5

@aklikic Thanks, this is essentially where I’m coming from, however I find it very vague and if you are not using Kubernetes or DC/OS there isn’t really anything described there apart from having to implement your own ServiceLocator interface. Also the entire bootstrap of a service without the dev environment seems undocumented (at least with maven). In the Scala DSL there are things like LagomApplication that you can use together with Play to start the application, but I do not want to use Scala and I cant really find an equivalent in the Java DSL. All in all there just seems to be very little documentation around that subject.

(Yanick Salzmann) #6

I was able to make progress with this. I have created a class implementing the play.core.ApplicationProvider interface. It creates a standard ApplicationLoader.Context, ApplicationLoader and creates an Application which is then run using Play.start. Now for the services to work it also requires a play http server. For that you need the play server dependency (play-server_${scala.binary.version}). Using the play.core.server.ServerProvider I can create a play.core.Server which is subsequently started. Now my services are available. What is not (yet) covered by this is the formation and hardening of the akka remoting cluster, but there I am still looking for options.

(Alan Klikic) #7

Orchenstrating clustered based microservices is not trivial.
I beleive it is an overhead trying implementing it yourself and not using something that is recommended and mostly used by the community.

Good example is Lightbend itself. They offered, proprietary orchestration platform (ConductR). Invested a lot of resources implementing very complex platform but in the end dropped it in favor of alternative solutions like Kubernates and DC/OS.
I would say the main reason was that there were/are alternative solutions providing similar functionalities with bigger community and more
transparent usage (commircal and opensource).

So Ligtbend now focuses on providing tooling for simplifying deployments to this alternative solutions Lightbend orchestration .

Maybe if you have a few microservices, orchestration environment looks like an overhead but microservice system grows by its nature.
We are currently running 70+ microservices on conductr and started migration to Amazon EKS.

Hope this helps.

(Yanick Salzmann) #8

@aklikic I absolutely agree and most of our system will be running using kubernetes, however some parts cannot due to platform and infrastructure constraints that are out of my control, that’s why I had to come up with an alternative. I wish there would be more documentation about that, especially not only about SBT and Scala, because as far as I have seen there is no way to get an executable service with Maven and the Java DSL if you are just going by the documentation. The good thing is that that part of the system is considerably small (2-3 services) and is not intended to grow beyond that. Ideally they also wont need any cluster support.

(Alan Klikic) #9

@yanick.salzmann we have few servces that are running stand alone. There is no clustering involved and services do not connect to each other. Basically not microservices but plain services. In this case we are using sbt native packager to create a build with shell script to start the service.