Chapter 24 - Spring Microservices Flashcards

1
Q

Monolithic architecture

A

Negative features:
1) One major problem is that the application is overwhelmingly complex. It’s simply too large for any single developer to fully understand. As a result, fixing bugs and implementing new features correctly becomes difficult and time consuming. What’s more, this tends to be a downwards spiral. If the codebase is difficult to understand, then changes won’t be made correctly. You will end up with a monstrous, incomprehensible big ball of mud.

2) The larger the application, the longer the start‑up time is. If developers regularly have to restart the application server, then a large part of their day will be spent waiting around and their productivity will suffer.

3) Imagine you have a large e-commerce website like Amazon. If you need to update a small feature, such as changing the way product recommendations are displayed, you have to redeploy the entire website, not just the recommendation feature.

4) Monolithic applications can also be difficult to scale when different modules have conflicting resource requirements. For example, one module might implement CPU‑intensive image processing logic and would ideally be deployed in Amazon EC2 Compute Optimized instances. Another module might be an in‑memory database and best suited for EC2 Memory‑optimized instances. However, because these modules are deployed together you have to compromise on the choice of hardware.

5) all modules are running within the same process, a bug in any module, such as a memory leak, can potentially bring down the entire process

6) can’t rewrite whole code to another framework

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Solution of the Monotholic problems is?

A

Solutions with Microservices
Microservices architecture addresses these issues by breaking down the application into smaller, independent services. Each service can be developed, deployed, and scaled independently. For example, in the e-commerce scenario, the recommendation feature could be a separate microservice. Updating it wouldn’t require redeploying the entire website, leading to quicker and safer deployments.

Each service instance is a Docker container

Rather than sharing a single database schema with other services, each service has its own database schema.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Difference between microservices and SOA (Service oriented Architecture)

A

Key Differences
Service Granularity:

SOA: Larger, coarse-grained services.
Microservices: Smaller, fine-grained services.
Communication:

SOA: Often relies on ESBs with protocols like SOAP.
Microservices: Uses lightweight protocols like HTTP/REST and messaging queues.
Governance:

SOA: Centralized governance and management.
Microservices: Decentralized governance, with each service independently managed.
State Management:

SOA: Can be stateful.
Microservices: Preferably stateless, with external state management.
Deployment and Scaling:

SOA: Services are typically part of a larger, monolithic deployment unit, making independent scaling challenging.
Microservices: Each service can be independently deployed and scaled.
Flexibility and Agility:

SOA: Less flexible due to centralized control and larger service granularity.
Microservices: Highly flexible and agile, enabling continuous deployment and faster iterations.
Technology Stack:

SOA: More standardized, often using traditional enterprise technologies.
Microservices: Polyglot, allowing the use of diverse technologies best suited for each service.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Microservices Synchronous Communication

A

In synchronous communication, a predefined source service address required, where exactly to send the request, and BOTH the service (caller and callee) should be up and running at the moment. Though Protocol may be synchronous, I/O operation can be asynchronous where the client need not necessarily wait for the response. This is a difference in I/O and Protocol. The common request-response approach common to web API includes REST, GraphQL, and gRPC.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Microservices ASynchronous Communication

A

In the case of asynchronous communication, callers need not have the specific destination of the callee. Handling multiple consumers at a time becomes relatively easy (as services may add up consumers). Moreover, the message queues up if the receiving service is down & proceeds later when they are up. This is particularly important from the perspective of loose coupling, multi-service communication, and coping up with partial server failure. These are determining factors for inclining microservices towards Async communication. Asynchronous protocols like MQTT, STOMP, AMQP are handled by platforms like Apache Kafka Stream, RabbitMQ.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Message

A

A message is like a little package of information that is sent to a specific place. It contains instructions on what needs to be done. These messages are sent through different ways, like texting or emailing.

Imagine a message as a letter you send to a friend. The mailbox is like the queue where the letter waits until your friend reads it. Once your friend gets the letter, they react to it by responding or taking action.

In a message-driven system, it’s like having friends waiting for your letters. They stay ready to act when they receive your message, otherwise they wait quietly.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

event

A

Sure, here’s a simpler explanation:

An event is like a notification that something has happened. For example, when you order something online, an event might be created to show that the order was requested.

Listeners are like people who are waiting to hear about these events. They are connected to the sources of events and will be notified when an event occurs.

There are two main types of events:
1. Domain Events: These are events related to the business domain, like when an order is requested or when a credit is reserved. These events are important for understanding the history of what has happened in the business.
2. Change Events: These are events generated by the database to indicate a change in state, like when data is updated or deleted. These events are useful for tracking changes in the database.

example:
Interaction:

The OrderPlaced event triggers the InventoryUpdate event indirectly, as the inventory needs to be updated based on the items ordered.
The InventoryUpdate event does not directly interact with the OrderPlaced event, but it is a consequence of the order being placed.

Event streamers are tools that help manage these events. They store events in a durable and persistent way, ensuring that they are not lost even if something goes wrong. The processor, in this case, is like a traffic cop, simply routing the events to where they need to go. This approach avoids the need for complex integration platforms and allows the client or services to handle the logic related to these events.

Event streamers are durable, persistent, fault-tolerant without any idea of the consumers. In such a case the processor is dumb (in a sense it acts as a message router only) and the client/services own the domain-centric logic making dump processor and active clients. This avoids complex integration platforms such as ESB used in traditional SOA design.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

smart endpoints and dumb pipes VS dump processor and active clients

A

Smart Endpoints and Dumb Pipes
Smart Endpoints: In this context, “smart” endpoints refer to the microservices themselves. They are responsible for implementing the business logic and processing data.
Dumb Pipes: “Dumb” pipes refer to the communication channels between microservices. This means that the communication mechanisms (such as HTTP, messaging queues, etc.) should be simple and straightforward, without adding complexity or logic to them.
Implication: The idea is that instead of relying on complex middleware or communication frameworks to handle interactions between microservices, the focus should be on making the microservices themselves intelligent and capable of handling their own logic.

Dump Processor and Active Clients
Dump Processor: This seems like a typo and likely should be “Dumb Processor.” In this context, a “dumb processor” refers to a component that simply routes messages or events from one place to another without any understanding of the message’s content. It acts as a simple mediator, similar to a network switch that forwards packets without interpreting them.
Active Clients: “Active clients” refer to the microservices or clients that consume the events or messages. These clients are responsible for interpreting the messages and taking appropriate actions based on them.
Implication: This approach offloads the complexity of message processing from the middleware or processor to the clients, allowing for more flexibility and decentralization in the system architecture.

finally both are same!!!!!!

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Saga Pattern — Maintaining Atomicity Across Multiple Services

A

Distributed Transaction Scenario
Example: Consider an e-commerce application where placing an order involves checking the customer’s credit limit, verifying the item’s availability in inventory, and then processing the payment.
Challenge: A single ACID transaction is not feasible across these services due to their distributed nature.
Saga
Definition: A saga is a sequence of local transactions that together form a larger, coordinated transaction spanning multiple services.
Purpose: Ensures that the overall transaction is completed successfully or rolled back atomically.
Failure Handling: If any local transaction fails, a series of compensating transactions is executed to undo the changes made by preceding transactions, ensuring consistency.
Choreography-Based Saga
Concept: Participants (services) in the saga exchange events to coordinate their local transactions without a centralized controller.
Advantages: Decentralized control leads to simpler implementation and better scalability.
Example: After the order service places an order, it publishes an “OrderPlaced” event. The inventory service listens for this event and reserves the item. If successful, it publishes an “ItemReserved” event, which the payment service then listens for to process the payment.
Orchestration-Based Saga
Concept: A centralized controller (orchestrator) coordinates the saga by telling the participants what local transactions to execute.
Advantages: Provides a clear, centralized view of the saga’s progress and allows for easier monitoring and management.
Example: The orchestrator first tells the order service to place an order. Once done, it instructs the inventory service to reserve the item, and finally, it tells the payment service to process the payment.
Summary
Saga: A way to manage distributed transactions across multiple services.
Choreography-Based Saga: Participants communicate directly to coordinate transactions without a central controller.
Orchestration-Based Saga: A central controller coordinates the saga by instructing participants on what transactions to execute.

A saga is a sequence of local transactions that updates each service and publishes a message/event to trigger the next local transaction. In case of failure of any of the local transactions, saga executes series of compensating transactions that undo changes made by preceding local transactions thereby preserving atomicity.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Two-Phase Commit

A

Two-Phase Commit Protocol
Prepare Phase: All participants (services) in the transaction are asked to prepare to commit the transaction. This involves ensuring that they can commit the transaction if instructed to do so.
Commit Phase: If all participants are able to prepare successfully, a commit message is sent to all participants, instructing them to commit the transaction. If any participant fails to prepare, a rollback message is sent to all participants, instructing them to abort the transaction.

Limitations in Microservices Architecture
Synchronous Nature: The two-phase commit protocol is synchronous, meaning that all participants must be available and respond in a timely manner. In a microservices architecture with potentially many services, this can lead to performance issues and increased latency.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Retry Strategies

A

Retry – The source application can immediately retry to send the request to the service. If the specific fault is unusual or rare, the probability of success when repeating the request is very high.

Retry after a delay – The source application can retry to send the request to the cloud service after a period of time (that normally increases exponentially). This is a common practice when the failure event is due to reasons such as cloud service busy and so on.If the fault is caused by one of the more commonplace connectivity or busy failures, then the application has to wait for some time and try again.

Sliding Retry – The source application will retry repeatedly based on schedule and keeps adding an incremental delay in subsequent tries. For example, the retry logic may multiply the waiting period of 60 seconds by increment a try count from 1 to the number of tries and so on. This helps in reducing the overall number of retries.

Retry With Jitter – The sliding retry and the exponential backoff retry add a predictable sequence in their retry and backoff timelines. If there are multiple calls to the service at the same time and the same retry policy is applied then all the calls will retry and back off at the same time. To prevent this we need to add a certain randomness to the retry logic. This can be one by introducing a jitter to the retry policy. The jitter is a random calculation that results in different retry and backoff timelines for various calls.

Cancel – The source application can cancel the request to the cloud service and throw an exception. This is a common practice when the failure is not transient or is likely to be unsuccessful if repeated.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Retry Pattern

A

The retry pattern is an extremely important pattern to make applications and services more resilient to transient failures. A transient failure is a common type of failure in a cloud-based distributed architecture. This is often due to the nature of the network itself (loss of connectivity, timeout on requests, and so on). Transient faults occur when services are hosted separately and communicate over the wire, most likely over a HTTP protocol. These faults are expected to be short-lived. Repeating such a request that has previously failed could succeed on a subsequent attempt.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Testing Microservices:

A

Microservices are developed with business-oriented APIs to encapsulate core business capabilities, using the principle of loose coupling to minimize dependencies.
Testing microservices is different from testing monolithic systems due to the distributed nature of microservices architecture.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Why Test Microservices?:

A

Testing ensures peace of mind and helps avoid problems caused by a domino effect in a distributed environment with many moving parts.
In a system with multiple teams deploying multiple times a day, proper testing helps prevent side effects and substantial rollbacks.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

The Testing Pyramid:

A

Describes different types of tests and their coverage in a pyramid structure, with unit tests at the bottom (cheap, fast, and easy to develop) and end-to-end tests at the top (expensive, slow, and complex).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Microservices Testing Types:

A

Unit Testing: Ensures individual microservices’ business logic works correctly.
Integration Testing: Verifies communication paths and interactions between microservices.
Component Testing: Tests microservices in isolation, mocking other microservices.
Contract Testing: Validates the API contracts between microservices.
End-to-End Testing: Tests the entire system to verify it meets business goals.
Performance Testing: Evaluates the performance of microservices under load.
Examples: Spotify prefers integration testing, focusing on interaction points and making them explicit.

17
Q

Virtualization vs Containerization: 5 Main Differences

A

Virtual machines and containers are often confused but have distinct differences.
The right option depends on user needs.
Virtualization uses a hypervisor to create multiple virtual servers on a single physical server.
Each virtual server has its own OS, drivers, binaries, libraries, and applications.
Virtual machines are secure but resource-heavy and slow.

18
Q

Containerization

A

Containers encapsulate an application and its dependencies in its environment.
Containers run in isolation using the same system resources and OS as other containers.
Containers are lightweight and efficient, with each image being only a few megabytes in size.
Containers simplify maintenance and decrease hardware costs.
Containers are less secure than virtual machines and share the host OS.

19
Q

Virtualization vs Containerization Comparison

A

Virtualization is more secure and fully isolated, while containerization is less secure and isolated at the process level.
Virtualization is heavyweight with high resource usage, while containerization is lightweight with less resource usage.
Virtualization uses hardware-level virtualization, while containerization uses operating system virtualization.
Virtual machines run in their own operating system, while containers share the host operating system.
Virtual machines have startup times in minutes and slow provisioning, while containers have startup times in milliseconds and quicker provisioning.

20
Q

comntainerization

A

Containerization is an approach to software development where an application, its dependencies, and its environment configuration are packaged together as a container image. This image is then tested as a unit and deployed to a host operating system. Containers provide an isolated, resource-controlled, and portable operating environment for applications to run without affecting other containers or the host system.

Key Concepts:

Container Host: The machine that runs one or more containers.
Container Image: A snapshot of a containerized application and its dependencies. Images are used to create containers.
Container: A runtime instance of a container image.
Container OS Image: The base layer of an image that includes the operating system. It is immutable and cannot be modified.
Container Repository: Stores container images for reuse and distribution across container hosts.
Advantages:

Efficiency: Containers share the host operating system, reducing resource consumption compared to virtual machines.
Portability: Containers can be easily transferred and deployed across different environments.
Isolation: Each container runs as an isolated process, enhancing security and preventing interference between applications.
Scalability: Containers can be quickly instantiated and scaled to accommodate changing workloads.
Docker:

Docker is an open platform for developing, shipping, and running applications using containers.
It provides tools and a platform to manage the lifecycle of containers, from development to production deployment.
Docker enables developers to work in standardized environments, streamlining the development lifecycle and facilitating continuous integration and deployment workflows.
It allows for the efficient deployment and scaling of applications across different environments, including local, cloud, and hybrid environments.
Docker uses a client-server architecture, where the Docker client interacts with the Docker daemon to manage Docker objects such as images, containers, networks, and volumes.

21
Q

Fault tolerance

A

To make your microservices resilient, add fault tolerance strategies to your code. Resilient microservices can keep running even if part of the system fails. Fault tolerance helps by managing requests and providing backup plans for common errors. For instance, in an airline ticket app, various microservices handle scheduling, purchasing, and customer preferences. If one service fails, fault tolerance measures prevent it from affecting the entire app.

22
Q

MicroProfile fault tolerance

A

The MicroProfile Fault Tolerance feature defines a standard API to implement a set of fault tolerance policies. The policies that you implement in your code guide how long requests run, when they retry after an error, and what they do to recover when certain requests fail. MicroProfile Fault Tolerance makes it easy to build resilient microservices that provide reliable function, even when errors occur.
MicroProfile Fault Tolerance supports the following policies:

Timeouts
Retries
Fallbacks
Circuit Breakers
Bulkheads
Asynchronous

23
Q

timeouts

A

The Timeout policy is used to prevent a request from waiting indefinitely by setting a maximum time limit for its execution. If the request takes longer than this limit, the policy forcefully terminates the request, even if it would have otherwise completed successfully. This prevents the application from wasting resources on a service that is not responding in a timely manner.

24
Q

Retry

A

Retry
In some cases, the underlying causes of an error or delay are momentary. The Retry policy saves an operation from failing on a momentary error by trying the operation again and giving it another chance to succeed.
The Retry policy can be applied at either the class or method level. If it is applied to a class, all the methods in that class receive the same retry policy. If different retry policies are applied at a class level and at a method level within that class, the method level @Retry annotation overrides the class level policy for that particular method.

25
Q

Circuit Breaker

A

The circuit breaker policy prevents repeated failures by setting conditions under which an operation fails immediately. If these conditions are met, the circuit breaker opens and fails the operation, which prevents repeated calls that are likely to fail.
There are three possible circuit states that are set by the circuit breaker. The transition between these states is determined by how the failure condition parameters are configured on the @CircuitBreaker annotation.

Closed: Under normal conditions, the circuit breaker is closed, which allows operations to continue running.

Open: When the configured error conditions are met, the circuit breaker opens and calls to the service that is operating under the circuit breaker fail immediately.

Half-open: After the configured delay period, an open circuit moves to a half-open state. In this state, the circuit accepts a configured number of trial calls. If any of these calls fail, the circuit breaker returns to the open state. If the configured number of trial calls succeed, the circuit moves to the closed state, which resumes normal operations.

26
Q

Bulkhead

A

The Bulkhead policy prevents faults in one part of an application from cascading to the entire system and causing widespread failure. The @Bulkhead annotation limits the number of concurrent requests and saves an unresponsive service from wasting system resources.

27
Q
A