Introduction to Microservices
Now that we have made it through our whirlwind introduction to microservices, it is time to begin implementing what we have learned so far. To do this, we will begin by building a reference implementation for a simple microservice application. The goal of this reference implementation is to create the skeleton of a fully functional microservice application using a particular implementation technology.

Rather than building a toy application, the reference implementation will provide an open-source implementation of the essential components common to many microservice applications, including both infrastructure and application elements. The reader is free to use these components as they are or customize them to suit their needs. Since we are using a microservice approach, the reader can supplement the reference architecture with any application-specific service they may require. The reference architecture will both demonstrate a working microservice architecture and provide a bootstrap application on which to build.

Infrastructure Components

The infrastructure components we will be building will provide common services that assist the application components. These include:

  • Unified Logging

    In a microservice architecture, each service generates an individual log, which complicates troubleshooting when a request spans multiple services. To address this, we will employ a unified logging model. This approach employs a data collector and transport mechanism (Fluentd), a centralized log indexer and persistent store (Elasticsearch), and a User-interface for querying the log data (Kibana). This stack allows aggregation, indexing, and query capabilities across all of the application's services log data.

    Fluentd is the open-source data collector we will use in conjunction with each of our services to collect service log output and transport it to the unified data store.

    Elasticsearch provides a persistent, indexed data store for each of the reference implementation's service logs. Elasticsearch unifies the disparate service logs into a single searchable location.


    Kibana provides a comprehensive user interface to the Elasticsearch store. It provides log query capabilities and can be configured to provide a graphical application dashboard.

  • Message/Event Bus

    - The Message/Event Bus provides a shared message bus that can be used to communicate state changes and messages between services.


    In our reference implementation, we will be using the open-source RabbitMQ message broker. Spring Integration has comprehensive support for most Enterprise Integration Patterns when using RabbitMQ.

  • Application Data Persistence

    The reference implementation employs both Relational and Document-oriented persistence models.

    Relational persistence


    The reference implementation will use the PostgreSQL open-source database for relational persistence. The PostgreSQL instance will be administered with an instance of pgAmin4, which provides a full-featured, web-based administration client.

    Document-oriented persistence


    The reference implementation uses the MongoDB open-source database for its document-oriented persistence. The MongoDB instance will be administered by an instance of MongoExpress, which provides a web-based administration client.

  • Service Metrics Monitoring

    Each service in the reference implementation generates a set of metrics that we will use to monitor its health and activity. To accomplish this we will deploy two supporting services: Prometheus and Grafana.

    Prometheus


    Prometheus provides an open-source time-series database to capture real-time metrics. Prometheus that performs an interval poll of each service's actuator endpoint to collect both service-specific metrics as well as a comprehensive complement JVM metrics.

    Grafana


    Grafana provides an open-source analytics and visualization application that retrieves time-series data from the Prometheus instance. We will use it to visual real-time metrics for each service.


Application Components

In our skeleton application, we are focused on providing components common to most applications while demonstrating the microservice principles we have covered in previous articles.

  • Configuration Service- This service allows the application to centralize all service configuration data to a single location. When a service starts, it queries the configuration service to retrieve its custom configuration.
  • Discovery Service- This service provides a mechanism to allow register and query services. On startup, each service registers with the Discovery Service to announce its availability to service requests. When a service needs to call a different service, it queries the Discovery Service to lookup an available service instance of a specific type. This mechanism decouples services from each other and allows services to scale by enabling multiple instances of the service to be load balanced.
  • Authentication Service- The Authentication Service is responsible for handling the following user-related services:
    • Registration - allow a new user to register.
    • Authentication - authenticate a user's credentials.
    • Authorization - assign roles to a user.
    • Password change- allow a user to change their password.
    • Password recovery- allow a user to recover a lost password using the email address associated with the account.
    • JWT generation- generate a JSON Web Token with the user's information, roles, and refresh token.
    • Token refresh- allow the user to refresh their token using a refresh token embedded in the JWT.
    • User Account enable/disable- provide a facility to enable/disable a user account.
  • Account Profile Service- Maintains account profile demographic data and avatar for each system user.
  • Account History Service - Maintains all historical account events generated by the application for each user.
  • Content Service - Provides a lightweight content server to provide static resources to application clients.
  • Administration Service- Provides administration services for the application.
  • Notification Service -Provides a service that allows the application to send outbound Email and SMS messages.
  • Outbound Email Service-Provides an outbound email client service that can be scaled to support large email volumes.
  • Outbound SMS Service -Provides an outbound SMS client service that can be scaled to support large SMS volumes.
  • Feature Service -Provides an endpoint for retrieval of client feature sets to support Feature Toggles.
  • Telemetry Service-Provides application client logging telemetry to troubleshoot client applications and to capture client operations.
  • Peer-Signaling Service-Provides a peer signaling service that supports WebRTC peer-to-peer video/and data clients.
  • API Gateway Service- Provides the external, client-facing application API.




Deployment

In the first phase of each of our implementations, we will get our feet wet with containers using Docker containers to package, deploy, and run each of the application's services. We will use Docker-Compose to provide basic service orchestration. Once we have built all of our services, we will orchestrate the application using Kubernetes.

Coming Up

Our first implementation will employ the Spring application framework. In the next article, we will introduce you to the Spring Application Framework, Spring Boot, and Spring Cloud and discuss the rationale for Spring.