Showing posts with label Microservice. Show all posts
Showing posts with label Microservice. Show all posts

Saturday, 29 August 2020

This week 5/2020 - Docker tools

This article is a shortcut of docker tools. These tools are commonly used in micro-service architecture:

  • Docker
  • Docker Compose

Docker

is a platform to run application using containers. Containers are created on basis of images created incrementally similar to code repositories, layer after layer.
Container is a environment to run isolated application. It doesn't use their own operating system as virtualized machines. Container share it with host that's why container stand up in a seconds and is lighter for physical machine instead of stand up minutes as virtual machine. That's why docker is commonly used to create instances of application.

Docker can be used interactively, from console. Below most useful commands:

docker ps - show all running container
docker images - show images in local repository
docker run -d [image_name] - run image in daemon mode
docker exec -it [container_id] "[command to run in the container, ex /bin/sh]" - plug in and execute command on specific container
docker container logs [container_id] - print logs from container
docker pull [image name] - pull image from external images repository

but the biggest benefit of docker is that can be used by scripts, so all process is repeatable and can be automatized. Default docker file is Dockerfile. Below some example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# base image to this build
FROM openjdk:8-jdk-alpine

# define what directory should be mounted to host 
# - mounted directories are created in /var/lib/docker/volumes
VOLUME /tmp

# only inform what ports can expose application
EXPOSE 8080

# define variable
ARG JAR_FILE=target/*.jar


# define variable using environment variable, or "v.1.0.0" if not defined. 
#ENV override ARG variable. Example execution with variable: 
# $ docker build --build-arg CONT_IMG_VER=v2.0.1 .
ENV SOME_ENV_VAR ${CONT_IMG_VER:-v1.0.0}


#copy file from host to container storage
COPY ${JAR_FILE} app.jar

#copy file from host to container storage, but comparing to COPY 
# can also get file from url and extract tar file
ADD ${JAR_FILE} app.jar

# run command in container
RUN uname -a

# health check command - docker is checking if application is working properly
HEALTHCHECK --interval=5m --timeout=3s --retries=5 \
  CMD curl -f http://localhost/ || exit 1


# run application as goal of this image
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]


having Dockerfile it is executed command:

docker build

and then if this image have to be pushed to remote repository

docker image tag [image_tag_name] [docker repository path]
docker push [docker repository path]

There is also possible to start a repository on docker container, executing a command:

docker run -d -p 5000:5000 --name registry registry:2

and to remove container registry container

docker container stop registry && docker container rm -v registry


Docker Compose

it is a tool to stand up a few containers on basic of docker-compose.yml file. Tool manages with dependences between containers, so by one command it is possible to run many services (containers). Below a few most useful commands:

docker-compose build - build images included in file docker-compose.yml
docker-compose up -d - run containers in daemon mode
docker-compose down - stop containers
docker-compose logs - print logs from containers

and docker-compose.yml file example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# version of file format
version: "3.3"
# definition of services (container templates)
services:
 #name of service 
  mongoDB:
# image name - this image is retrieved from remote repository  
    image: library/mongo:4.4.0
# container name     
    container_name: "mongoDBcontainerName"
# what if application is dead    
    restart: on-failure
# ports which should be exposed to host (host port: container port)    
    ports:
    - 27017:27017
# images have defined variables, this way are defined their values
    environment:
      MONGO_INITDB_ROOT_USERNAME: sboot
      MONGO_INITDB_ROOT_PASSWORD: example
      MONGO_INITDB_DATABASE: test
# storage mapping ( host : containers path : access mode)      
    volumes:
      - ./src/main/sql/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro

  app:
# build properties - this service will be built 
    build:
# where is context path on host    
      context: ./
# docker file      
      dockerfile: Dockerfile
    container_name: "myApp"      
# definition of depending on services      
    depends_on:
      - mongoDB
# this defines in container dns names for depending on services
    links:
      - mongoDB

To prepare this article I used:

  • Docker in version 19.03.6 - provided by system
  • Docker Compose in version 1.17.1 - provided by system

Resources:
[1] Docker

Sunday, 26 March 2017

This week 5/2017

In this article I'd like to collect some ideas connected with Microservice Architecture.

1. Bounded context and organisational aspect.
In many sources there is recommendation to create small teams dedicated to one or a few microservices. One microservice should resolve a problem of one bounded context. A small team should well understand implemented part of domain (bounded domain) and should gather maximum "two-pizza team".

2. Possibility to scaling every service of application. 
Microservice architecture requires usage of many servers, that's why they have to be monitored and managed centrally. On each server works one instance of service but if we need more instances it is very easy to install it on more servers. This way it is possible to start new instance of service and shut down it if it is  needless. Another advantage of Microservice is that small application boot faster than big monolith and it is easy to deploy new code without outage.

3. Duplication of code
There is common opinion that much easier is to control monolith than Microservices. Martin Fowler recommends to try resolve business problem in monolith architecture and then eventually move into microservices. However this style have become fashionable and everyone tries his hands at it and it has nothing common to do with business needs... During migration process there is a lot of duplicated code between services. It could be also big problem. However my idea is to move shared parts of code into small utils jars.

4.  Latency time & lack of consistent = additional complexity
Common question is how to get consistency and availability concurrently? Answer is sad but it is impossible. Consistency requires to have shared database where every business operation locks updated or removed record.
However, firstly we have to remember that coding, transmitting and decoding message takes time, especially if services are situated in worldwide locations, transmission has significant influence.
Secondly, fault tolerant services move task to available instance of service.
Then, to have hight performance every service has its own database or even every instance of service. That's why in most cases there is used optimistic locking, data partitioning or CQRS and Event Sourcing. Sometimes it is not enough and some business decisions are required to be ready for border conditionals, ex. hotel's room reservation problem.

5. Interface development - contract problem
This subject is good known for SOA and Microservices as well. The common solution for SOA is to use the same wsdl file for producer and consumer but what if we have many different consumers and we need to extend our interface without engaging teams responsible for immutable services?
There is one way to do that - Consumer-Driven Contract. This approach requires to use only needed fields and inform producer about customer schema.


Resources: