Microservices
9. How did you deploy your application?
(Answer: IntelliJ -> GitHub -> Github Actions/Jenkins -> Docker Hub -> Kubernetes -> AWS EC2/AWS EKS)
11. Describe your microservice architecture (candidates were asked to draw the architecture during the interview)
11. Describe your microservice architecture (candidates were asked to draw the architecture during the interview)
22. Tell me about your experience with Cloud Service. Ex. AWS, GCP, Azure
22. Tell me about your experience with Cloud Service. Ex. AWS, GCP, Azure
17. What is a dead letter exchange (DLX)?
A dead letter exchange (DLX) is an exchange in RabbitMQ that receives messages from other exchanges, which are not delivered to any queue and are rejected or expired. DLX can be configured to route these messages to a specific queue or exchange for further processing or analysis. The messages can be rejected due to various reasons, such as invalid format, invalid routing key, or lack of available resources.
2. What is cascading failure? How to prevent this failure?
Cascading failure is a failure that starts with one component in a system and then spreads throughout the system, causing multiple other components to fail. This can be especially dangerous in complex systems where multiple components are interconnected and dependent on one another. To prevent cascading failure, it is important to implement measures that can detect and isolate the root cause of a failure before it spreads to other components. Some techniques to prevent cascading failure include: Redundancy: Implementing redundancy by having multiple copies of critical components or services can help prevent cascading failures by allowing the system to switch to a backup copy in case of a failure. Isolation: Isolating critical components or services can help prevent cascading failures by limiting the impact of a failure to only a small part of the system. This can be achieved through techniques such as containerization, virtualization, or microservices. Monitoring: Implementing effective monitoring and alerting systems can help detect issues early on and prevent cascading failures. This can involve using monitoring tools to track performance metrics, detect anomalies, and generate alerts when thresholds are breached. Testing: Testing the system thoroughly can help identify potential issues and prevent cascading failures. This can involve testing for failure scenarios, testing for scalability, and testing for performance. Recovery: Implementing effective recovery strategies can help prevent cascading failures by allowing the system to recover quickly from failures. This can involve techniques such as automatic failover, automated backups, and disaster recovery planning.
12. How to debug your microservice? (In other words, how to troubleshoot when there is an error in the microservice application?)
Debugging microservices can be challenging due to their distributed nature and the possibility of complex interactions between different services. Here are some general steps you can take to debug a microservice: Reproduce the issue: Start by reproducing the issue in a local or test environment if possible. Use tools like Postman or curl to send requests to the service and observe the response. Check the logs: Most microservice frameworks provide logging capabilities that can help you understand the flow of requests through the system. Check the logs to see if there are any error messages or exceptions that might indicate the source of the issue. Use tracing tools: Distributed tracing tools like Zipkin or Jaeger can help you trace requests across multiple services and identify where the issue is occurring. These tools can provide insights into the overall flow of requests and the latency of each service. Debug the code: If the issue is related to the code, use a debugger to step through the code and identify the source of the issue. Most IDEs provide debugging capabilities that can be used to debug microservices. Use monitoring tools: Monitor the performance and health of your microservices using tools like Prometheus or Grafana. These tools can help you identify bottlenecks and performance issues. Collaborate with other teams: If the issue is related to a dependency or an external service, collaborate with the team responsible for that service to identify the source of the issue.
8. How many environments can your application have?
Development environment: This is where developers work on the application code and test their changes before committing them to the source code repository. Testing environment: This is where QA testers test the application to ensure it meets the requirements and works as expected. Staging environment: This is where the application is deployed for final testing before being released to production. Production environment: This is where the application runs live and serves actual users.
25. Explain distributed database management (2-phase commit, SAGA)
Distributed database management is a method of managing a database that is spread across multiple nodes or computers in a network. In this approach, the data is divided and stored on different nodes, and each node operates as an independent database server. This provides various benefits such as improved scalability, availability, and performance, as well as the ability to handle large volumes of data.
24.What is ELK? (Please look at the guide on the training portal under day 35) ELK stands for Elasticsearch, Logstash, and Kibana. It is a popular open-source software stack used for log analysis and management.
Elasticsearch: a distributed search and analytics engine that stores and indexes the logs, making it easy to search, analyze, and visualize the data. Logstash: a data processing pipeline that ingests and transforms the logs before sending them to Elasticsearch. Kibana: a web-based user interface that allows you to visualize and analyze the logs stored in Elasticsearch.
3. What is fault tolerance? How to make your microservice fault tolerance?
Fault tolerance refers to the ability of a system to continue functioning even when some of its components fail or malfunction. In the context of microservices, fault tolerance is essential because a microservice architecture is typically composed of many small, independent services that rely on each other to provide a cohesive system. To make your microservices fault tolerant, you can implement several strategies, including: Redundancy: Implementing redundant services can help ensure that there is always a backup available if one service fails. This can involve creating multiple copies of a service and distributing the load across them, or using load balancers to redirect traffic to healthy services. Circuit Breakers: Circuit breakers are a design pattern that allows microservices to gracefully handle failures. When a service fails, the circuit breaker can prevent further requests from being sent to that service, redirecting them to a fallback service instead. Timeouts: Setting timeouts for requests can help prevent failures from propagating through the system. If a service takes too long to respond, the request can be cancelled, preventing further delays. Graceful Degradation: Graceful degradation is the process of reducing the functionality of a service in the event of a failure. This can involve reducing the number of features or limiting the number of requests the service can handle to prevent overload. Resilient Communication: Implementing resilient communication patterns, such as retries and timeouts, can help ensure that services can communicate even in the event of network failures or other issues. Monitoring and Logging: Monitoring and logging are essential for detecting and diagnosing failures. By collecting data on system performance and errors, you can quickly identify issues and take action to resolve them.
13.The production support team reports that your application is running slow as the customer base becomes large, what can you do to increase the performance of your application? (async, caching, pagination)
If the production support team reports that the application is running slow as the customer base becomes large, there are several steps you can take to improve the performance of your application: Optimize your database: You can optimize your database by creating indexes, optimizing queries, and using caching mechanisms. Improve your code: Review your code for inefficiencies and bottlenecks. Look for areas where you can improve the code and optimize performance. Use caching: Caching can help reduce the number of requests to your database and speed up the response time of your application. Consider using tools like Redis or Memcached to cache frequently accessed data. Use a load balancer: A load balancer can distribute incoming traffic across multiple servers, preventing any single server from becoming overwhelmed. Scale horizontally: Consider scaling your application horizontally by adding more servers to your infrastructure. This will help you handle more traffic and improve performance. Optimize your server configuration: Make sure your server is properly configured to handle the load. This includes optimizing the server settings and tuning the operating system. Monitor your application: Set up monitoring tools to track the performance of your application in real-time. This will help you identify performance issues and take corrective action before they become critical. Use cloud services: Consider using cloud services like AWS, Azure, or Google Cloud to help scale your application quickly and easily. These services provide a variety of tools and services that can help you improve performance and scale your application.
10.Usage of Jenkins. (Please refer to the CI/CD guide on the training portal under day 35)
Jenkins is an open-source automation server that helps automate parts of the software development process. It can be used to automate tasks such as building, testing, and deploying applications. Here are some common use cases for Jenkins: Continuous Integration (CI): Jenkins can be used to build and test code changes every time they are committed to the source code repository. This ensures that any code changes are tested and validated quickly, reducing the risk of introducing bugs and other issues into the codebase. Continuous Delivery (CD): Jenkins can be used to automate the deployment of applications to various environments, such as staging and production, after they have passed the necessary tests and validations. Automated Testing: Jenkins can be used to run automated tests, including unit tests, integration tests, and functional tests, as part of the CI/CD pipeline. This helps ensure that any code changes do not break existing functionality. Code Quality Analysis: Jenkins can be used to analyze code quality metrics such as code coverage, code complexity, and code style violations. This helps identify areas of the code that may need improvement or refactoring. Reporting: Jenkins can be used to generate reports and visualizations that provide insights into the health and status of the software development process.
23.What is Kafka? (Please look at the pdf and demo code on the training portalunder day 35)
Kafka is a distributed streaming platform that is used for building real-time data pipelines and streaming applications. It is a publish-subscribe-based messaging system that is designed to be fast, scalable, and durable. Kafka is often used for processing large volumes of data in real-time and is particularly useful for use cases such as data ingestion, event processing, and analytics.
4. How do microservices communicate?
Microservices communicate with each other through various mechanisms, including: REST API: The most common way for microservices to communicate is via RESTful APIs. Each microservice exposes its own RESTful API, which can be called by other services. Message Queues: Microservices can also communicate via message queues such as RabbitMQ, Kafka, or AWS SQS. With this approach, each service publishes messages to a queue, and other services can subscribe to the queue to receive and process the messages. RPC: Remote Procedure Call (RPC) is another way for microservices to communicate. With this approach, a service can invoke a method on another service directly as if it was a local function call. Event-Driven: In an event-driven architecture, services communicate by publishing and subscribing to events. When an event occurs, such as a new order being created, a service can publish the event, and other services can subscribe to the event and respond accordingly.
6. How do you monitor your application?
Monitoring an application is an essential part of maintaining its reliability and performance. There are several ways to monitor an application, including: Logging: Logging is a simple way to monitor an application's behavior. Developers can use logging frameworks like Log4j, Logback, or Java Logging API to log events, errors, and other important information. This information can then be used to identify and debug issues in the application. Metrics: Metrics provide a way to measure the performance and health of an application. Developers can use metrics frameworks like Micrometer, Prometheus, or Dropwizard Metrics to capture and visualize metrics such as CPU usage, memory usage, response times, and error rates. Tracing: Tracing provides a way to follow a request as it flows through the application. Developers can use tracing frameworks like Zipkin, Jaeger, or OpenTelemetry to trace requests and identify bottlenecks and performance issues. Alerting: Alerting provides a way to notify developers and operations teams of issues in the application. Developers can use alerting tools like PagerDuty, OpsGenie, or VictorOps to set up alerts based on certain conditions, such as error rates or latency thresholds. APM: Application Performance Monitoring (APM) tools provide a comprehensive view of an application's performance and behavior. APM tools like New Relic, AppDynamics, or Dynatrace provide features like tracing, metrics, logging, and alerting, all in one platform.
15. What are the components of RabbitMQ? Describe the role of each component.
RabbitMQ is a message broker software that implements the Advanced Message Queuing Protocol (AMQP). It consists of several components that work together to facilitate message exchange between applications. Producer: A producer is an application that sends messages to RabbitMQ. It creates a message and sends it to an exchange. The exchange is responsible for routing messages to the correct queue based on the exchange type and routing key. Exchange: An exchange is responsible for receiving messages from producers and routing them to the appropriate queue(s). There are several types of exchanges, including direct, fanout, topic, and headers. Queue: A queue is a buffer that stores messages until they are consumed by a consumer. Messages are consumed in a first-in, first-out (FIFO) order. Consumers can subscribe to one or more queues and receive messages as they arrive. Consumer: A consumer is an application that receives messages from RabbitMQ. It subscribes to one or more queues and waits for messages to arrive. When a message arrives, the consumer retrieves it from the queue and processes it. Broker: A broker is the core component of RabbitMQ. It receives messages from producers, routes them to the appropriate queues, and delivers them to consumers. The broker also handles message acknowledgments, message persistence, and message redelivery. Virtual Host: A virtual host is a logical grouping of exchanges, queues, and bindings. It allows you to isolate resources and control access to them. Each virtual host has its own set of users, permissions, and policies. Binding: A binding is a relationship between an exchange and a queue. It specifies the routing key that the exchange should use to route messages to the queue.
14. What is RabbitMQ and what can it help us to achieve in a web application?
RabbitMQ is a message broker that allows various components of a web application to communicate asynchronously and reliably. It acts as a middleman between the sender and the receiver, ensuring that messages are delivered in a reliable and ordered manner. In a web application, RabbitMQ can help achieve various goals such as: Decoupling: RabbitMQ can decouple various components of a web application by enabling them to communicate with each other without knowing about each other's existence. This enables developers to build and maintain complex systems with ease. Scalability: RabbitMQ can help in scaling a web application by distributing workload across various components of the application. It allows adding new components to the application without affecting the existing components. Reliability: RabbitMQ ensures that messages are delivered in a reliable and ordered manner. It can also handle failures and retries, ensuring that messages are not lost. Asynchronous Processing: RabbitMQ allows for asynchronous processing of messages, which can help in improving the performance of a web application. It allows for parallel processing of tasks, which can lead to faster response times for users.
18. How to secure your endpoint? (In other words, How can you check if a HTTP call is valid in microservices?)
Securing your endpoints is crucial in web applications to protect sensitive data and prevent unauthorized access. Here are some ways to secure your endpoints: Authentication: Implement a robust authentication mechanism such as OAuth or JWT (JSON Web Tokens) to ensure that only authorized users can access the endpoint. Authorization: Use role-based access control (RBAC) or attribute-based access control (ABAC) to grant access to specific endpoints based on the user's role or attributes. HTTPS: Use HTTPS (Hypertext Transfer Protocol Secure) to encrypt the communication between the client and server, preventing eavesdropping and man-in-the-middle attacks. Input validation: Validate user input to prevent injection attacks such as SQL injection and cross-site scripting (XSS) attacks. Rate limiting: Implement rate-limiting to prevent malicious users from overwhelming the server with requests. Secure coding practices: Follow secure coding practices such as input sanitization, proper error handling, and avoiding hard-coded passwords to prevent vulnerabilities. Logging and monitoring: Implement logging and monitoring to detect and respond to security threats and anomalies in real-time.
5. How do you document your endpoints? What's the purpose of Swagger?
To document APIs and endpoints, developers often use API documentation tools such as Swagger, OpenAPI, and RAML. These tools provide a structured way to document endpoints and describe their input and output parameters, data types, and possible responses. Swagger, now known as OpenAPI, is an open-source toolset that allows developers to define, build, and document RESTful APIs. Swagger provides a standard way to describe APIs in a JSON or YAML format, which can be easily shared and understood by other developers. With Swagger, developers can generate interactive API documentation, client SDKs, and server stubs in multiple programming languages. The purpose of Swagger is to make it easy for developers to discover, understand, and consume APIs. Swagger provides a user-friendly interface that allows developers to explore and test APIs without having to read through extensive documentation. Additionally, Swagger provides a way for API providers to publish their APIs and make them discoverable by other developers.
20. How did you do user authorization in microservices
User authorization in microservices can be achieved using a variety of approaches depending on the specific use case and security requirements of the system. Some common techniques include: JWT (JSON Web Tokens): This is a token-based authentication and authorization method where a token is issued to the user after they have successfully authenticated. The token contains user information and can be used to authorize subsequent requests. OAuth 2.0: This is a widely used authorization framework that allows applications to access user resources on other servers. OAuth 2.0 involves multiple steps including obtaining an access token, which can be used to authorize subsequent requests. Role-based access control (RBAC): This approach involves assigning users specific roles and permissions based on their level of access. The user's role determines which endpoints they can access and what actions they can perform. API Gateway: An API gateway can act as a front door to your microservices, allowing you to authenticate and authorize users before they can access the services. The API gateway can also perform other tasks such as routing and rate limiting.
21.Vertical Scaling and Horizontal scaling in your application
Vertical scaling, also known as scaling up, involves adding more resources to a single server or machine, such as increasing the amount of RAM, CPU, or storage capacity. This approach is usually more expensive, as it requires purchasing more powerful hardware, but can be easier to implement. Horizontal scaling, also known as scaling out, involves adding more servers or machines to the system, spreading the workload across multiple instances. This approach is more cost-effective, as it does not require expensive hardware upgrades, but can be more complex to implement and requires proper load balancing.
19. Where do you store your configuration file when you use microservices?
When using microservices, it is common to store configuration files in a centralized configuration server. This allows for centralized management of configurations and easy updates without requiring redeployment of individual microservices. Some popular tools for managing centralized configurations in a microservices architecture include Spring Cloud Config and HashiCorp Consul. Additionally, some cloud platforms such as AWS offer their own configuration management services such as AWS Systems Manager Parameter Store.
7. What is the gateway and is it necessary?
a gateway is a piece of software that sits between clients and the microservices that they need to interact with. The primary role of the gateway is to provide a single entry point for clients, as opposed to having them interact directly with each microservice individually. While a gateway is not strictly necessary in a microservices architecture, it can provide several benefits. By providing a single entry point for clients, the gateway simplifies the client-side code and can improve security and performance. Additionally, the gateway can provide a centralized location for managing API-related tasks, such as authentication, rate limiting, and analytics.
1. Difference between Monolithic vs. Microservice
a. Advantages and disadvantages of Monoliths vs Microservices Advantages of Monoliths: Simpler Development: Monolithic applications are simpler to develop since all the code is in one codebase. Easier Debugging: With monoliths, there's only one place to look for bugs. Faster Deployment: Deploying a monolith application is often quicker since there are fewer moving parts. Fewer Dependencies: Monoliths have fewer dependencies than microservices. Disadvantages of Monoliths: Limited Scalability: Monoliths can be difficult to scale horizontally since all the components are tightly coupled. Risk of Downtime: If one component fails, it can take down the entire application. Long Development Cycles: It can take a long time to make changes to a monolithic application due to its size and complexity. Advantages of Microservices: Scalability: Microservices can be scaled horizontally, allowing for better performance and scalability. Resilience: If one component fails, it doesn't necessarily take down the entire application since each service is independent. Flexibility: Microservices allow for greater flexibility since each service can be developed and deployed independently. Easier Maintenance: Microservices are easier to maintain since each service is smaller and more focused. Disadvantages of Microservices: Increased Complexity: Microservices are more complex to develop and manage due to their distributed nature. Distributed Transactions: Transactions that span multiple services can be difficult to manage and implement. Network Latency: There can be network latency issues when services communicate with each other over a network. Higher Overhead: Microservices have higher operational overhead due to the increased number of services and infrastructure required. Overall, the choice between monoliths and microservices depends on the specific requirements and constraints of the application being developed. Monoliths may be suitable for smaller applications with simpler requirements, while microservices may be more appropriate for larger, complex applications that require greater scalability and flexibility.
16. What are different types of exchanges that exist in RabbitMQ? Explain each Exchange.
n RabbitMQ, there are four types of exchanges: Direct Exchange: A direct exchange routes messages to queues based on a message routing key. The routing key is specified by the producer when the message is published. The message is then delivered to the queue whose binding key matches the message routing key exactly. Direct exchange is ideal for point-to-point messaging scenarios. Fanout Exchange: A fanout exchange routes messages to all queues that are bound to it. The routing key is ignored in fanout exchange, and the message is delivered to all queues that are bound to the exchange. Fanout exchange is useful in broadcast scenarios, where a message needs to be delivered to multiple recipients. Topic Exchange: A topic exchange routes messages based on the routing key pattern that is specified in the binding between the exchange and the queue. The routing key can contain wildcards to match multiple routing keys. Topic exchange is useful in scenarios where a message needs to be delivered to specific recipients based on the content of the message. Headers Exchange: A headers exchange routes messages based on the message header attributes instead of the routing key. In this type of exchange, the message is matched to the queue if the headers in the message match the headers specified in the binding between the exchange and the queue. This type of exchange is useful in scenarios where the content of the message is complex and requires detailed matching based on message header attributes.