Friday, December 27, 2019

Basic Microservices Interview Questions

What are microservices and why would someone want to look at implementing it.
Microservices is an architectural style which structures and application as a collection of loosely coupled, independently maintainable, testable and deployable services which are organized around business capabilities. 
If you have a business focus and you want to solve a use case or a problem efficiently without the boundaries of technology, want to scale an independent service infinitely, highly available stateless services which are easy to maintainable and managed as well as independently testable then we would go ahead and implement Microservices architecture.

When should one consider microservices kind of architecture?
There are two cases.
i) If you already have a monolith application and it grows to an extent where there are problems in scaling or we are not able to reutilize the components/modules/services across different projects/platforms and there is a need to do so. As well as at the same time implementing new features is painful and more error-prone and it is difficult to scale further.

ii) For new applications where implementation has not started yet started, we can think of a business case to be efficiently implemented, which can be easily maintainable, testable and scalable in the future and might be used across other projects/products/platforms at the same time.

List down the advantages of Microservices Architecture?
Advantage
Description
Independent Development
All microservices can be easily developed based on their individual functionality
Independent Deployment
Based on their services, they can be individually deployed in any application
Fault Isolation
Even if one service of the application does not work, the system still continues to function
Mixed Technology Stack
Different languages and technologies can be used to build different services of the same application
Granular Scaling
Individual components can scale as per need, there is no need to scale all components together


 What is the difference between Monolithic, SOA and Microservices Architecture?


  • Monolithic Architecture is similar to a big container wherein all the software components of an application are assembled together and tightly packaged.
  • Service-Oriented Architecture is a collection of services which communicate with each other. The communication can involve either simple data passing or it could involve two or more services coordinating some activity.
  • Microservice Architecture is an architectural style that structures an application as a collection of small autonomous services, modeled around a business domain.

Microservices Challenges

  • Difficult to achieve strong consistency across services
  • ACID transactions do not span multiple processes.
  • Distributed System so hard to debug and trace the issues
  • Greater need for an end to end testing
  • Required cultural changes in across teams like Dev and Ops working together even in the same team.
What is Domain Driven Design?



Why there is a need for Domain Driven Design (DDD)?




What is Ubiquitous language?
If you have to define the Ubiquitous Language (UL), then it is a common language used by developers and users of a specific domain through which the domain can be explained easily.
The ubiquitous language has to be crystal clear so that it brings all the team members on the same page and also translates in such a way that a machine can understand.

What is Cohesion?
The degree to which the elements inside a module belong together is said to be cohesion.

What is Coupling?
The measure of the strength of the dependencies between components is said to be coupling. A good design is always said to have High Cohesion and Low Coupling.

What is Bounded Context?
Bounded Context is a central pattern in Domain-Driven Design. It is the focus of DDD’s strategic design section which is all about dealing with large models and teams. DDD deals with large models by dividing them into different Bounded Contexts and being explicit about their inter-relationships.

What is the use of PACT in Microservices architecture?
PACT is an open source tool to allow testing interactions between service providers and consumers in isolation against the contract made so that the reliability of Microservices integration increases.
Usage in Microservices:
  • Used to implement Consumer Driven Contract in Microservices.
  • Tests the consumer-driven contracts between consumer and provider of a Microservice.

Why Do People Hesitate to Use Microservices?
I have seen many devs fumble over this question. After all, they're getting asked this question when interviewing for a microservices architect role, so acknowledging its cons can be a little tricky. Here are some good answers:
  • They require heavy investment – Microservices demand a great deal of collaboration. Since your teams are working independently, they should be able to synchronize well at all times.
  • They need heavy architecture set up – The system is distributed, the architecture is heavily involved.
  • They need excessive planning for handling operations overhead – You need to be ready for operations overhead if you are planning to use a microservices architecture.
  • They have autonomous staff selection – Skilled professionals are needed who can support microservices that are distributed heterogeneously.

What Are Some Major Roadblocks for Microservices Testing?
  • Testers should have a thorough understanding of all the inbound and outbound processes before they start writing the test cases for integration testing.
  • When independent teams are working on different functionalities, collaboration can prove to be quite a struggling task. It can be tough to find an idle time-window to perform a complete round of regression testing.
  • With an increasing number of microservices, the complexity of the system also increases.
  • During the transition from monolithic architecture, testers must ensure that there is no disruption between the internal communications among the components.

Common Mistakes Made While Transitioning to Microservices
Not only on development, but mistakes also often occur on the process side. And any experienced interviewer will have this in the queue for microservices interview questions. Some of the common mistakes are:
  • Often the developer fails to outline the current challenges.
  • Rewriting the programs that already exist.
  • Responsibilities, timeline, and boundaries not clearly defined.
  • Failing to implement and figure out the scope of automation from the very beginning.

What Are the Fundamentals of Microservices Design?
This is probably one of the most frequently asked microservices interview questions. Here is what you need to keep in mind while answering to it:
  • Define a scope.
  • Combine loose coupling with high cohesion.
  • Create a unique service which will act as an identifying source, much like a unique key in a database table.
  • Creating the correct API and taking special care during integration.
  • Restrict access to data and limit it to the required level.
  • Maintain a smooth flow between requests and response.
  • Automate most processes to reduce time complexity.
  • Keep the number of tables to a minimum level to reduce space complexity.
  • Monitor the architecture constantly and fix any flaw when detected.
  • Data stores should be separated for each microservice.
  • For each microservice, there should be an isolated build.
  • Deploy microservices into containers.
  • Servers should be treated as stateless.

Where Do We Use WebMVC Test Annotation?
WebMvcTest is used for unit testing Spring MVC applications. As the name suggests, it focuses entirely on Spring MVC components. For example,
@WebMvcTest(value = ToTestController.class, secure = false):
Here, the objective is to only launch ToTestController. Until the unit test has been executed, other mappings and controllers will not be launched.

How Would You Perform Security Testing on Microservices?
Before answering this microservices interview question, explain to the interviewer that microservices cannot be tested as a whole. You will need to test the pieces independently. There are three common procedures:
  • Code scanning – To ensure that any line of code is bug-free and can be replicated.
  • Flexibility – The security solution should be flexible so that it can be adjusted as per the requirements of the system.
  • Adaptability – The security protocols should be flexible and updated to cope up with the new threats by hackers or security breaches.

What Is Idempotence and How Is it Used?
Idempotence refers to a scenario where you perform a task repetitively, but the end result remains constant or similar.
Idempotence is mostly used as a data source or a remote service in a way that when it receives more than one set of instructions, it processes only one set of instructions.


What is the 12 Factor App?

The Twelve-Factor App is a recent methodology (and/or a manifesto) for writing web applications which run as a service.



Codebase
One codebase, multiple deploys. This means that we should only have one codebase for different versions of a microservices. Branches are ok, but different repositories are not.
Dependencies
Explicitly declare and isolate dependencies. The manifesto advises against relying on software or libraries on the host machine. Every dependency should be put into pom.xml or build.gradle file. 
Config
Store config in the environment. Do never commit your environment-specific configuration (most importantly: password) in the source code repo. Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. Using Spring Cloud Config Server you have a central place to manage external properties for applications across all environments. 
Backing services 
Treat backing services as attached resources. A microservice should treat external services equally, regardless of whether you manage them or some other team. For example, never hard code the absolute url for dependent service in your application code, even if the dependent microservice is developed by your own team. For example, instead of hard coding url for another service in your RestTemplate, use Ribbon (with or without Eureka) to define the url: 
Release & Run 
Strictly separate build and run stages. In other words, you should be able to build or compile the code, then combine that with specific configuration information to create a specific release, then deliberately run that release. It should be impossible to make code changes at runtime, for e.g. changing the class files in tomcat directly. There should always be a unique id for each version of release, mostly a timestamp. Release information should be immutable, any changes should lead to a new release. 
Processes 
Execute the app as one or more stateless processes. This means that our microservices should be stateless in nature, and should not rely on any state being present in memory or in the filesystem. Indeed the state does not belong in the code. So no sticky sessions, no in-memory cache, no local filesystem storage, etc. Distributed cache like memcache, ehcache or Redis should be used instead
Port Binding 
Export services via port binding. This is about having your application as standalone, instead of relying on a running instance of an application server, where you deploy. Spring boot provides a mechanism to create a self-executable uber jar that contains all dependencies and embedded servlet container (jetty or tomcat). 
Concurrency 
Scale-out via the process model. In the twelve-factor app, processes are a first-class citizen. This does not exclude individual processes from handling their own internal multiplexing, via threads inside the runtime VM, or the async/evented model found in tools such as EventMachine, Twisted, or Node.js. But an individual VM can only grow so large (vertical scale), so the application must also be able to span multiple processes running on multiple physical machines. Twelve-factor app processes should never write PID files, rather it should rely on operating system process manager such as systemd - a distributed process manager on a cloud platform. 
Disposability 
The twelve-factor app’s processes are disposable, meaning they can be started or stopped at a moment’s notice. This facilitates fast elastic scaling, rapid deployment of code or config changes, and robustness of production deploys. Processes should strive to minimize startup time. Ideally, a process takes a few seconds from the time the launch command is executed until the process is up and ready to receive requests or jobs. Short startup time provides more agility for the release process and scaling up; and it aids robustness because the process manager can more easily move processes to new physical machines when warranted. 
Dev/Prod parity 
Keep development, staging, and production as similar as possible. Your development environment should almost identical to a production one (for example, to avoid some “works on my machine” issues). That doesn’t mean your OS has to be the OS running in production, though. Docker can be used for creating logical separation for your microservices. 
Logs 
Treat logs as event streams, sending all logs only to stdout. Most Java Developers would not agree to this advice, though. 
Admin processes 
Run admin/management tasks as one-off processes. For example, a database migration should be run using a separate process altogether.

How do microservices communicate with each other?
Microservices are often integrated using a simple protocol like REST over HTTP. Other communication protocols can also be used for integration like AMQP, JMS, Kafka, etc.
The communication protocol can be broadly divided into two categories- synchronous communication and asynchronous communication.
Synchronous Communication
RestTemplate, WebClient, FeignClient can be used for synchronous communication between two microservices. Ideally, we should minimize the number of synchronous calls between microservices because networks are brittle, and they introduce latency. Ribbon - a client-side load balancer can be used for better utilization of resource on the top of RestTemplate. Hystrix circuit breaker can be used to handle partial failures gracefully without a cascading effect on the entire ecosystem. Distributed commits should be avoided at any cost, instead, we shall opt for eventual consistency using asynchronous communication.
Asynchronous Communication
In this type of communication, the client does not wait for a response, instead, it just sends the message to the message broker. AMQP (like RabbitMQ) or Kafka can be used for asynchronous communication across microservices to achieve eventual consistency.

What should be preferred communication style in microservices: synchronous or asynchronous?
  1. You must use asynchronous communication while handling HTTP POST/PUT (anything that modifies the data) requests, using some reliable queue mechanism (RabbitMQ, AMQP, etc.) 
  2. It's fine to use synchronous communication for Aggregation pattern at API Gateway Level. But this aggregation should not include any business logic other than aggregation. Data values must not be transformed at Aggregator, otherwise, it defeats the purpose of Bounded Context. In Asynchronous communication, events should be published into a Queue. Events contain data about the domain, it should not tell what to do (action) on this data. 
  3. If microservice to microservice communication still requires synchronous communication for GET operation, then seriously reconsider the partitioning of your microservices for bounded context and create some tasks in backlog/technical debt.
What is polyglot persistence? Can this idea be used in monolithic applications as well?
Polyglot persistence is all about using different databases for different business needs within a single distributed system. We already have different database products in the market each for a specific business need, for example: 

RDBMS
Relational databases are used for transactional needs (storing financial data, reporting requirements, etc.) 

MongoDB
Documented oriented databases are used for documents-oriented needs (for e.g. Product Catalog). Documents are schema-free so changes in the schema can be accommodated into the application without much headache.

Cassandra/Amazon DynamoDB
Key-value pair-based database (User activity tracking, Analytics, etc.). DynamoDB can store documents as well as key-value pairs.

Redis

In memory distributed database (user session tracking), its mostly used as a distributed cache among multiple microservices.

Neo4j 

Graph DB (social connections, recommendations, etc) 
Benefits of Polyglot Persistence are manifold and can be harvested in both monolithic as well as microservices architecture. Any decent-sized product will have a variety of needs which may not be fulfilled by a single kind of database alone. For example, if there are no transactional needs for a particular microservice, then it's way better to use a key-value pair or document-oriented NoSql rather than using a transactional RDBMS database. 

Characteristics of a microservices architecture
  1. High Cohesion - Small and focussed on doing one thing well. Small does not mean less number of lines of code because few programming languages are more verbose than others, but it means the smallest functional area that a single microservices caters to.
  2. Loose Coupling - Autonomous - the ability to deploy different services independently, and reliability, due to the ability for a service to run even if another service is down.
  3. Bounded Context - A Microservice serves a bounded context in a domain. It communicates with the rest of the domain by using an interface for that Bounded context.
  4. Organisation around business capabilities instead of around technology.
  5. Continuous Delivery and Infrastructure automation.
  6. Versioning for backward compatibility. Even multiple versions of same microservices can exist in a production environment.
  7. Fault Tolerance - if one service fails, it will not affect the rest of the system. For example, if a microservices serving the comments and reviews for e-commerce fails, the rest of the website should run fine.
  8. Decentralized data management with each service owning its database rather than a single shared database. Every microservice has the freedom to choose the right type of database appropriate for its business use-case (for example, RDBMS for Order Management, NoSql for catalogue management for an e-commerce website)
  9. Eventual Consistency - event-driven asynchronous updates.
  10. Security - Every microservice should have the capability to protect its own resources from unauthorized access. This is achieved using stateless security mechanisms like JSON Web Token (JWT pronounced as jot) with OAuth2.
 What Is Spring Cloud?
Spring Cloud is a system for integrating with external systems in Microservices. It is a short – lived paradigm which quickly designs an application. It has a really vital role in Microservice architectural design in connection with the limitless amount of information processing. Spring cloud offers a certain degree of actual experience in standard use cases as well as a series of comprehensive functionalities below this:
  • Versioned and distributed configuration
  • Discovery of service registration
  • Service to service calls
  • Routing
  • Circuit breakers and load balancing
  • Cluster state and leadership election
  • Global locks and distributed messaging
What are the challenges you face while working Microservice Architectures?
It is easy to develop a lot of smaller microservices however the obstacles they sometimes face were as follows:
  • Automate the Components: Hard to optimize as a variety of small modules are available. We will have to adopt the building, deployment and monitoring phases for each module.
  • Perceptibility: It is hard to deploy, preserve, supervise and address troubles to keep a huge number of modules together. All modules need to be highly perceptible.
  • Configuration Management: It is often difficult to maintain the configurations for modules in different environments.
  • Debugging: Every service is difficult to find for a mistake. Centralized logging and workflows are crucial for debugging issues.
Why Would You Need Reports & Dashboards in Microservices?
Most of the reports and dashboards were used for monitoring and maintaining microservices. Multiple options are available to help support this motive. It is possible to use reports and dashboards to:
  • Find out which resources are exposed to microservices.
  • Find out which services are affected whenever module alterations take place.
  • Provide an instant access point anytime information is needed.
  • Provides information about the versions of the deployed components or modules.
  • To give the components a level of self-awareness and compliance.
What Is Semantic Monitoring?
The entire application is monitored, and computerized tests are combined. Semantic Monitoring’s principal advantage is to discover out the qualities that make your business much more profitable. After a problem has been detected, it allows for faster insulation and bug triage, reducing the main repair time. After a problem has been detected, it allows for quicker insulation and bug emergency care, lowering the primary maintenance time. It tries to identify the transfers which are impacted by availability or lack of quality.

Why do we use Correlation IDs in Microservices architecture?
The correlation ID is a single value connected to requests and messages that refer a specific transaction or event chain. A correlation ID is also known as a transit ID. A well-publicized pattern of enterprise integration depends upon the use of Correlation ID. A correlation ID forms part of Java Messaging Service (JMS) as the non-standard HTTP header. But again, it is ambiguous to attach a correlation ID to a request. There’s not one you have to use. But you’re going to do enough to use a correlation identifier in your messages if you model a distributed system that utilizes messages delays and asynchronous processing.

 Which tools you use for automation in microservice environments?
Microservices are automated starting from development till deployment to production.
GIT is mostly used for version control.
Jenkins is used for continuous integration.
Testing tools like JUnit, Selenium are used for automating testing.
Container technologies like Docker are used with release management tools like Chef or Puppet for infrastructure management automation.
Deployment automation is done using tools such as Kubernetes or Spring Cloud.

What is CI/CD?
Continuous Integration (CI) is the practice of automatically building and unit testing an entire application frequently, ideally on every source code check-in.
Continuous Delivery (CD) is the practice of deploying every build to a production like environment and performing automated integration and acceptance testing after it passes its build and unit tests.
This is required so that errors are identified at an early state and little to no coordination is required between different teams building different microservices.

How do you monitor microservices?
Spring Boot actuator is a good tool monitor metrics, counters for individual microservices. But if you have multiple microservices, its difficult to monitor each individually.
For this, we can use open source tools like Prometheous, Kibana or Graphana.
Prometheous is a pull-based monitoring tool. It contains metrics at given intervals, displays them and can also trigger alerts.
Kibana or Grafana are dashboard tools used to visualize and monitor the data.
When there are large number of microservices with dependencies, we can use AppDynamicsDynatrace, and New Relic that can draw dependencies among microservices.

What is Kubernetes?
Kubernetes is the market leading orchestration solution.
It helps with automating container deployments, scheduling, and the scalability of containers.

Kubernetes supports features such as automatic progressive rollouts, versioned deployments, and container resiliency if containers fail due to some reason.


No comments:

Post a Comment