01 - The Driver for Change

The first thing we are going to do is run and examine a simple application. You are not expected to write any code, but we will be looking at Dockerfiles and Docker-Compose files.

The purpose of the exercise is to help you understand the structure of the application, capture it using C4, and ask architecturally significant questions.

01 The Monolith Application

Docker is an ideal tool for understanding the nature of monolithic applications without the need to have numerous physical nodes (a node is a piece of hardware)

Recap on the advantages of using Docker

  • Containers can be considered lightweight VMs

  • They are self-contained

  • Hermetically sealed

  • They expose their services through ports

  • They can share a common network and volume

image-20240620-125515.png

02 Running the Monolith

  1. Using the Gitbash terminal, navigate to /c/work

  2. Clone down the following projects

    1. https://bitbucket.org/stream2stream/react_app-vat_calculator/src/main/

    2. https://bitbucket.org/stream2stream/vat_calculator_service/src/main/

  3. Start Docker

  4. Open Windows' terminal in Admin mode (right-click on Windows Start, and select Terminal (Admin)

  5. Navigate to c:\work\vat_calculator_service

  6. Enter the command mvn package, this will build the binary for the calculator service. A number of files will have been created in the target folder. You will need the file called vat_calculator_service-0.0.1-SNAPSHOT-spring-boot.jar

  7. Navigate to c:\work\react_app-vat_calculator

  8. Create a folder called target

  9. Copy the file vat_calculator_service-0.0.1-SNAPSHOT-spring-boot.jar into the target folder

  10. Run the command docker build --tag=vat_calculator_service:latest .

    1. the full stop is important

  11. Run the command docker run -p 3000:3000 -p 8080:8080 --name vatc_fe --rm vat_calculator_service this will create a single docker container containing the 3 applications that are all wired together

03 Understanding the Monolith

Run the following commands

  1. Use docker ps -a you should see the container called vatc_fe, and the exposed ports.

  2. Open the frontend application from the browser using the URL localhost:3000

  3. Select Sales, you should see some sales data

  4. Attach to the application service from the browser using the URL http://localhost:8080/api/v1/vatentries. You should see some JSON data. It should be the same data that you saw when you selected the Sales menu item on the frontend app.

Before you run the next set of commands be sure that you have run the commands above 1, 2, and 3, you need to make notes of the observable results.

Run the following commands

  1. Run docker stop vatc_fe

  2. Run docker ps -a

  3. The container should have stopped and have been removed as a container, rerun the commands 2 and 3 above

  4. What are the observable results?

You are going to make a change to the backend (observe and make notes about the process you are about to follow)

  1. Using the terminal navigate to c:\work\vat_calculator_service (unless you are already there)

  2. Type code .

    1. the full stop is important

  3. Locate the file VATEntry.java (it’s in the folder src/main/java/com/celestial/vatcsl/model

  4. Replace line 37 so it looks like this this.description = ">>>" + description + "<<<";

  5. Save the file, and close VSC

  6. Run mvn package

  7. Navigate to c:\work\react_app_calculator.

  8. Copy the file vat_calculator_service-0.0.1-SNAPSHOT-spring-boot.jar into the target folder

  9. Run the command docker build --tag=vat_calculator_service:latest .

  10. Run the command docker run -p 3000:3000 -p 8080:8080 --name vatc_fe --rm vat_calculator_service this will create a single docker container containing the 3 applications that are all wired together

  11. Use docker ps -a; you should see the container called vatc_fe and the exposed ports.

  12. Open the frontend application from the browser using the URL localhost:3000

  13. Select Sales, you should see some sales data. The description of each sales item should be surrounded with >>> and <<<

Model what you have learnt using C4.

So what are the things that you notice and architecturally what are the PROs and CONs?

04 Monolith Breakdown

image-20240620-142909.png

05 Monolith to Docker

06 PROs and CONs of the Monolith

 

 

 

 

 

07 Breaking up the Monolith

We are now going to run each component of the system as separate services

Before we run the separate components we need to clean up the previous images. Run the following commands

  1. Run docker images, look for vat_calculator_service. When you find it, make a note of the first three characters of the image ID

  2. Run docker rmi <the three digits of the image ID>

The system should display a long number, the SHA. This indicates that the images have been removed. You are now ready to start the separate services.

Run the following commands

  1. Make sure you are in the folder c:\work\react_app_calculator

  2. Run docker-compose up

  3. Wait until no more messages are being sent to the screen

  4. Open another terminal window (the plus symbol next to the title of the current terminal window)

  5. Run docker ps -a, look at the services that are running. You should notice that there are two services; one is called vatc-fe, and the other is called vatc-service

  6. Examine the other fields that are displayed from the docker ps -a command

  7. In your browser enter the URL localhost:3001, when the app is running select the Sales menu option, and you should see some data

  8. In your browser enter the URL localhost:8080/api/v1/vatentries, you should see the same data from when you select the Sales option

  9. From the terminal run docker stop vatc-service

  10. In your browser enter the URL localhost:8080/api/v1/vatentries, you should see no data, this is because we have stopped the backend server

  11. In your browser enter the URL localhost:3001, when the app is running select the Sales menu option, and you should see no data, this is because the frontend runs as a separate service to the backend, we have isolated each service from the other.

  12. From the terminal run docker start vatc-service

  13. In your browser enter the URL localhost:8080/api/v1/vatentries, you should see the same data from when you select the Sales option

  14. From the terminal run docker stop vatc-fe

  15. In your browser enter the URL localhost:3001, it should fail to connect to the application

  16. In your browser enter the URL localhost:8080/api/v1/vatentries, you should see the same data from when you select the Sales option, so you can still access the data even though the frontend has been stopped

Stop and start each service, examining the results in the browser. Make sure you understand what’s happening here

Services are all about the separation of concerns

Domain Driven Design is all about the separation of concerns.

08 Cloud Computing Architecture

09 AWS Example with Docker Containers

We could use a computer engine, but this would require us to select the OS (infrastructure platform) and then install all the necessary applications and libraries to run our container on that compute engine

A better approach would be to use

A container-configured environment. Point the service at the registry where the Dockerfile is located, and let it do all the heavy lifting for you.

We’ve also highlighted Red Hat OpenShift as an alternative approach. OpenShift® gives a one-stop shop to access the services of any number of cloud providers, it’s a unified platform to build, modernize, and deploy applications at scale

10 Quality of Service Attributes Gained

10-01 Scaleability

When you ran the monolith VAT application one of the main issues was its inability to scale. Whether we wanted to scale it horizontally or vertically was an issue

Vertical Scaling

Modify the Node by adding more RAM, Upgrading the CPU, and adding more Disk space. All of these options require the system to be shut down, the hardware to be installed and the system to be rebooted. After this, you could have too much capacity or too little capacity.

Horizontal Scaling

Replicate a service, and distribute the workload amongst the distributed services You would make use of something like a load balancer to ensure that traffic is evenly sent to all replicated nodes/services (the cluster).

10-01 Demo Time

The trainer will demonstrate a Docker Image being deployed onto an AWS container service. They will also show horizontal scaling at work.

10-02 Less Brittle Architecture

10-03 Maintainability

How much effort is required to maintain the system, modify it, and integrate it with other systems?

If it’s difficult to make changes then it’s not maintainable

If it’s not clear what the effect is of changing the code (the outcomes become guesswork), then it’s not maintainable

If you have to butcher the code to make it realize new scenarios whilst continuing to be what it was intended for, then it’s not maintainable

10-04 Security

A system is the sum of its parts. If each service can have its level of security (different set of security constraints), it becomes easier to secure the whole. But if the whole is a monolith, inevitably it becomes more difficult to apply security constraints around the parts.

10-05 Performance

You tune the whole by tuning the parts. That’s a basic engineering principle.

Formula 1 teams spend vast amounts of money capturing data from all the components of the car, as well as the performance of the driver. The car and driver only hit optimal performance when everything is functioning in harmony.

10-06 Cost Efficiency

The problem with the monolithic approach is that you have to tune the whole even though your intention may be to only effect a part. It then becomes very difficult to target the tuning for a single part without affecting the whole. So you end up spending money where it’s not needed. The tuning and cost management becomes much easier by componentising the system and using a micro-service architecture.

10-07 More fault-tolerant

The requirement is to make the whole fault-tolerant, but each component has different requirements for achieving fault tolerance. By tackling each part, you are tackling the whole.

10-08 Higher availability

The requirement to make the entire system highly available can only be achieved by tuning thr parts and making them highly available. If you’re dealing with a monolith, then if one part fails, then the whole fails. But if we compartmentalise the system, and reduce the coupling, then if one part fails, strategies can be put in place to ensure that the whole is not compromised.

10-09 More extensible

A system is only extensible if it is designed to be extensible. If you have a monolithic piece of code, then by it’s very nature it is not extensible. Likewise if you have a system that is comprised of many parts but the coupling between those parts is tight, then a change in one component will impact on other components. Testing one component would require testing of adjacent components etc. This is a bad design.