Skip to content

Microservice Architecture with Spring Boot, Spring Cloud and Docker

License

Notifications You must be signed in to change notification settings

pochadri/PiggyMetrics

 
 

Repository files navigation

Build Status codecov.io GitHub license Join the chat at https://gitter.im/sqshq/PiggyMetrics

Piggy Metrics

A simple way to deal with personal finances

This is a proof-of-concept application, which demonstrates Microservice Architecture Pattern using Spring Boot, Spring Cloud and Docker. With a pretty neat user interface, by the way.

Piggy Metrics

Functional services

PiggyMetrics was decomposed into three core microservices. All of them are independently deployable applications, organized around certain business capability.

Functional services

Account service

Contains general user input logic and validation: incomes/expenses items, savings and account settings.

Method Path Description Authenticated Available from UI
GET /accounts/{account} Get specified account data
GET /accounts/current Get current account data × ×
GET /accounts/demo Get demo account data (pre-filled incomes/expenses items, etc) ×
PUT /accounts/current Save current account data × ×
POST /accounts/ Register new account ×

Statistics service

Performs calculations on major statistics parameters and captures time series for each account. Datapoint contains values, normalized to base currency and time period. This data is used to track cash flow dynamics in account lifetime (fancy charts not yet implemented in UI).

Method Path Description Authenticated Available from UI
GET /statistics/{account} Get specified account statistics
GET /statistics/current Get current account statistics × ×
GET /statistics/demo Get demo account statistics ×
PUT /accounts/{account} Create or update time series datapoint for specified account

Notification service

Stores users contact information and notification settings (like remind and backup frequency). Scheduled worker collects required information from other services and sends e-mail messages to subscribed customers.

Method Path Description Authenticated Available from UI
GET /notifications/settings/current Get current account notification settings × ×
PUT /notifications/settings/current Save current account notification settings × ×

N.B.

  • Each microservice has it's own database, so there is no way to bypass API and access persistance data directly.
  • In this project, I use Mongodb as a primary database for each service. It might also make sense to have a polyglot persistence architecture (сhoose the type of db that is best suited to service requirements).
  • Service-to-service communication is quite simplified: microservices talking using only synchronous REST API. Common practice in a real-world systems is to use combination of interaction styles. For example, perform synchronous GET request to retrieve data and use asynchronous approach via Message broker for create/update operations in order to decouple services and buffer messages. However, this brings us in eventual consistency world.

Infrastructure services

There's a bunch of common patterns in distributed systems, which could help us to make described core services work. Spring cloud provides powerful tools that enhance Spring Boot applications behaviour to implement those patterns. I'll cover them briefly. Infrastructure services

Config service

Spring Cloud Config provides horizontally scalable centralized configuration service in a distributed system. It uses a pluggable repository layer that currently supports local storage, Git, and Subversion.

In this project, I use native profile, which simply loads config files from the local classpath. You can see shared directory in Config service resources. Those config files are shared with all applications in cluster. For example, when Statistics-service requests it's configuration, Config service will response with shared/statistics-service.yml and shared/application.yml (which is shared between all client applications).

Client side usage

Just build Spring Boot application with spring-cloud-starter-config. That's it.

You now don't need any embedded properties in your application. Just provide bootstrap.yml with application name and Config service url:

spring:
  application:
    name: notification-service
  cloud:
    config:
      uri: http://config:8888
      fail-fast: true
With Spring Cloud Config, you can change app configuration dynamically.

For example, EmailService bean was annotated with @RefreshScope. That means, you can change e-mail text and subject without rebuild and restart Notification service application.

First, change required properties in Config server. Then, perform refresh request to Notification service: curl -H "Authorization: Bearer #token#" -XPOST http://127.0.0.1:8000/notifications/refresh

Also, you could use Repository webhooks to automate this process

Notes
  • There are some limitations for dynamic refresh though. @RefreshScope doesn't work with @Configuration classes and doesn't affect @Scheduled methods
  • fail-fast property means that Spring Boot application will fail startup immediately, if it cannot connect to the Config Service. That's very useful when we start all applications together
  • There are significant security notes below

Auth service

API Gateway

Service discovery

Http client, Load balancer and Circuit breaker

Monitor dashboard

Log analysis

Centralized logging can be very useful when attempting to identify problems in a distributed environment. Elasticsearch, Logstash and Kibana stack lets you search and analyze your logs, utilization and network activity data with ease. Ready-to-go Docker configuration described in my other project.

Security

Infrastructure automation

How to run all the things?

Feedback welcome

PiggyMetrics is open source, and would greatly appreciate your help. Feel free to contact me with any questions.

About

Microservice Architecture with Spring Boot, Spring Cloud and Docker

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 38.2%
  • CSS 29.4%
  • JavaScript 21.0%
  • HTML 11.1%
  • Shell 0.3%