Modiji_Microservices Interview Questions
Modiji_Microservices Interview Questions
Microservices architecture is a popular architectural style that breaks down a large application into
smaller, independent services. This approach offers several benefits, including improved scalability,
flexibility, and maintainability.
Example: In an e-commerce application, you might have separate microservices for product
catalog, user authentication, order processing, and payment processing.
Benefit: Each service can be developed, deployed, and scaled independently, allowing for faster
development and deployment cycles.
2. Loose Coupling:
Example: The product catalog service might not need to know the internal implementation
details of the order processing service. They communicate through well-defined APIs.
Benefit: Changes to one service have minimal impact on others, reducing the risk of cascading
failures.
Example: A banking application might have microservices for accounts, loans, and transactions,
each responsible for a specific business domain.
Benefit: Aligning services with business capabilities improves team autonomy and focus.
4. Distributed Governance:
Example: Different teams can use different technologies and programming languages for their
microservices.
Benefit: Teams can choose the best tools for the job, leading to increased innovation and
productivity.
Example: Each microservice can have its own database, tailored to its specific needs.
Benefit: This allows for flexibility in data storage and retrieval, and avoids vendor lock-in.
6. API-First Design:
Benefit: This promotes clear boundaries between services and enables easier integration with
other systems.
7. Continuous Delivery:
Example: Each microservice can be deployed independently, allowing for frequent releases and
faster time to market.
8. Fault Isolation:
Example: If one microservice fails, it doesn't necessarily bring down the entire application.
9. Scalability:
Example: You can scale individual microservices independently, based on their specific needs.
Benefit: This allows for efficient resource utilization and cost optimization.
By understanding these key features and applying them effectively, you can build robust, scalable, and
maintainable microservices applications.
Decoupling – Services within a system are largely decoupled. So the application
as a whole can be easily built, altered, and scaled
Componentization – Microservices are treated as independent components that
can be easily replaced and upgraded
Business Capabilities – Microservices are very simple and focus on a single
capability
Autonomy – Developers and teams can work independently of each other, thus
increasing speed
Continous Delivery – Allows frequent releases of software, through systematic
automation of software creation, testing, and approval
Responsibility – Microservices do not focus on applications as projects. Instead,
they treat applications as products for which they are responsible
Decentralized Governance – The focus is on using the right tool for the right
job. That means there is no standardized pattern or any technology
pattern. Developers have the freedom to choose the best useful tools to solve
their problems
Agility – Microservices support agile development. Any new feature can be
quickly developed and discarded again
These are less stable then monolithic services because in monolithic services we deploy single
services over sever and check the configuration for that one only, but here we have number of
independent services and each dependent service will have to be check before testing can
occur.
Here we have separate data store for each service so it would be very difficult to maintain
transactions here.
These can be less secure compared to monolithic services because services communicate with
each other which gives the chance to hackers to penetrate the system.
Here we can see that we have clubbed search, payments & Ratings components into a single application
means the code for all these functionalities are on the same server. Now the problem is if we have to
enhance the performance of search module then we can’t deploy it independently on multiple servers,
we have to deploy whole application on each server.
Microservices Monolithic Architecture
Every unit of the entire application should be the A single code base for all business goals
smallest, and it should be able to deliver one
specific business goal.
Fault isolation is easy. Even if one service goes Fault isolation is difficult. If any specific feature is
down, other can continue to function. not working, the complete system goes down. In
order to handle this issue, the application needs
to re-built, re-tested and also re-deployed.
Businesses can deploy more resources to Since services are not isolated, individual
services that are generating higher ROI resource allocation not possible
Microservices always remains consistent and Development tools get overburdened as the
continuously available. process needs to start from the scratch.
Small Focused Teams. Parallel and faster Large team and considerable team management
development effort is required
Change in the data model of one Microservice Change in data model affects the entire database
does not affect other Microservices.
Interacts with other microservices by using well- Not applicable
defined interfaces
Microservices work on the principle that focuses Put emphasize on the entire project
on products, not projects
Multiple Service Instance per Host: Run single or multiple service instances of
the application on single/multiple physical/virtual hosts.
Service Instance per Host: Run a service instance per host.
Service Instance per Container: Run each service instance in its respective
container.
Serverless Deployment: Create serverless functions on Azure.
What is the difference between Monolithic, SOA and Microservices Architecture?
Every unit of the entire application should be the A single code base for all business goals
smallest, and it should be able to deliver one
specific business goal.
Fault isolation is easy. Even if one service goes Fault isolation is difficult. If any specific feature is
down, other can continue to function. not working, the complete system goes down. In
order to handle this issue, the application needs
to re-built, re-tested and also re-deployed.
Businesses can deploy more resources to Since services are not isolated, individual
services that are generating higher ROI resource allocation not possible
Microservices always remains consistent and Development tools get overburdened as the
continuously available. process needs to start from the scratch.
Small Focused Teams. Parallel and faster Large team and considerable team management
development effort is required
Change in the data model of one Microservice Change in data model affects the entire
does not affect other Microservices. database
Microservices work on the principle that focuses Put emphasize on the entire project
on products, not projects
Design type In SOA, software components are Micro Service is a part of SOA. It is an
exposed to the outer world for usage in implementation of SOA.
the form of services.
Dependency Business units are dependent. They are independent of each other.
Size of the Software size is larger than any The size of the Software is always
Software conventional software small in Microservices
Technology The technology stack is lower compared Microservice technology stack could
Stack to Microservice. be very large
Independent and SOA applications are built to perform They are built to perform a single
Focus multiple business tasks. business task.
Business logic Business logic components are stored Business logic can live across
inside of single service domain Simple domains enterprise Service Bus like
wire protocols(HTTP with XML JSON) layers between services Middleware
API is driven with SDKs/Clients
What are the challenges you face while working Microservice Architectures?
Developing a number of smaller microservices sounds easy, but the challenges often
faced while developing them are as follows.
Automate the Components: Difficult to automate because there are a number
of smaller components. So for each component, we have to follow the stages of
Build, Deploy and, Monitor.
Perceptibility: Maintaining a large number of components together becomes
difficult to deploy, maintain, monitor and identify problems. It requires great
perceptibility around all the components.
Configuration Management: Maintaining the configurations for the components
across the various environments becomes tough sometimes.
Debugging: Difficult to find out each and every service for an error. It is essential
to maintain centralized logging and dashboards to debug problems.
There are 3 main decision one must take while deciding to go with microservices architecture pattern.
We should be opting for monolith only or first approach in the following circumstances:
1. Business is not ready to invest in the upfront cost that microservices based applications incur.
2. Inability for business to foresee the value provided by the microservices first approach.
3. Unavailability of suitable manpower to build and run microservices-based applications.
4. Software delivery with tight time constraints: Sometimes monolith helps in entering the market
very quickly.
5. When state of tools and technologies available to support smooth deployment of microservices
application, is a concern.
When to use microservices instead of monolith?
Cohesion – measurement of how the elements inside a module belong to each other.
A good design is always said to have High Cohesion and Low Coupling. When loosely
coupled, a service knows very little about other. This keeps the services intact. In high cohesion,
it becomes possible to keep all the related logic in a service. Otherwise, the services will try to
communicate with each other, impacting the overall performance.
For e.g.
Coupling – a class is dependent on an interface without knowing its actual implementation is the
example of low coupling. Or one microservice can communicate with other without knowing
what exactly happens in that api.
Cohesion – a class for e.g. a shoppingcart class is capable enough to perform all the operations
related to the adding, deleting, updating items in the cart is an example of cohesion. Or A
microservice written for shopping cart should have all the functionalities related to shopping cart
otherwise it will look for other apis to do some of the tasks.
In layman terms, you can say that end to end testing is a kind of tests where everything
is tested after a particular period.
The Server-Side Discovery Pattern – Here client makes request to the load balancer and then it routes
the request to the available instances. If we have multiple instances of a service then load balancer keep
information of all the running instances and keep them in service registry, as soon as request arrives to
load balancer it sends the request to appropriate instance of service. For eg. Azure load balancer
The Client Side Discovery pattern – the client is responsible for determining the network locations of
available service instances and load balancing requests across them. The client queries a service registry,
which is a database of available service instances. The client then uses a load-balancing algorithm to
select one of the available service instances and makes a request. For eg. We can use eureka or consul
as a service registry database. Whenever a new instance of the application is created, application itself
register to the consul and share it network location to it. Consul store the network location against the
instance. Now client will send request to the consul and it will return any one running instance of the
particular service. Then client sends the request to the same service instance. Consul also keep track of
inactive instances.
Client side discovery pattern is more cost effective as compared to server side pattern, because here we
don’t need to pay for load balancer applied to each service. For e.g. if we have application having 5
different services and each service has 10 running instances, it means we will need atleast 5 load
balancer one for each service. Load balancer is a paid service for which we have to pay to the service
provider, this cost can be waived off if we use client side discovery pattern.
-------------Raj---
In microservices architecture, service discovery is a crucial mechanism that enables services to locate
and communicate with each other. It addresses the dynamic nature of microservices, where services can
be added, removed, or scaled without impacting the overall system.
There are primarily two approaches to service discovery: server-side and client-side. Let's delve into the
key differences and considerations for each:
Centralized Registry: A central registry maintains information about all services, including their
addresses and health status.
Load Balancer: A load balancer acts as an intermediary, querying the registry to route incoming
requests to available service instances.
Client Simplicity: Clients interact with the load balancer, simplifying their implementation and
reducing complexity.
Centralized Control: The load balancer can implement advanced load-balancing strategies, such
as round-robin, least connections, or weighted load balancing.
Potential Bottleneck: The load balancer can become a single point of failure, impacting overall
system performance.
Distributed Registry: Service instances register themselves with a distributed registry, which can
be a centralized service or a distributed system like Consul or ZooKeeper.
Client Responsibility: Clients query the registry to obtain the addresses of services they need to
communicate with.
Flexibility: Clients can implement custom load-balancing strategies and fault tolerance
mechanisms.
Distributed Control: The discovery process is distributed across multiple clients, reducing the
risk of a single point of failure.
Increased Complexity: Clients need to implement logic for service discovery, which can add
complexity to the application code.
The choice between server-side and client-side service discovery depends on several factors:
Control: Client-side discovery offers more flexibility and control over load balancing and fault
tolerance.
Scalability: Both approaches can be scaled effectively, but server-side discovery might require
careful configuration of the load balancer.
Security: Consider the security implications of exposing service registries and load balancers.
-----------------------------------------------------------------
For message brokers, RabbitMQ, Nats, Kafka, etc., can be used, each built for a
particular message semantic. Another way is to use Backend As A Service like Space
Cloud, which automates the entire backend.
After an order is placed on an e-commerce website, the user is provided with an order
ID. This order ID once generated contains all the information regarding the order. As a
microservice, the order ID is the only source for any information regarding the order
service. So, if any other service seeks information regarding the order service, the order
ID acts as the source of information rather than its actual attributes.
4. API Integration
Breaking down the monolithic design into multiple services means these services will
coordinate and work together to form the system. But, how do these services
communicate? Imagine using multiple technologies to create different services. How do
they relate to each other?
Well, the simple answer would be the use of an API (Application Programming
Interface). The fundamental of microservice design is using the correct API. This is
crucial to maintaining communication between the service and the client calls. Easy
transition and execution are important for proper functioning.
6. Traffic Management
Once the APIs have been set and the system is up and running, traffic to different
services will vary. The traffic is the calls sent to specific services by the client. In the real
world scenario, a service may run slowly, thus, causing calls to take more time. Or a
service may be flooded with calls. In both the cases, the performance will be affected
even causing a software or hardware crash.
This high traffic demand needs management. A specific way of calling and being called
is the answer to a smooth flow of traffic. The services should be able to terminate any
such instances which cause delay and affect the performance.
This can also be achieved using a process known as ‘auto-scaling’ which includes
constant tracking of services with prompt action whenever required. In some cases, a
‘circuit breaker pattern’ is important to supply whatever incomplete information is
available in case of a broken call or an unresponsive service.
7. Constant Monitoring
Imagine breaking down a monolithic architecture into a microservice design. This needs
a lot of time and resources. It is not easy to monitor all the changes made with the help
of traditional tools. The insertion of data layers and caching increases performance but
makes it difficult to monitor the entire process.
public
interface
IMessageServi
ce
{
Task<string> GetHelloMessage();
Task<string> GetGoodbyeMessage();
}
public class MessageService : IMessageService
{
private IMessageRepository _messageRepository;
private AsyncRetryPolicy _retryPolicy;
private AsyncCircuitBreakerPolicy _circuitBreakerPolicy;
_circuitBreakerPolicy = Policy.Handle<Exception>()
.CircuitBreakerAsync(1, TimeSpan.FromMinutes(1),
(ex, t) =>
{
Console.WriteLine("Circuit broken!");
},
() =>
{
Console.WriteLine("Circuit Reset!");
});
}
In above code we are using both approaches (1) Retry policy (2) Circuit breaker
In retry policy we are giving the value like how many times the repository method should be invoked
if it gives Exception. Here we can give custom exception class so that retry should happen if we get
exception of that particular type only. If our application gets the response before maximum retries
then no more retry would happen. If we still get the exception after maximum retries then application
will throw exception.
Circuit-breaker Policies
In circuit breaker we define the value like after how many consecutives exception circuit should be
breaked and the duration for which circuit should be breaked.
If any further request comes during that period then circuit breaker will give
the message that “The circuit is now open and is not allowing calls.
“.
Lets see a example where we are doing both retry and circuit break.
//ConfigureServices() - Startup.cs
services.AddHttpClient<IBasketService, BasketService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes
.AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>()
.AddPolicyHandler(GetRetryPolicy())
.AddPolicyHandler(GetCircuitBreakerPolicy());
n the code example above, the circuit breaker policy is configured so it breaks or
opens the circuit when there have been five consecutive faults when retrying the
Http requests. When that happens, the circuit will break for 30 seconds: in that
period, calls will be failed immediately by the circuit-breaker rather than actually be
placed. The policy automatically interprets relevant exceptions and HTTP status
codes as faults.
//…
try
return View(vm);
catch (BrokenCircuitException)
{
// Catches error when Basket.api is in circuit-opened mode
HandleBrokenCircuitException();
return View();
}
using Polly;
// ...
.Handle<Exception>()
await Task.Delay(1000);
});
The Policy.Handle<Exception>() part specifies that the policy should handle any exceptions.
using Polly.CircuitBreaker;
// ...
.Handle<Exception>()
.CircuitBreakerAsync(3, TimeSpan.FromMinutes(5));
await circuitBreakerPolicy.ExecuteAsync(async () =>
await Task.Delay(1000);
});
Microservices Pattern
To effectively build and manage microservices in .NET Core, you should focus on the following key areas:
Core Concepts
1. Microservices Architecture:
2. RESTful APIs:
o Master the design and implementation of RESTful APIs using ASP.NET Core.
o Grasp concepts like HTTP methods, status codes, and content negotiation.
3. API Gateways:
o Explore API gateways like Ocelot or Kong to route requests, handle authentication, and
rate limiting.
4. Service Discovery:
o Learn about different load balancing techniques (round-robin, least connections, etc.).
7. Retry Pattern:
8. Rate Limiting:
1. ASP.NET Core:
o Master the fundamentals of ASP.NET Core, including MVC and Web API.
2. gRPC:
3. Message Queues:
o Use message queues like RabbitMQ or Azure Service Bus for asynchronous
communication.
4. Distributed Tracing:
o Implement distributed tracing tools like Jaeger or Zipkin to monitor and troubleshoot
microservices.
5. Configuration Management:
7. Security:
By mastering these concepts and technologies, you'll be well-equipped to build scalable, resilient, and
maintainable microservices applications in .NET Core.
Would you like to delve deeper into a specific topic or have any other questions?
Service Boundaries
Service boundaries are crucial in microservices architecture as they define the scope and responsibilities
of each individual service.
If we have clear boundaries of each microserive then we can easily scale,independent deploy,fault
tolerant,Technology diversity
1)Domain driven development 2)Single responsibility principle 3) High Cohesion, Low Coupling
Consider an e-commerce application. We can define the following microservices with clear boundaries:
User Service:
Recommendation Service:
Additional Considerations:
Evolutionary Design: Start with a simple design and evolve your microservices architecture as your
application grows.
1. Service Boundaries
o Bounded Context: A specific context within a domain where a particular language and
set of terms apply.
o Domain Model: A conceptual model of the domain, representing entities, value objects,
and aggregates.
Example:
o E-commerce Domain:
3. Bounded Contexts
Definition: A specific context within a domain where a particular language and set of terms
apply.
Example:
Product Catalog: Might focus on product attributes like color, size, and material.
Service Boundaries are often aligned with Bounded Contexts. Each Bounded Context can
typically be implemented as a separate microservice.
Domain-Driven Design helps define the Bounded Contexts and the Ubiquitous Language used
within each context.
Well-defined Service Boundaries ensure that microservices are loosely coupled and can evolve
independently.
Reduced Complexity: Breaking down a large, complex system into smaller, manageable parts.
By understanding and applying these concepts, you can design microservices that are well-structured,
maintainable, and scalable.
In a microservices architecture, the Order Processing and Payment Processing services often work in
tandem to complete a purchase. The Order Processing service initiates the order, while the Payment
Processing service handles the financial transaction.
Communication Mechanisms
Several strategies can be employed to facilitate communication between these two services:
1. RESTful API:
Direct Request-Response:
o The Order Processing service sends an HTTP request to the Payment Processing service,
providing order details, payment information, and other relevant data.
o The Payment Processing service processes the payment and sends an HTTP response
indicating success or failure.
2. Message Queues:
Asynchronous Communication:
o The Order Processing service sends a message to a message queue containing order
details.
o The Payment Processing service consumes the message and processes the payment.
o This approach decouples the services and allows for asynchronous processing,
improving scalability and reliability.
3. Event-Driven Architecture:
Event-Based Communication:
o The Order Processing service emits an event (e.g., "Order Placed") when an order is
created.
o The Payment Processing service subscribes to this event and triggers the payment
process.
Security:
Reliability:
o Implement retry mechanisms and circuit breakers to handle failures and ensure reliable
communication.
Performance:
Scalability:
o Design the communication layer to handle increasing load and scale horizontally.
Error Handling:
o Implement robust error handling and logging to identify and resolve issues.
Performance requirements: Real-time processing might favor synchronous RESTful APIs, while
asynchronous processing might be better for batch jobs.
Reliability: Message queues and event-driven architectures can improve reliability by
decoupling services.
Security: Strong security measures are essential for payment processing, especially when using
RESTful APIs.
By carefully considering these factors, you can design a reliable and efficient communication strategy
between your Order Processing and Payment Processing microservices.
Flexible Routing: It provides flexible routing mechanisms, allowing messages to be routed to different
consumers based on various criteria.