{"id":22473346,"url":"https://github.com/arsy786/spring-boot-microservices-2","last_synced_at":"2025-06-21T08:06:53.685Z","repository":{"id":147956100,"uuid":"564380686","full_name":"arsy786/spring-boot-microservices-2","owner":"arsy786","description":"This project provides a comprehensive guide of microservices using Spring Boot and Spring Cloud.","archived":false,"fork":false,"pushed_at":"2024-03-17T14:25:33.000Z","size":7568,"stargazers_count":6,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-09T01:51:22.806Z","etag":null,"topics":["2022","guide","java","microservices","spring-boot","spring-cloud"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arsy786.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2022-11-10T15:40:29.000Z","updated_at":"2025-03-29T13:49:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"5ee273a5-1b14-4dc3-acf0-fe5c15296519","html_url":"https://github.com/arsy786/spring-boot-microservices-2","commit_stats":null,"previous_names":["arsy786/spring-boot-microservices-2"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/arsy786/spring-boot-microservices-2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsy786%2Fspring-boot-microservices-2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsy786%2Fspring-boot-microservices-2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsy786%2Fspring-boot-microservices-2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsy786%2Fspring-boot-microservices-2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arsy786","download_url":"https://codeload.github.com/arsy786/spring-boot-microservices-2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsy786%2Fspring-boot-microservices-2/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261088354,"owners_count":23107682,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2022","guide","java","microservices","spring-boot","spring-cloud"],"created_at":"2024-12-06T12:22:35.037Z","updated_at":"2025-06-21T08:06:48.669Z","avatar_url":"https://github.com/arsy786.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# spring-boot-microservices\n\nThis project is a guide to learning how to build, deploy and manage Microservices\nusing Spring Boot, Docker and Kubernetes.\n\n## Table of Contents\n\n[0. Getting Started](#0-getting-started)\n\u003cbr\u003e\n[A. Building Microservices](#a-building-microservices)\n\u003cbr\u003e\n[1. Building REST Services](#1-building-the-services)\n\u003cbr\u003e\n[2. Communication between Microservices](#2-communication-between-microservices)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[2.1 Synchronous Communication](#21-synchronous-communication)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[2.2 Asynchronous Communication](#22-asynchronous-communication)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[2.3 Implementation (WebClient, OpenFeign)](#23-implementation-webclient-openfeign)\n\u003cbr\u003e\n[3. Service Discovery](#3-service-discovery)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[3.1 Implementation (Eureka)](#31-implementation-eureka)\n\u003cbr\u003e\n[4. API Gateway](#4-api-gateway)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[4.1 Implementation (Spring Cloud Gateway)](#41-implementation-spring-cloud-gateway)\n\u003cbr\u003e\n[5. Security](#5-security)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[5.1 Implementation (Keycloak)](#51-implementation-keycloak)\n\u003cbr\u003e\n[6. Circuit Breaker](#6-circuit-breakers)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[6.1 Implementation (Resilience4J, Hystrix)](#61-implementation-resilience4j-hystrix)\n\u003cbr\u003e\n[7. Centralize Configuration](#7-centralize-configuration)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[7.1 Implementation (Cloud Config)](#71-implementation-spring-cloud-config)\n\u003cbr\u003e\n[8. Distributed Tracing](#8-distributed-tracing)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[8.1 Implementation (Spring Cloud Sleuth \u0026 Zipkin)](#81-implementation-spring-cloud-sleuth--zipkin)\n\u003cbr\u003e\n[9. Message Brokers/Queues](#9-message-brokers--queues)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[9.1 Implementation (Kafka, RabbitMQ)](#91-implementation-kafka-rabbitmq)\n\n[B. Deploying Microservices](#b-deploying-microservices)\n\u003cbr\u003e\n[1. Packaging / Containerizing the Application](#1-packaging--containerizing-the-application)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[1.1 Docker](#11-docker)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[1.1.1 Dockerfile](#111-dockerfile)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[1.1.2 Docker Compose](#112-docker-compose)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[1.1.3 Docker Hub](#113-docker-hub)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[1.2 Jib](#12-jib)\n\u003cbr\u003e\n[2. Managing the Application](#2-managing-the-application)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[2.1 Kubernetes](#21-kubernetes)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[2.1.1 Deployment](#211-deployment)\n\u003cbr\u003e\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;[2.1.2 Service](#212-service)\n\u003cbr\u003e\n\n## 0. Getting Started\n\nYou can watch the tutorial here - [Spring Boot Microservice Project Full Course in 6 Hours (YouTube/ProgrammingTechie)](https://www.youtube.com/watch?v=mPPhcU7oWDU)\n\n### How to run the application using Docker\n\n1. Run `mvn clean package -DskipTests` to build the applications and create the docker image locally.\n2. Run `docker-compose up -d` to start the applications.\n\n### How to run the application without Docker\n\n1. Run `mvn clean verify -DskipTests` by going inside each folder to build the applications.\n2. After that run `mvn spring-boot:run` by going inside each folder to start the applications.\n\n### Configuration\n\nEnsure you review and adjust the `application.properties` and `application-docker.properties` in each service to suit your setup before launching the application with Docker or directly.\n\n## A. Building Microservices\n\n\u003cins\u003eSummary\n\nIn simple terms, a monolithic application is built as a single unified unit while a microservices\narchitecture is a collection of smaller, independently deployable services.\n\n![monolithic-vs-microservice](images/monolothic-vs-microservice-apps.png)\n\n\u003cins\u003eMonolithic Architecture\n\nThe monolithic architecture is considered to be a traditional way of building applications.\nA monolithic application is built as a single and indivisible unit. Usually, such a solution comprises a\nclient-side user interface, a server side-application, and a database.\nIt is unified and all the functions are managed and served in one place.\n\nNormally, monolithic applications have one large code base and lack modularity.\nIf developers want to update or change something, they access the same code base.\nSo, they make changes in the whole stack at once.\n\n| Strengths                           | Weaknesses                              |\n| ----------------------------------- | --------------------------------------- |\n| Easy to develop                     | Less scalability                        |\n| Simple deployment                   | Inability to adapt to new technologies  |\n| Uncomplicated testing and debugging | High dependence between functionalities |\n\n\u003cins\u003eMicroservices Architecture\n\nWhile a monolithic application is a single unified unit, a microservices architecture breaks it down\ninto a collection of smaller independent units.\nThese units carry out every application process as a separate service.\nSo all the services have their own logic and database, as well as perform their specific functions.\n\nWithin a microservices architecture, the entire functionality is split up into independently deployable\nmodules which communicate with each other through defined methods called APIs.\nEach service covers its own scope and can be updated, deployed, and scaled independently.\n\n| Strengths                 | Weaknesses                  |\n| ------------------------- | --------------------------- |\n| Independent services      | Time and resource-consuming |\n| Enables agile development | Complicated deployment      |\n| Scalable \u0026 reliable       | Complex testing             |\n\n\u003cins\u003eDeciding between a Monolithic or Microservices Architecture for your project\n\nFor choosing a monolithic architecture:\n\n- Small team.\n- A simple application.\n- No microservices expertise.\n- Quick launch.\n\nFor choosing a microservices architecture:\n\n- Microservices expertise.\n- A complex and scalable application.\n- Enough engineering skills.\n\n\u003cins\u003eSpring Cloud\n\nSpring Cloud provides many design patterns to help build Microservice applications.\nHere is a typical Microservice application developed using Spring based projects:\n\n![spring-boot-microservices](images/microservices.jpg)\n\n\u003cins\u003eSupporting Material\n\n[Introduction to Microservices, Docker, and Kubernetes (YouTube/JamesQuigley)](https://www.youtube.com/watch?v=1xo-0gCVhTU)\n\u003cbr\u003e\n[Microservices vs Monolith: which architecture is the best choice for your business? (n-ix.com/RomanaGnatyk)](https://www.n-ix.com/microservices-vs-monolith-which-architecture-best-choice-your-business/)\n\u003cbr\u003e\n[the Basic Microservices Architecture with Spring Cloud (devo.to/BrunoDrugowick)](https://dev.to/brunodrugowick/project-overview-the-basic-microservices-architecture-with-spring-cloud-2e8e)\n\u003cbr\u003e\n\n## 1. Building the Services\n\nTo build the microservices, we must first separate the components that would be present in a\nMonolithic application into smaller, independent applications.\n\nFor example, instead of building a \"Store App\" with a model, repository, service and so on for\nProduct, Order and Inventory... we extract these into their own individual applications.\nHere, we will end up with product-service, order-service and inventory-service applications.\n\nThe Microservice example application developed in this repository is based on the architecture below\nand comes from [Spring Boot Microservices Full Course (YouTube/ProgrammingTechie)](https://www.youtube.com/playlist?list=PLSVW22jAG8pBnhAdq9S8BpLnZ0_jVBj0c):\n\n![microservices-app-architecture](images/microservices-app-architecture.png)\n\nWe must not forget to carry out appropriate tests for each microservice, this is typically carried out in\nthe form of integration tests.\nFor testing, we can make use of Testcontainers which allows us to run JUnit tests in lightweight throwaway\ninstances of databases that can be run in Docker containers!\n\nFurthermore, it will be more functional to adopt a Maven multi-module project to manage the\nmicroservices/applications more easily.\n\n\u003cins\u003eSupporting Material\n\n[Spring Boot Microservices Level 1: Communication and Discovery (YouTube/JavaBrains)](https://www.youtube.com/playlist?list=PLqq-6Pq4lTTZSKAFG6aCDVDP86Qx4lNas)\n\u003cbr\u003e\n\n## 2. Communication between Microservices\n\n![interservice-communication](images/interservice-comms.png)\n\nIf you are working with a Spring Boot project which involves multiple microservices,\nYou might have felt the need to communicate from one microservice to another.\nDepending upon business use-cases, this communication can be of synchronous or asynchronous type.\n\n\u003cins\u003eSupporting Material\n\nLink to: [Spring Boot Microservices Level 1: Communication and Discovery (YouTube/JavaBrains)](https://www.youtube.com/playlist?list=PLqq-6Pq4lTTZSKAFG6aCDVDP86Qx4lNas)\n\u003cbr\u003e\n\n## 2.1 Synchronous Communication\n\nIn the case of Synchronous Communication, the client sends a request and waits for a response from the service.\nThe important point here is that the protocol (HTTP/HTTPS) is synchronous and the client code can only continue\nits task when it receives the HTTP server response.\n\nAn example of where this might be used is in an e-commerce application, if a customer searches for a particular\nproduct to purchase, then that product’s availability needs to be validated in the inventory by making a request\nto the product availability service.\nWhy? Because the customer must know about the current availability of the product before placing the order.\nIn this case, you use synchronous communication to get the product’s real-time availability\nin inventory and price information.\n\nFor Synchronous Communication: Can make use of REST Template, OpenFeign or WebClient.\n\n## 2.2 Asynchronous Communication\n\nIn the case of Asynchronous Communication, the client sends a request and does not wait for a response from the service.\nThe client will continue executing its task - It does not wait for the response from the service.\n\nAn example of where this might be used is in the banking domain, a loan request should be processed and needs approval at multiple levels.\nSo in this case, when a user raises a request for the loan, the loan request service will provide a reference number immediately.\nOnce all the approvals are done, the system will persist the loan request details into the database.\nSo in this scenario, we can use asynchronous communication.\n\nFor Asynchronous Communication: Can make use of Message Brokers / Message Queues such as RabbitMQ and Apache Kafka.\n\n## 2.3 Implementation (WebClient, OpenFeign)\n\n\u003cins\u003eWebClient\n\nWebClient is an interface representing the main entry point for performing web requests.\nIt was created as part of the Spring Web Reactive module and has replaced the classic RestTemplate in these scenarios.\n\nLink to WebClient examples:\n\u003cbr\u003e\n[Calling REST from Java with Spring WebClient (YouTube/vaadinofficial)](https://www.youtube.com/watch?v=-U_dDUAw_OM)\n\u003cbr\u003e\n[Using WebClient to make API calls (YouTube/JavaBrains)](https://www.youtube.com/watch?v=F3uJyeAyv5g)\n\n\u003cins\u003eOpenFeign\n\nOpenFeign, originally known as Feign and sponsored by Netflix, is designed to allow developers to use a declarative\nway to build HTTP clients by means of creating annotated interfaces without writing any boilerplate code.\n\nLink to OpenFeign examples:\n\u003cbr\u003e\n[Feign Client Using Spring Boot (YouTube/PlayJava)](https://www.youtube.com/watch?v=tlshVRtbS_c)\n\n\u003cins\u003eAsynchronous Communication\n\nImplementation of Asynchronous Communication is covered in [Section 9. Message Brokers/Queues](#9-message-brokers--queues).\n\n## 3. Service Discovery\n\nMicroservices are dynamic in nature. This means that multiple instances of a single Microservice\ncan/will be co-existing.\nIt is likely your instances will either have a different IP address, a different port or even both.\nFurthermore, the number of instances will be dynamic too.\n\nThis brings up the questions:\n\n- How do I know the location of any Microservice instance?\n- How can I keep a track of all the instances?\n- How do I select a Microservice instance?\n- What happens if the Microservice instance goes down?\n\nWhen building REST APIs, We are assuming the URL (e.g. http://localhost:8080/product/\\*\\*) to be constant\nbut in reality, it is dynamic. All parts of it — be it the hostname or the port.\n\nService Discovery solves this problem. It provides a mechanism that keeps track of all the services and their instances.\nAll the Microservices register to the Service Discovery and update their network information regularly.\n\n\u003cins\u003eClient-side Service Discovery\n\n![eureka-service-discovery](images/eureka-service-discovery.png)\n\nThe discovery server will keep a track of all the instances, their hosts, ports, and health status.\nIf a service needs to communicate with another service, it needs to get the instance info from this\ndiscovery server. However, Load balancing is a must as the discovery server does not handle it automatically.\n\nClient-side service discovery allows services to find and communicate with each other without hard-coding\nthe hostname and port. The only ‘fixed point' in such an architecture is the service registry, with\nwhich each service has to register.\n\nAbove describes Client-side Service Discovery but, you can also have Server-side Service Discovery.\nServer-side is similar to the option above but the load balancing is not happening at the client side.\nWe have a dedicated proxy server that takes care of this.\n\n\u003cins\u003eSupporting Material\n\n[Spring Boot Microservices Level 1: Communication and Discovery (YouTube/JavaBrains)](https://www.youtube.com/playlist?list=PLqq-6Pq4lTTZSKAFG6aCDVDP86Qx4lNas)\n\u003cbr\u003e\n[Spring Boot Microservices — Developing Service Discovery (Medium/LalVerma)](https://lalverma.medium.com/spring-boot-microservices-implementing-service-discovery-cfc98e49b74f)\n\n## 3.1 Implementation (Eureka)\n\n\u003cins\u003eEureka\n\nWe make use of client-side service discovery via “Spring Cloud Netflix Eureka”.\nWe must ensure the correct dependencies and configurations are entered on both the Server and Client(s) properties file.\nLoad balancing is a must as the discovery server does not handle it automatically, so this must also be configured.\n\nLink to Eureka examples:\n\u003cbr\u003e\n[Spring Boot Microservices Project Example - Part 3 | Service Discovery (YouTube/ProgrammingTechie)](https://www.youtube.com/watch?v=0TQliqoX6Kc\u0026list=PLSVW22jAG8pBnhAdq9S8BpLnZ0_jVBj0c\u0026index=3)\n\n## 4. API Gateway\n\n![api-gateway](images/api-gateway.png)\n\nAn API gateway is the single entry point for all clients. The API gateway handles requests in one of two ways,\nsome requests are simply proxied/routed to the appropriate service while others\nare spread to multiple services.\n\nRather than provide a one-size-fits-all style API, the API gateway can expose a different API for each client.\nFor example, the Netflix API gateway runs client-specific adapter code that provides each client with an API\nthat’s best suited to its requirements.\n\n![api-gateway-2](images/api-gateway-2.png)\n\nThe API gateway might also implement security, e.g. verify that the client is authorized to perform the request.\n\n## 4.1 Implementation (Spring Cloud Gateway)\n\n\u003cins\u003eSpring Cloud Gateway\n\nSpring Cloud Gateway provides a library for building API gateways on top of Spring and Java.\nIt provides a flexible way of routing requests based on a number of criteria, as well as focuses on\ncross-cutting concerns such as security (authentication), resiliency (load balancing), and monitoring.\n\nLink to Spring Cloud Gateway examples:\n\u003cbr\u003e\n[Spring Boot Microservices Project Example - Part 4 | API Gateway (YouTube/ProgrammingTechie)](https://www.youtube.com/watch?v=0TQliqoX6Kc\u0026list=PLSVW22jAG8pBnhAdq9S8BpLnZ0_jVBj0c\u0026index=4)\n\n## 5. Security\n\nAn important aspect of securing your applications is authorization and access to the API resources.\nIf you think about web app authorization, the first approach that probably comes to your mind is OAuth 2.0\nor OpenID Connect. OAuth 2.0 is the industry-standard protocol for authorization.\nOf course, it is supported by Spring Security.\nThere are also multiple OAuth2 providers (Google, Github, etc.) you can integrate your application with. One of them is Keycloak.\n\n## 5.1 Implementation (Keycloak)\n\n\u003cins\u003eKeycloak\n\nKeycloak is an open-source identity and access management solution which makes it easy to secure modern applications with less code.\nKeycloak is based on standard protocols and provides support for OpenID Connect, OAuth 2.0, and SAML.\nBuilding an application that is integrated with Keycloak will provide you a more secure and stable solution.\n\nYou can enable and configure OAuth 2.0 support on the API gateway via Keycloak running in a Docker container.\nBut, we must ensure that configurations such as Issuer URI and SecurityConfig.class are added.\nWhen using POSTMAN for communicating with the REST API's, we must select OAuth2.0\nin \"Authorization Type\" and complete the configuration options as per our KeyCloak settings.\nThis will allow us to use JWT's issued by KeyCloak.\n\nLink to Keycloak examples:\n\u003cbr\u003e\n[Spring Boot Microservices Project Example - Part 5 | Security (YouTube/ProgrammingTechie)](https://www.youtube.com/watch?v=0TQliqoX6Kc\u0026list=PLSVW22jAG8pBnhAdq9S8BpLnZ0_jVBj0c\u0026index=5)\n\u003cbr\u003e\n[Securing Spring Boot Microservices with Keycloak using OpenID | OAuth2.0 (YouTube/JavaTechie)](https://www.youtube.com/watch?v=La082JsJoH4)\n\u003cbr\u003e\n\n## 6. Circuit Breakers\n\nIn Microservices, an application or service can make many remote calls to applications running in different services,\nusually on different machines across a network. If there are many callers to an unresponsive service, you\ncan run out of critical resources leading to cascading failures across multiple systems.\n\nConsider an example that multiple users log-in to a banking application and the account service is down.\nThe authentication service will wait on the account service and now many user threads are waiting for\na response, thereby exhausting the CPU on the authentication service as well as the account service.\nAs a result, the system cannot serve any of the users.\n\nCircuit Breakers are a design pattern to create resilient microservices by limiting the impact of service\nfailures and latencies. The major aim of the Circuit Breaker pattern is to prevent any cascading failure in\nthe system. In a microservice system, failing fast is critical.\n\n![circuit-breaker](images/circuit-breaker.png)\n\nIn the Circuit Breaker, there are 3 states: Closed, Open, and Half-Open. These different states are triggered\nbased on the configurations we have set. There are 2 types of circuit breaker patterns, Count-based and Time-based.\nA count-based circuit breaker switches state from closed to open if the last N number of calls failed or\nwere slow. A time-based circuit breaker switches to an open state if the responses in the last N seconds\nfailed or were slow.\n\nIf there are failures in the Microservice ecosystem, then you need to fail fast by opening the circuit.\nThis ensures that no additional calls are made to the failing service and that we can return the fall back logic\n(we have implemented in our service) to the client immediately.\n\n\u003cins\u003eSupporting Material\n\n[Spring Boot Microservices Level 2: Fault Tolerance and Resilience (YouTube/JavaBrains)](https://www.youtube.com/playlist?list=PLqq-6Pq4lTTbXZY_elyGv7IkKrfkSrX5e)\n\u003cbr\u003e\n\n## 6.1. Implementation (Resilience4J, Hystrix)\n\nSpring Cloud Circuit Breaker supports many circuit breaker implementations including,\nResilience4J, Hystrix, Sentinal, and Spring Retry.\nIn this guide we will be using the modern alternative to Hystrix, Resilience4J.\n\n\u003cins\u003eResilience4J\n\nResilience4J is a lightweight fault tolerance library inspired by Netflix Hystrix, but designed for\nfunctional programming.\nResilience4J provides higher-order functions (decorators) to enhance any functional interface,\nlambda expression or method reference with a Circuit Breaker, Rate Limiter, Retry or Bulkhead.\n\nLink to Resilience4J examples:\n\u003cbr\u003e\n[Spring Boot Microservices Project Example - Part 6 | Resilience4J Circuit Breaker (YouTube/ProgrammingTechie)](https://www.youtube.com/watch?v=0TQliqoX6Kc\u0026list=PLSVW22jAG8pBnhAdq9S8BpLnZ0_jVBj0c\u0026index=6)\n\u003cbr\u003e\n\n## 7. Centralize Configuration\n\nConfiguration is essential for any production application as it is required for establishing connections,\nstoring credentials, configuring Spring Cloud properties and so on.\n\nWe must not write any configuration logic in the business logic code, but instead,\nseparate them and add the config into files such as application.properties.\nThis is done so any property values can be easily set, located or changed.\n\nPreviously, XML was the favoured filetype for storing application properties, however formats such as .properties,\n.yaml and .json are now preferred as they are significantly less verbose.\n\n\u003cins\u003eExternalise Configuration\n\n![config-build](images/config-build.png)\n\nFrom a deployment perspective, it is not necessary to go through the process of rebuilding/testing the application\nwhen changes are made to the config file(s). It is much more efficient to simply separate and externalize\nconfiguration.\n\nSpring Boot by default uses application.properties as its config file however, application.yml supports nesting through\nindentations and reduces duplication when it comes to key name paths.\n\n\u003cins\u003eSpring Profiles\n\nIn Spring, we can specify which environment (DEV, PROD etc.) we want to run the application based on\nthe config file and app names.\nNaming the config files based on environment follows the format:\n\n```\napplication-\u003cenvironmentName\u003e.extn\n```\n\nTo have environment based config while still having everything packaged within the .jar file:\n\n```\njava -jar \u003cjar-name\u003e.jar --spring.profiles.active=test\n```\n\nThis means we can have multiple application-environment.yml config files saved in the project directory, packaged into\nthe .jar file, without stating the active Spring profile, and we can specify which environment to run the application in.\n\n\u003cins\u003eSpring Cloud Config\n\n![centralized-config](images/centralized-config.webp)\n\nIn the Microservices world, managing configurations of each service separately is a tedious and time-consuming\ntask. Imagine each service has their own config file, and there are also multiple instances of each service,\nmanaging properties for each module with the traditional approach is very difficult.\nA Central configuration server provides configurations (properties) to each microservice connected and handles this\nproblem more efficiently.\n\nWhat is required is a repository that holds the configuration files and can be connected to the Spring Cloud Config\nServer. We can use Git for this.\nIn doing this, no application re-build is required if any changes are made to any of these files.\nWhen using a Git Repo, we can commit any changes to the config files and push them to the remote repository directly.\n\nThe goal of centralizing configuration is to:\n\n- Externalize configuration\n- Allow environment specificity (DEV, PROD, TEST)\n- Maintain consistency (configuration between services)\n- Track version history\n- Adopt real-time management (make changes to configuration while services are still running!)\n\n\u003cins\u003eSupporting Material\n\n[Spring Boot Microservices Level 3: Microservice configuration (YouTube/JavaBrains)](https://www.youtube.com/playlist?list=PLqq-6Pq4lTTaoaVoQVfRJPqvNTCjcTvJB)\n\u003cbr\u003e\n\n## 7.1 Implementation (Spring Cloud Config)\n\n\u003cins\u003eSpring Cloud Config Server\n\nWe need to:\n\n- Add Spring Cloud Config Server dependency\n- Add @EnableConfigServer annotation\n- Configure git URI in application.properties file\n- Specify the server.port=8888 (typical for cloud config)\n- Add the Config Clients dependencies\n- Spring Cloud Config URI properties\n- Add any microservice specific properties in microservices-name.yml where the name is specified in spring.app.name key.\n\nLink to Spring Cloud Config examples:\n\u003cbr\u003e\n[Set up spring cloud config server from scratch (YouTube/JavaBrains)](https://www.youtube.com/watch?v=gb1i4WyWNK4\u0026list=PLqq-6Pq4lTTaoaVoQVfRJPqvNTCjcTvJB\u0026index=11)\n\u003cbr\u003e\n[Setting up spring cloud config client (YouTube/JavaBrains)](https://www.youtube.com/watch?v=E2HkL766VHs\u0026list=PLqq-6Pq4lTTaoaVoQVfRJPqvNTCjcTvJB\u0026index=12)\n\u003cbr\u003e\n[Dynamic config with spring Boot (YouTube/JavaBrains)](https://www.youtube.com/watch?v=yNnLICy2zk4\u0026list=PLqq-6Pq4lTTaoaVoQVfRJPqvNTCjcTvJB\u0026index=13)\n\u003cbr\u003e\n\n## 8. Distributed Tracing\n\n![distributed-tracing](images/distributed-tracing.png)\n\nDistributed Tracing is the process of tracing every single request from the point of origin up to\nall the services it touches by analyzing the data.\nEvery request will have a Trace ID, timestamp, and other useful metadata.\n\n## 8.1 Implementation (Spring Cloud Sleuth \u0026 Zipkin)\n\n\u003cins\u003eSpring Cloud Sleuth\n\nSpring Cloud Sleuth allows you to aggregate and track log entries as requests move through a\ndistributed software system by adding trace and Span ID’s on the appropriate HTTP request headers.\n\n\u003cins\u003eZipkin\n\nZipkin is an open source project that provides mechanisms for sending, receiving, storing, and\nvisualizing traces. This allows us to correlate activity between servers and get a much clearer picture of\nexactly what is happening (by using the UI) in our services.\n\nLink to Sleuth \u0026 Zipkin examples:\n\u003cbr\u003e\n[Spring Boot Microservices Project Example - Part 7 | Distributed Tracing (YouTube/ProgrammingTechie)](https://www.youtube.com/watch?v=0TQliqoX6Kc\u0026list=PLSVW22jAG8pBnhAdq9S8BpLnZ0_jVBj0c\u0026index=7)\n\u003cbr\u003e\n\n## 9. Message Brokers / Queues\n\n![event-driven-microservices](images/event-driven-microservices.jpeg)\n\nEvent-driven architecture (EDA) is a software design pattern in which decoupled applications can asynchronously\npublish and subscribe to events via an event broker/message broker.\nIn an Event-Driven Architecture, applications communicate with each other by sending and/or receiving\nevents or messages.\n\n## 9.1 Implementation (Kafka, RabbitMQ)\n\n\u003cins\u003eKafka\n\nIn the above architecture, OrderService, StockService, and EmailService microservices are independent of each other.\nOrderService is a Producer application that sends an event to the Message Broker.\nStockService and EmailService are Consumers who will consume the events from the Message Broker.\n\nIn the links below, you can see how multiple consumers can subscribe to a single Kafka topic to\nconsume the events/messages.\n\nLink to Kafka examples:\n\u003cbr\u003e\n[Event-Driven Microservices using Spring Boot and Kafka (javaguides)](https://www.javaguides.net/2022/07/event-driven-microservices-using-spring-boot-and-apache-kafka.html)\n\u003cbr\u003e\n[Kafka Tutorial - Spring Boot Microservices (YouTube/AmigosCode)](https://www.youtube.com/watch?v=SqVfCyfCJqw)\n\n## B. Deploying Microservices\n\n\u003cins\u003eSummary of Steps:\n\nEnsure you are in the project directory for the Packaging and Docker steps, and that Docker is running and you are signed-in.\n\n1. Develop Spring Boot Application\n2. Package Application (mvn clean package)\n3. Build Docker Image (Dockerfile, docker-compose.yaml, Jib)\n4. Run Docker Image in Container (for testing, not necessary with k8s deployment)\n5. Push Docker Image to Docker Hub and move to Remote Repository (docker push)\n6. Start Kubernetes (minikube start)\n7. Create Kubernetes Deployment (deployment.yaml)\n8. Create Kubernetes Service (service.yaml)\n9. Run Deployment and Service (kubectl apply)\n10. View k8s Dashboard (minikube dashboard)\n\n[SpringBoot to Kubernetes in 15 minutes (YouTube/TEKE)](https://www.youtube.com/watch?v=aH1IwAPHe1w)\n\u003cbr\u003e\n[Deploy SpringBoot Microservices to Kubernetes Cluster (YouTube/DailyCodeBuffer)](https://www.youtube.com/watch?v=VAmntTPebKE\u0026t=408s)\n\u003cbr\u003e\n\n## 1. Packaging / Containerizing the Application\n\nOne question that a lot of beginning programmers have is: \"Now that I’ve created my application in the IDE,\nhow do I get it to work from the command line outside of the IDE.\" Similarly, someone might ask,\n\"How do I distribute this application to other users without having to give them the whole IDE as well?\"\n\nWe can package the application in the form of an executable JAR file.\n\nA JAR file is an archive file that can contain multiple files and folders.\nJAR files are similar to zip files, but JAR files can have additional attributes that are useful for\ndistributing Java applications. These attributes include digitally signing JAR files, additional compression,\nmultiplatform compatibility, etc.\n\nFirstly, we need to package our Java application into a jar file using the command:\n\n```shell\n$\u003e mvn clean package\n```\n\nThis will create an executable .jar file in the \"target\" folder.\nWe can even start the Spring Boot application with the command:\n\n```shell\n$\u003e java -jar target/\u003cjar-file-name\u003e.jar\n```\n\nNow that we have packaged the application, we can think about containerizing it with Docker.\n\n## 1.1 Docker\n\nDocker Commands: [Docker CLI Cheat Sheet (PDF)](docker_cheatsheet.pdf)\n\u003cbr\u003e\nInstalling Docker: [How to Install Docker on Mac (2022) (YouTube/AmitThinks)](https://www.youtube.com/watch?v=SGmFGYCuJK4)\n\u003cbr\u003e\n\nDocker is an open platform for building, running and shipping applications.\nIt allows developers to easily build and deploy applications in containers.\n\n![docker-vs-VM](images/docker-vs-VM.png)\n\n\u003cins\u003eBenefits of Docker include:\n\n- A Docker container image is a lightweight, standalone, executable package of software that includes everything needed to run an application.\n- As there is no OS involved, an application that operates in a container will behave the same in any container environment.\n- When compared with VM's, they take up less space, require less time to deploy and can handle more applications.\n- It can run on physical hardware, virtual hardware and on cloud.\n- Docker is used a lot for CI/CD workflows in the DevOps space.\n  It works well as part of its pipelines along with tools such as Jenkins.\n  These tools can save the new version as a Docker image, every time our source code is updated,\n  just tag it with an updated version number and push to Docker Hub, then deploy it to production automatically.\n\n![docker-flow](images/docker-flow.png)\n\n\u003cins\u003eWhat is an Image?\n\n- Docker image is a file used to execute code in a Docker Container.\n- Docker images act as a set of instructions to build a Docker container, like a template.\n- Contains the application code libraries, tools and everything needed to run your application.\n- From this template, we can run multiple instances of the image(s) in containers.\n\n\u003cins\u003eWhat is a Container?\n\n- A container is an isolated environment for running an application.\n- They contain everything your application needs\n- They are running instances of our application.\n- It is also the smallest deployable unit for Docker.\n- Multiple containers can be spun up from a single Docker image.\n- To compare it to OOP, you can think of a Docker Image as a Class, and a Container as an instance of that Class (Object).\n- This deployment is made easier with tools such as Jenkins, which is a platform for creating a Continuous Integration/Continuous Delivery (CI/CD) environment.\n\n## 1.1.1 Dockerfile\n\nYour packaged application code is converted to a Docker Image via a Dockerfile.\nA Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.\nTo dockerize an application, we first create a file named Dockerfile with the following content:\n\nDockerfile:\n\n```dockerfile\nFROM openjdk:11-jdk\nARG JAR_FILE=target/*.jar\nCOPY ${JAR_FILE} /app.jar\nENTRYPOINT [\"java\",\"-jar\",\"/app.jar\"]\n```\n\nanother example Dockerfile:\n\n```dockerfile\nFROM openjdk:8\nEXPOSE 8080\nADD target/springboot-k8s-demo.jar springboot-k8s-demo.jar\nENTRYPOINT [\"java\",\"-jar\",\"/springboot-k8s-demo.jar\"]\n```\n\nThese files contain the following information:\n\n- FROM: specifies the Parent Image from which you are building (the base image).\n- ARG: Defines the parameter name and defines its default value.\n- COPY: copies files from a local source location to a destination in the Docker container.\n- ADD: used to copy files/directories into a Docker image.\n- EXPOSE: tells Docker that a container listens for traffic on the specified port.\n- ENTRYPOINT: used to set executables that will always run when the container is initiated.\n\n\u003cins\u003eBuilding a Docker Image\n\nTo build an image from our Dockerfile, we have to run ‘docker build' in the command line.\n\n**Ensure Docker is running, you are logged in AND you are in the project directory**\n\nformat = docker build tag \u003crepository-name\u003e:\u003ctag-version\u003e directory\n\n```shell\n$\u003e docker build -t message-server:latest .\n```\n\nWe can check if the image is present in our docker local repository:\n\n```shell\n$\u003e docker images\n```\n\nFinally, we're able to run a container from our image by providing the image name and tag:\n\n```shell\n$\u003e docker run -p8887:8888 message-server:latest\n```\n\nThis will start our application in Docker, and we can access it from the host machine at\nlocalhost:8887/messages.\nHere it's important to define the port mapping, which maps a port on the host (8887) to the port\ninside Docker (8888).\nThis is the port we defined in the properties of the Spring Boot application.\n\nWe can view running containers or all containers with:\n\n```shell\n$\u003e docker ps\n$\u003e docker ps -a\n```\n\nNow that the Docker image has been created and is running in a container,\nwe can now deploy it on a Kubernetes cluster.\n\nMore Docker commands available at: [Docker CLI Cheat Sheet (PDF)](docker_cheatsheet.pdf)\n\n\u003cins\u003eLayered Jars in Docker\n\nWe can reduce the size of a docker image by splitting the application into layers.\nThis is done by modifying the Dockerfile to run a command that extracts and copies these application layers.\nWith this configuration, when we change our source code, we'll only rebuild the application layer.\nThe rest will remain cached.\n\nDockerfile.layered:\n\n```dockerfile\nFROM adoptopenjdk:11-jre-hotspot as builder\nWORKDIR extracted\nADD target/*.jar app.jar\nRUN java -Djarmode=layertools -jar app.jar extract\n\nFROM adoptopenjdk:11-jre-hotspot\nWORKDIR application\nCOPY --from=builder extracted/dependencies/ ./\nCOPY --from=builder extracted/spring-boot-loader/ ./\nCOPY --from=builder extracted/snapshot-dependencies/ ./\nCOPY --from=builder extracted/application/ ./\nEXPOSE 8080\nENTRYPOINT [\"java\", \"org.springframework.boot.loader.JarLauncher\"]\n```\n\nAs we have kept the original \"Dockerfile\" file from previous, instead of overwriting its contents\nwe can create an image from the new file \"Dockerfile.layered\".\nWhen building this new image however,\nwe must specify the filename in the command line so Docker does not by default automatically search for and build the \"Dockerfile\" file instead.\n\nTo build a docker image from a specified Dockerfile file:\n\n```shell\ndocker build -t arsy786/fcms-layered -f Dockerfile.layered .\n```\n\nWe can see the significant difference in size between the two images:\n\n![docker-image-size-comparison](images/docker-image-size-comparison.png)\n\n## 1.1.2 Docker Compose\n\nDocker commands and Dockerfiles are particularly suitable for creating individual containers.\nHowever, if we want to operate on a network of isolated applications, the container management quickly\nbecomes cluttered.\n\nTo solve this, Docker provides a tool named Docker Compose. This tool comes with its own build-file in\nYAML format, and is better suited for managing multiple containers.\n\nWithin the docker-compose.yaml file, we must configure all the docker containers for each service, image and db\nin the Microservice application. For example, Mongo, KeyCloak, Zookeeper \u0026 Kafka, KeyCloak \u0026 MySQL, Zipkin,\nEureka Server, and all SB apps need docker-compose configs.\n\nWe must also configure an application.properties for the Docker environment.\nSimilar to a DEV/PROD profile, to enable environment-specific configuration properties we need to add new application.properties files.\n\n- application-dev.properties\n- application-prod.properties\n- application-local.properties\n- application-test.properties\n- application-docker.properties\n\nNOTE: Can make use of Spring Cloud Config Server instead of trying to set up many properties files for each service.\n\nAn example of two applications running in different Docker containers,\nwe can combine the configuration for both services in one file called docker-compose.yaml:\n\n```yaml\nversion: \"2\"\nservices:\n  message-server:\n    container_name: message-server\n    build:\n      context: docker-message-server\n      dockerfile: Dockerfile\n    image: message-server:latest\n    ports:\n      - 18888:8888\n    networks:\n      - spring-cloud-network\n  product-server:\n    container_name: product-server\n    build:\n      context: docker-product-server\n      dockerfile: Dockerfile\n    image: product-server:latest\n    ports:\n      - 19999:9999\n    networks:\n      - spring-cloud-network\nnetworks:\n  spring-cloud-network:\n    driver: bridge\n```\n\nBefore we continue, you can check the build-file for syntax-errors:\n\n```shell\n$\u003e docker-compose config\n```\n\nThen we can build our images, create the defined containers, and start it in one command:\n\n```shell\n$\u003e docker-compose up --build\n```\n\nThis will start up the message-server and product-server in one go.\n\n## 1.1.3 Docker Hub\n\nDocker Hub is a cloud-based repository in which Docker users and partners create, test,\nstore and distribute container images. Through Docker Hub, a user can access public,\nopen source image repositories, as well as use a space to create their own private\nrepositories, automated build functions, webhooks and work groups.\n\nYou can pull and push Docker images to Docker Hub, all you need is a Docker account.\n\n\u003cins\u003ePull and run a container image from Docker Hub:\n\nto pull the image from Docker Hub:\n\n```shell\n$\u003e docker pull hello-world\n```\n\nto run the image locally:\n\n```shell\n$\u003e docker run hello-world\n```\n\n\u003cins\u003eBuild and push a container image to Docker Hub from your computer:\n\nStart by creating a Dockerfile to specify your application as shown previously:\n\nto build your Docker image:\n\n```shell\n$\u003e docker build -t \u003cyour_username\u003e/my-private-repo .\n```\n\nto test your Docker image locally:\n\n```shell\n$\u003e docker run \u003cyour_username\u003e/my-private-repo\n```\n\nto push your Docker image to Docker Hub:\n\n```shell\n$\u003e docker push \u003cyour_username\u003e/my-private-repo\n```\n\nNOTE: Ensure Docker is running on your machine and that you are logged in by running the command docker login.\n\n## 1.2 Jib\n\nJib is an open-source Java tool maintained by Google for building Docker images of Java applications.\nIt simplifies containerization since with it, we don't need to write a dockerfile.\nAnd actually, we don't even have to have docker installed to create and publish the docker images\nourselves.\n\nDocker build flow:\n![docker_build_flow](images/docker_build_flow.png)\nJib build flow:\n![jib_build_flow](images/jib_build_flow.png)\n\nJib organizes your application into distinct layers; dependencies, resources, and classes;\nand utilizes Docker image layer caching to keep builds fast by only rebuilding changes.\nJib's layer organization and small base image keeps overall image size small which improves performance and portability.\n\n\u003cins\u003eImplementation\n\n- Configuration for Jib is carried in pom.xml where aside from adding the plugins, you configure the image properties.\n- You must provide your Docker credentials in settings.xml file in Maven folder.\n- To use Jib must run the command: mvn compile jib:build\n- Posts image to DockerHub automatically.\n\nLink to Jib examples:\n\u003cbr\u003e\n[Dockerizing Spring Boot Apps using Google Jib (YouTube/JavaTechie)](https://www.youtube.com/watch?v=dKXx4O_GIyo)\n\u003cbr\u003e\n\n## 2. Managing the Application\n\n## 2.1 Kubernetes\n\nKubectl Commands: [Kubernetes Cheat Sheet (PDF)](Kubernetes-Cheat-Sheet.pdf)\n\u003cbr\u003e\nInstalling Kubernetes: [How to Install Kubernetes on Mac (YouTube/ResearchRocks)](https://www.youtube.com/watch?v=gFI8PI-gMqQ)\n\u003cbr\u003e\nWhat is Kubernetes? [Kubernetes in 5 mins (YouTube/VMwareCloudNativeApps)](https://www.youtube.com/watch?v=PH-2FfFD2PU)\n\u003cbr\u003e\nLink to: [Kubernetes 101: Pods, Nodes, Containers, and Clusters (medium/DanielSanche)](https://medium.com/google-cloud/kubernetes-101-pods-nodes-containers-and-clusters-c1509e409e16)\n\u003cbr\u003e\n\n\u003cins\u003eWhat is Kubernetes?\n\nKubernetes (also known as k8s or “kube”) is an open source container orchestration platform that\nautomates many of the manual processes involved in deploying, managing, and scaling\ncontainerized applications.\n\n![components-of-kubernetes](images/components-of-kubernetes.png)\n\n\u003cins\u003eWhat is a Kubernetes Cluster?\n\nWhen you deploy Kubernetes, you get a cluster.\n\nA Kubernetes cluster consists of a set of worker machines, called nodes, that run\ncontainerized applications. Every cluster has at least one worker node.\n\nThe worker node(s) host the Pods that are the components of the application workload.\nThe control plane manages the worker nodes and the Pods in the cluster.\nIn production environments, the control plane usually runs across multiple computers and\na cluster usually runs multiple nodes, providing fault-tolerance and high availability.\n\n\u003cins\u003eWhat is a Pod?\n\n![k8s-pod](images/k8s-pod.png)\n\nPods are the smallest, most basic deployable objects in Kubernetes.\nA Pod represents a single instance of a running process in your cluster.\nPods contain one or more containers, such as Docker containers.\nWhen a Pod runs multiple containers, the containers are managed as a single entity and share the Pod's resources.\n\n\u003cins\u003eWhat is a Volume?\n\nA Volume in Kubernetes represents a directory with data that is accessible across multiple containers in a Pod.\nThe container data in a Pod is deleted or lost when a container crashes or restarts, but when you use a volume,\nthe new container can pick up the data at the state before the container crashes\n\n\u003cins\u003eWhat is a Deployment?\n\nAlthough pods are the basic unit of computation in Kubernetes, they are not typically directly launched on a cluster.\nInstead, pods are usually managed by one more layer of abstraction: the deployment.\n\nA deployment’s primary purpose is to declare how many replicas of a pod should be running at a time.\nWhen a deployment is added to the cluster, it will automatically spin up the requested number of pods,\nand then monitor them. If a pod dies, the deployment will automatically re-create it.\n\nDeployments can also help to efficiently scale the number of replica pods, enable the rollout of updated code in a controlled manner, or roll back to an earlier deployment version if necessary.\n\nUsing a deployment, you don’t have to deal with pods manually. You can just declare the desired state of the system,\nand it will be managed for you automatically.\n\n## 2.1.1 Deployment\n\n[Run \u0026 Deploy Spring Boot Application in K8s Cluster using yaml configuration (medium/JavaTechie)](https://medium.com/@javatechie/kubernetes-tutorial-run-deploy-spring-boot-application-in-k8s-cluster-using-yaml-configuration-3b079154d232)\n\u003cbr\u003e\n\nNow that the Docker image is created, we can now deploy it on the Kubernetes cluster.\nNext steps to deploy this springboot-k8s-example docker image in to k8s cluster first we need to create deployment\nobject.\n\nThe best way to make a deployment in K8s is by preparing a YAML file, this file describes configuration about how the\napplication should run in k8s pod. Or in simple terms, with the help of this deployment configuration we are telling\nk8s to create instances of my spring boot application in k8s cluster.\n\nSo let’s define deployment specification. In the root project directory, create a new file named deployment.yaml\n(Note: you can give any name) and add the code snippet below:\n\n```yaml\napiVersion: apps/v1\nkind: Deployment # Kubernetes resource kind we are creating\nmetadata:\n  name: spring-boot-k8s\nspec:\n  selector:\n    matchLabels:\n      app: spring-boot-k8s\n  replicas: 2 # Number of replicas that will be created for this deployment\n  template:\n    metadata:\n      labels:\n        app: spring-boot-k8s\n    spec:\n      containers:\n        - name: spring-boot-k8s\n          image: springboot-k8s-example:1.0\n          # Image that will be used to containers in the cluster\n          imagePullPolicy: IfNotPresent\n          ports:\n            - containerPort: 8080\n# The port that the container is running on in the cluster\n```\n\nNow that we have created the Kubernetes deployment file, we can deploy it to the cluster. Execute the command below to deploy the application to the cluster.\n\n```shell\nkubectl apply -f deployment.yaml\n```\n\ncheck the deployment status\n\n```shell\nkubectl get deployments\n```\n\nNext since we mentioned replicas: 2 , kubernetes will create two pods/instance for our application, so first we can get pods information using\n\n```shell\nkubectl get pods\n```\n\nWe can see here status is running, let’s fetch the logs of running pods\n\n```shell\nkubectl logs podName\n```\n\nAnd now, you can check the Kubernetes Dashboard to see that your cluster is up and running as expected.\n\n```shell\nminikube dashboard\n```\n\n## 2.1.2 Service\n\nIn Kubernetes service plays the role of service discovery where it exposes our application outside the Kubernetes cluster as well as it act as Load balancer where it decides which pod should handle the request.\n\nIn the root project directory, create a new file named service.yaml (Note: you can give any name) and add the code snippet below.\n\n```yaml\napiVersion: v1 # Kubernetes API version\nkind: Service # Kubernetes resource kind we are creating\nmetadata: # Metadata of the resource kind we are creating\n  name: springboot-k8s-svc\nspec:\n  selector:\n    app: spring-boot-k8s\n  ports:\n    - protocol: \"TCP\"\n      port: 8080 # The port that the service is running on in the cluster\n      targetPort: 8080 # The port exposed by the service\n  type: NodePort # type of the service.\n```\n\nNow that we have created the service file, let’s expose our app to outside k8s cluster using command below\n\n```shell\nkubectl apply -f service.yaml\n```\n\n\u003cins\u003eService Types\n\nKubernetes supports 4 types of service:\n\n1. NodePort: here we expose our application to the node in which our PODs are running.\n2. ClusterIP: here our application is only accessible in the K8S private network and can’t be accessed from the outside world.\n3. LoadBalancer: the type that’s most used in production because we can have multiple instances running in different nodes inside the K8S cluster. to use this type we should route the traffic from the external IP address to the cluster network in order to deliver packets.\n4. No service type: used to statically expose a service. An example of that would be a database or a third-party service provider.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsy786%2Fspring-boot-microservices-2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farsy786%2Fspring-boot-microservices-2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsy786%2Fspring-boot-microservices-2/lists"}