Book Image

Microservices Deployment Cookbook

By : Vikram Murugesan
Book Image

Microservices Deployment Cookbook

By: Vikram Murugesan

Overview of this book

This book will help any team or organization understand, deploy, and manage microservices at scale. It is driven by a sample application, helping you gradually build a complete microservice-based ecosystem. Rather than just focusing on writing a microservice, this book addresses various other microservice-related solutions: deployments, clustering, load balancing, logging, streaming, and monitoring. The initial chapters offer insights into how web and enterprise apps can be migrated to scalable microservices. Moving on, you’ll see how to Dockerize your application so that it is ready to be shipped and deployed. We will look at how to deploy microservices on Mesos and Marathon and will also deploy microservices on Kubernetes. Next, you will implement service discovery and load balancing for your microservices. We’ll also show you how to build asynchronous streaming systems using Kafka Streams and Apache Spark. Finally, we wind up by aggregating your logs in Kafka, creating your own metrics, and monitoring the metrics for the microservice.
Table of Contents (15 chapters)
Microservices Deployment Cookbook
Credits
About the Author
About the Reviewer
www.PacktPub.com
Customer Feedback
Preface

Writing microservices with Dropwizard


Dropwizard is a collection of libraries that help you build powerful applications quickly and easily. The libraries vary from Jackson, Jersey, Jetty, and so on. You can take a look at the full list of libraries on their website. This ecosystem of libraries that help you build powerful applications could be utilized to create microservices as well. As we saw earlier, it utilizes Jetty to expose its services. In this recipe, we will create the same GeoLocation API using Dropwizard and Jersey.

To avoid confusion and dependency conflicts in our project, we will create the Dropwizard microservice as its own Maven project. This recipe is just here to help you get started with Dropwizard. When you are building your production-level application, it is your choice to either use Spring Boot, WildFly Swarm, Dropwizard, or SparkJava based on your needs.

Getting ready

Similar to how we created other Maven projects, create a Maven JAR module with the groupId  com.packt.microservices and name/artifactId  geolocation-dropwizard. Feel free to use either your IDE or the command line. After the project is created, if you see that your project is using a Java version other than 1.8, follow the Creating a project template using STS and Maven recipe to change the Java version to 1.8. Perform a Maven update for the change to take effect.

How to do it...

The first thing that you will need is the dropwizard-core Maven dependency. Add the following snippet to your project's pom.xml file:

  <dependencies> 
    <dependency> 
      <groupId>io.dropwizard</groupId> 
      <artifactId>dropwizard-core</artifactId> 
      <version>0.9.3</version> 
    </dependency> 
  </dependencies> 

Guess what? This is the only dependency you will need to spin up a simple Jersey-based Dropwizard microservice.

Before we start configuring Dropwizard, we have to create the domain object, service class, and resource class. Follow the steps from the previous recipe to create the following four files:

  • com.packt.microservices.geolocation.GeoLocation.java

  • com.packt.microservices.geolocation.GeoLocationService.java

  • com.packt.microservices.geolocation.GeoLocationServiceImpl.java

  • com.packt.microservices.geolocation. GeoLocationResource.java

Let's see what each of these classes does. The GeoLocation.java class is our domain object that holds the geolocation information. The GeoLocationService.java class defines our interface, which is then implemented by the GeoLocationServiceImpl.java class. If you take a look at the GeoLocationServiceImpl.java class, we are using a simple collection to store the GeoLocation domain objects. In a real-time scenario, you will be persisting these objects in a database. But to keep it simple, we will not go that far.

To be consistent with the previous recipe, let's change the path of GeoLocationResource to /geolocation. To do so, replace @Path("/") with @Path("/geolocation") on line number 11 of the GeoLocationResource.java class.

We have now created the service classes, domain object, and resource class. Let's configure Dropwizard.

In order to make your project a microservice, you have to do two things:

  1. Create a Dropwizard configuration class. This is used to store any meta-information or resource information that your application will need during runtime, such as DB connection, Jetty server, logging, and metrics configurations. These configurations are ideally stored in a YAML file, which will then be mapped to your Configuration class using Jackson. In this application, we are not going to use the YAML configuration as it is out of scope for this book.

    Note

    If you would like to know more about configuring Dropwizard, refer to their Getting Started documentation page at http://www.dropwizard.io/0.7.1/docs/getting-started.html .

  2. Let's create an empty Configuration class called GeoLocationConfiguration.java:

             package com.packt.microservices.geolocation; 
     
             import io.dropwizard.Configuration; 
     
             public class GeoLocationConfiguration extends Configuration { 
     
             } 
    
  3. The YAML configuration file has a lot to offer. Take a look at a sample YAML file from Dropwizard's Getting Started documentation page to learn more. The name of the YAML file is usually derived from the name of your microservice. The microservice name is usually identified by the return value of the overridden method public String getName() in your Application class. Now let's create the GeoLocationApplication.java application class:

            package com.packt.microservices.geolocation; 
     
            import io.dropwizard.Application; 
            import io.dropwizard.setup.Environment; 
      
            public class GeoLocationApplication extends
            Application<GeoLocationConfiguration> { 
        
              public static void main(String[] args) throws Exception { 
                new GeoLocationApplication().run(args); 
              } 
     
              @Override 
              public void run(GeoLocationConfiguration config, Environment 
                 env) throws Exception { 
                 env.jersey().register(new GeoLocationResource()); 
              } 
            } 
    

    There are a lot of things going on here. Let's look at them one by one. Firstly, this class extends Application with the GeoLocationConfiguration generic. This clearly makes an instance of your GeoLocationConfiguraiton.java class available so that you have access to all the properties you have defined in your YAML file at the same time mapped in the Configuration class. The next one is the run method. The run method takes two arguments: your configuration and environment. The Environment instance is a wrapper to other library-specific objects such as MetricsRegistry, HealthCheckRegistry, and JerseyEnvironment. For example, we could register our Jersey resources using the JerseyEnvironment instance. The env.jersey().register(new GeoLocationResource()) line does exactly that. The main method is pretty straight-forward. All it does is call the run method.

  4. Before we can start the microservice, we have to configure this project to create a runnable uber JAR. Uber JARs are just fat JARs that bundle their dependencies in themselves. For this purpose, we will be using the maven-shade-plugin. Add the following snippet to the build section of the pom.xml file. If this is your first plugin, you might want to wrap it in a <plugins> element under <build>:

        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-shade-plugin</artifactId>
          <version>2.3</version>
          <configuration>
            <createDependencyReducedPom>true</createDependencyReducedPom>
            <filters>
              <filter>
                <artifact>*:*</artifact>
                <excludes>
                  <exclude>META-INF/*.SF</exclude>
                  <exclude>META-INF/*.DSA</exclude>
                  <exclude>META-INF/*.RSA</exclude>
                </excludes>
              </filter>
            </filters>
          </configuration>
          <executions>
            <execution>
              <phase>package</phase>
              <goals>
                <goal>shade</goal>
              </goals>
              <configuration>
                <transformers>
                  <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                  <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
        <mainClass>com.packt.microservices.geolocation.GeoLocationApplication</mainClass>
                  </transformer>
                </transformers>
              </configuration>
            </execution>
          </executions>
        </plugin>
     
    
  5. The previous snippet does the following:

    It creates a runnable uber JAR that has a reduced pom.xml file that does not include the dependencies that are added to the uber JAR. To learn more about this property, take a look at the documentation of maven-shade-plugin.

    It utilizes com.packt.microservices.geolocation.GeoLocationApplication as the class whose main method will be invoked when this JAR is executed. This is done by updating the MANIFEST file.

    It excludes all signatures from signed JARs. This is required to avoid security errors.

  6. Now that our project is properly configured, let's try to build and run it from the command line. To build the project, execute mvn clean package from the project's root directory in your terminal. This will create your final JAR in the target directory. Execute the following command to start your microservice:

          java -jar target/geolocation-dropwizard-0.0.1-SNAPSHOT.jar server
    
  7. The server argument instructs Dropwizard to start the Jetty server. After you issue the command, you should be able to see that Dropwizard has started the in-memory Jetty server on port 8080. If you see any warnings about health checks, ignore them. Your console logs should look something like this:

  8. We are now ready to test our application. Let's try to create two geolocations using the POST API and later try to retrieve them using the GET method. Execute the following cURL commands in your terminal one by one:

            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 41.803488, "longitude": -88.144040}' http://localhost:8080/geolocation
    
  9. This should give you an output similar to the following (pretty-printed for readability):

    {
              "latitude": 41.803488,
              "longitude": -88.14404,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
            curl -H "Content-Type: application/json" -X POST -d '{"timestamp": 1468203975, "userId": "f1196aac-470e-11e6-beb8-9e71128cae77", "latitude": 9.568012, "longitude": 77.962444}' http://localhost:8080/geolocation
    
  10. This should give you an output like this (pretty-printed for readability):

    {  
              "latitude": 9.568012,
              "longitude": 77.962444,
              "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
              "timestamp": 1468203975
            }
    
  11. To verify whether your entities were stored correctly, execute the following cURL command:

          curl http://localhost:8080/geolocation
    
  12. It should give you an output similar to the following (pretty-printed for readability):

    [
              {
                "latitude": 41.803488,
                "longitude": -88.14404,
                "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                "timestamp": 1468203975
              },
              {
                "latitude": 9.568012,
                "longitude": 77.962444,
                "userId": "f1196aac-470e-11e6-beb8-9e71128cae77",
                "timestamp": 1468203975
             }
           ]
    

Excellent! You have created your first microservice with Dropwizard. Dropwizard offers more than what we have seen so far. Some of it is out of scope for this book. I believe the metrics API that Dropwizard uses could be used in any type of application. Therefore, we will look at how to use it in later chapters.