JavaRush /Java Blog /Random EN /A Guide to Java Microservices. Part 2: Deployment and Tes...

A Guide to Java Microservices. Part 2: Deployment and Testing

Published in the Random EN group
Translation and adaptation of Java Microservices: A Practical Guide . Link to the first part of the guide . A Guide to Java Microservices.  Part 2: Deployment and Testing - 1Any server-side Java program, and therefore any microservice, is just a file with a .jar or .war extension. There's one great thing about the Java ecosystem, or rather the JVM: you only need to write Java code once and it can run on almost any operating system, as long as you haven't compiled your code with a newer version of Java than your target JVM version . This is important to understand, especially when it comes to topics like Docker, Kubernetes, or (drum roll!) The Cloud. Why? Let's look at different deployment scenarios.

Minimalistic Java Microservice Deployment Example

Let's continue with the bank example. So we have a monobank.jar file (monolith) and our newly extracted riskengine.jar (the first risk checking microservice). Let's also assume that both applications, like every other application in the world, need a .properties file. In our case, it will only contain the database URL and credentials. A minimal deployment might consist of two directories that look something like this: First:

-r-r------ 1 ubuntu ubuntu     2476 Nov 26 09:41
-r-x------ 1 ubuntu ubuntu 94806861 Nov 26 09:45 monobank-384.jar

ubuntu@somemachine:/var/www/$ java -jar monobank-384.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

-r-r------ 1 ubuntu ubuntu     2476 Nov 26 09:41
-r-x------ 1 ubuntu ubuntu 94806861 Nov 26 09:45 risk-engine-1.jar

ubuntu@someothermachine:/var/www/$ java -jar risk-engine-1.jar

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
This leaves the question open: how will the .properties and .jar files get to the server? Unfortunately, there may be many answers.

How to Use Build Tools, SSH, and Ansible to Deploy Java Microservices

Boring, but no less excellent advice on how to deploy Java microservices... Actually, exactly the way system administrators have deployed any Java server program in companies over the past 20 years. This is the mix:
  • your favorite build tool (Maven, Gradle)
  • good old SSH/SCP for copying .jars to servers
  • Bash scripts to manage deployment scripts and servers
  • or even better: some Ansible scripts.
Of course, this is not suitable for innovators who need a “breathing” cloud, servers with automatic load balancing, and so on. This is real boring old school. However it works!

How to Use Docker to Deploy Java Microservices

Let's return to the sweet agony of choice. A couple of years ago Docker came onto the scene, and with it containerization. If you've never worked with it, here's a short description aimed at end users and developers:
  • A container (simplified) is similar to the good old virtual machine, but “lighter”. If you are unclear about what “easier” means in this context, please check out this answer on Stackoverflow .
  • The container guarantees its own portability. That is, it works anywhere. Sounds familiar, doesn't it?
A Guide to Java Microservices.  Part 2: Deployment and Testing - 2It's funny that given the JVM's portability and backward compatibility, this feature doesn't seem like such an advantage. You can simply download on any Raspberry Pi (or even mobile phone), extract it and run any .jar file. The situation changes in languages ​​like PHP or Python, where version incompatibilities or deployment settings are more complex. Or if your Java application depends on many other installed services (with the correct version numbers): for example, a Postgres database, or a Redis key value store. So, the main advantage of Docker for Java microservices, or more precisely for Java applications, is this: the ability to set up homogenized testing or integration environments using tools like Testcontainers . Complex developments are easier to install. Take Discourse forum software . You can install it with a single Docker image, and that image contains everything you need, from Discourse software written in Ruby, to a Postgres database, to Redis, to the kitchen sink. If your deployments are similar or you want to run a nice little Oracle database, try Docker. So to summarize, instead of just looking at the .jar file, you now:
  • bundle your jar file into a Docker image
  • push this image to a private Docker registry
  • pull and run this image on your target platform
  • or copy the Docker image directly to your production system and run it.

How to Use Docker Swarm or Kubernetes to Deploy Java Microservices

Let's say you decide to try Docker. Every time you deploy a Java microservice, you create a Docker image that bundles your .jar file. Let's say you have a couple of these Java microservices, and you want to deploy these services on several machines (in a cluster). The question arises: how to manage this cluster? Run Docker containers, check performance, deploy updates, scale the system (brrr)? Two possible answers to this question are Docker Swarm and Kubernetes. Going into detail about both options would make this already long tutorial too long, but we think it's important to mention that both options ultimately rely on you writing YAML files (see Yaml indentation stories ) to manage your cluster. If you want to know what feelings this evokes in practice, just type a similar query into the Twitter search. So the deployment process for your Java microservices now looks something like this:
  • Configuring and managing Docker Swarm/Kubernetes
  • All steps for Docker (see above)
  • Write and execute YAML until your eyes bleed until everything works.

How to Test Java Microservices

Let's say you decide to implement microservices in production. How can we test n-microservices integration during development now? How can you see if the entire workflow is working, and not just parts of it? In practice, you can use one of three methods:
  1. With a little work (if you're using frameworks like Spring Boot), you can combine all your microservices into one launcher class and load all the microservices using a single class - depending on whether you have enough memory on your machine to run them all your microservices.
  2. You can copy Docker Swarm or Kubernetes settings locally.
  3. Just don't run integration tests locally anymore. Instead, deploy a dedicated DEV/TEST environment. This is something that quite a few teams actually do when they succumb to the pain of local microservice setups.
Additionally, in addition to your Java microservices, you will probably also need a running message broker (such as ActiveMQ or RabbitMQ) or perhaps an email server or any other messaging component that your Java microservices need to communicate with each other. This leads to a significant underestimation of complexity on the DevOps side. Take a look at Microservice Testing Libraries, they can alleviate this pain. In any case, this complexity brings us to the general problems of microservices, which we will talk about right now. In the final part , we will cover general questions about Java microservices.