Why I would not choose Java to run in Kubernetes

Together with the rise of Java, Java Applications Servers (e.g Tomcat, IBM WAS) also came into the game. The idea of an application server was to have one JVM and to run multiple deployments (e.g. jar, ear, war), this way the memory footprint necessary for running lots of processes can be reduced.

Historically, the teams were well-defined in application administrators that could also be responsible with the operations aspects and developers with a focus on developing the business features of their product and not so much on how their code runs in terms of performance, reliability and so on. App admins instead, took a heavy interest in how the code is running on their administered applications so they would have a stable system. As one of them, even with optimized code, I still had a job that killed that Java process on a 24h basis, just to be sure, considering that we had processes that just froze after 1 week.

Then containers were launched and the idea that everything can be packed in images and those images can run anywhere. Kubernetes would be used for orchestration, monolith applications would be migrated to the cloud, by re-writing them in microservices.

The app admins will remain to administrate the monolith and the developers will go and build new small applications based on microservices in Docker.

In some of these new teams, there were no application administrators, to raise awareness on JRE, JVM and the garbage collector related issues, and no one else took care about this aspect. Instead, Kubernetes is used to deploy our newly shiny Docker images. So, there are not too many people to wonder if Java is really suitable for this kind of architecture from a reliability point of view.

As an old app admin to a new SRE position, I learned about Golang, which looks like a much better alternative for microservices.

Meanwhile, all Kubernetes is full of Java code and there are apps that cannot start if they have not a minimum of 200MB of RAM because Java code runs into a container image with its own JWM, JRE, JAR, CVE security patches and so on (all with an Image size 500+ MB).

                                                  scala microservice

During my learning time for Go, I started to play by writing small compiled Go microservices:

  • Static data that have 11MB in image size and 9MB of RAM used
  • DB Command Model 13MB in image size and 23MB of RAM used
                                                     golang static data
                                     golang database command model

(*both Java and Go screenshots are from services that run for at least 1 day).

Read the complete article here.

Written by Ionut Ilie, METRO SYSTEMS Romania