1. What is a Microservice?
A Microservice is a small and autonomous piece of code that does one thing very well. It is focused on doing one specific task in an excellent way in a big system.
It is also an autonomous entity that can be designed, developed and deployed independently.
Generally, it is implemented as a REST service on HTTP protocol, with technology-agnostic APIs.
A Microservice can have its own database. In ideal conditions, it does not share database with any other service.
2. What are the benefits of Microservices architecture?
Microservices architecture provides many benefits. Some of the key benefits are:
- Scaling: Whenever, there are multiple Microservices instead of one monolith, it is easier to scale up the service that is being used more. E.g. Let say, you have a Product Search service and Product Buy service. The frequency of calling Product Search service is much higher than that of Product Buy service. In this case, you can just scale up the Product Search service to run on powerful hardware with multiple servers. Whereas, Product Buy service can be deployed on less powerful hardware.
- Resilience: In Microservice architecture, if one service goes down, it may not affect the rest of the system. The other parts can keep functioning, business as usual (BAU). E.g. Let say, you have Product Recommendation service and Product Buy service. If Product Recommendation service goes down, the Product Buy service can still keep running.
- Technology Mix: With so many changes in technology every day, you can keep using the latest technology for your new Microservices. You can adopt new technologies with less risk in Microservices architecture compared to Monolithic architecture. This is one of the best benefits of Microservices architecture.
- Reuse: Microservices help you in reusing the lessons learnt from one service to another.
- Easy Deployment: Microservices architecture, if done correctly, helps in making the deployment process smooth. If anything goes wrong, it can be rolled back easily and quickly in Microservices.
- Debugging: In production system, something or other may go wrong. In a monolith system, it is complicated to debug and isolate a problem. With microservice architecture, you can easily find the specific microservice that is not working as expected. This helps in quicker debugging of a production issues.
3. What is the role of architect in Microservices architecture?
Architect, in Microservices architecture, plays the role of a town planner. Architect decides in broad strokes about the layout of the overall software system.
Architects help in deciding the zoning of the components. They make sure components are mutually cohesive but not tightly coupled. They need not worry about what is inside each zone.
Since they have to remain up to date with the new developments and problems, they have to code with developers to learn the challenges faced in day-to-day life.
They can make recommendations for certain tools and technologies, but the team developing a micro service is ultimately empowered to create and design the service. Always remember that a micro service implementation can change with time.
Architects have to provide technical governance so that teams follow core principles of Microservice during technical development.
Most of the time, Architect has to work as custodian of overall Microservices architecture.
4. What is the advantage of Microservices architecture over Service Oriented Architecture (SOA)?
Service Oriented Architecture (SOA) is an approach to develop software by creating multiple services. It creates small parts of services and promotes reusability of software. But SOA development can be slow due to use of things like communication protocols SOAP, middleware and lack of principles.
On the other hand, Microservices are agnostic to most of these technology things. You can use any technology stack, any hardware/middleware, any protocol etc. to build a Microservice, as long as you follow the core principles of Microservice.
Microservices architecture also provides more flexibility, stability and speed of development over SOA architecture.
5. Is it a good idea to provide a Tailored Service Template for Microservices development in an organization?
If your organization is using similar set of technologies, then it is a good idea to provide a Service Template that can be tailored by development teams. It can make development faster.
The template contains information about logging, monitoring, web framework, packaging, build, resiliency pattern etc.
Therefore, it helps in easy adoption of best practices into each microservice because it is already built into template. If your organization uses a wide variety of technologies, then it may not be wise to produce and maintain one template for each service. Instead it is better to introduce tools that help in maintaining same set of practices for Microservices architecture in technology agnostic manner.
There are many frameworks that provide tailored templates for Microservices. E.g. Dropwizard, Governator etc. You can use these templates to make faster development of services in your organization.
Also remember that template code should not promote shared code. This can lead to tight coupling between Microservices.
6. What are the disadvantages of using Shared libraries approach to decompose a monolith application?
You can create shared libraries to increase reuse and sharing of features among teams. But there are some downsides to it.
Shared libraries are implemented in same language, therefore, it constrains you from using multiple types of technologies.
It does not help you with scaling the parts of system that need better performance.
Deployment of shared libraries is done in a manner similar to the deployment of Monolith application. Hence, it comes with same deployment issues.
Shared libraries introduce shared code in Microservices, that increases tight coupling in software.
7. What are the characteristics of a Good Microservice?
Good Microservices have these characteristics:
- Loose coupling: A Microservice knows little about any other service. It is as much independent as possible. The change made in one Microservice does not require change in other Microservices.
- Highly cohesive: Microservices are highly cohesive. Each Microservice can provide one set of behavior independently.
- 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.
- Business Capability: Microservices individually add business capability to a system. It is considered as a small part of the big picture in an organization.
- Continuous Delivery: A good Microservice is built in such a way that it can be continuously integrated and continuously deployed on production. It increases the speed of feature deployment to production.
- Backward Compatibility: There can be instances when multiple versions of a Microservice exist in production. Therefore any new version of Microservice should provide backward compatibility to clients.
- Stateless: The good microservices try to keep the service stateless so that there is less dependency between the calls.
8. What is Bounded Context?
A bounded context is like a specific responsibility that is developed within a boundary. In a domain there can be multiple bounded contexts that are internally implemented.
E.g. A hospital system can have bounded contexts like- Emergency Ward handling, Regular vaccination, Out patient treatment etc.
Within each bounded context, each sub-system can be independently designed and implemented.
We can implement an independent Microservice to serve a bounded context within a large system.
9. What are the points to remember during integration of Microservices?
Some of the important points to remember during integration of Microservices are:
- Technology Agnostic APIs: Developing Microservices in a technology agnostic way helps in integration of multiple Microservices. With time, the technology implementation can change but the interface between Microservices can remain same.
- Breaking Changes: Every change in Microservice should not become a breaking change for client. It is better to minimize the impact of a change on an existing client. So that existing clients do not have to keep changing their code to adapt to changes in a Microservice.
- Implementation Hiding: Each Microservice should hide its internal implementation details from another one. This helps in minimizing the coupling between Microservices that are integrated for a common solution.
- Simple to use: A Microservice should be simple to use for a consumer, so that the integration points are simpler. It should allow clients to choose their own technology stack.
10. Is it a good idea for Microservices to share a common database?
Sharing a common database between multiple Microservices increases coupling between them. Consider a scenario when one service starts accessing data tables of another service. This can defeat the purpose of bounded context. Therefore, it is not a good idea to share a common database between multiple Microservices.
11. What is the preferred type of communication between Microservices?Synchronous or Asynchronous?
Synchronous communication is a blocking call, in which client blocks itself from doing anything else until the response comes back.
In asynchronous communication, client can move ahead with its work after making an asynchronous call. Therefore client is not blocked.
In synchronous communication, a Microservice can provide instant response about success or failure. In real-time systems, synchronous service is very useful. In Asynchronous communication, a service has to react based on the response received in future.
Synchronous systems are also known as request/response based.
Asynchronous systems are event-based. Synchronous Microservices are not loosely coupled.
Depending on the need and critical nature of business domain, Microservices can choose synchronous or asynchronous form of communication.
12. What is the difference between Orchestration and Choreography in Microservices architecture?
In Orchestration, we rely on a central system to control and call other Microservices to complete a task. In Choreography, each Microservice works like a State Machine and reacts based on the input from other parts.
Orchestration is a tightly coupled approach for integrating Microservices. Whereas, Choreography is a loose coupling approach.
Choreography based systems are more flexible and easy to change than Orchestration based systems.
Orchestration is often implemented by synchronous calls.
Choreography is implemented by asynchronous calls. The synchronous calls are much simpler compared to asynchronous communication.
13. What are the issues in using REST over HTTP for Microservices?
In general, REST over HTTP is one of the most popular implementations of Microservices. Some of the issues in using REST over HTTP for Microservices are as follows:
- In REST over HTTP, it is difficult to generate a client stub.
- Some Web-Servers do not support all the HTTP verbs like- GET, PUT, POST, DELETE etc.
- Due to JSON or plain text in response, performance of REST over HTTP is better than SOAP. But it is not as good as plain binary communication.
- There is an overhead of HTTP in each request for communication.
- HTTP is not well suited for low-latency communication.
- There is more work in consumption of payload. There may be overhead of serialization, deserialization in HTTP.
14. Can we create Microservices as State Machines?
Yes, Microservices are independent entities that serve a specific context. For that context, a Microservice can work as a State Machine.
In a State Machine, there are lifecycle events that cause change in the state of the system.
E.g. In a Library service, there is a book that changes state based on different events like- issue a book, return a book, lose a book, late return of a book, add a new book to catalog etc. These events and book object can form a state machine for Library Microservice.
As of now, current trend is to make microservice calls stateless. Remember, stateless and state machine are two different concepts.
15. What is Reactive Extensions?
Reactive Extensions is a design approach in which we collect results by calling multiple services and then compile a combined response.
These calls can be synchronous or asynchronous, blocking or non-blocking.
It is also known as Rx.
Rx works opposite to legacy flows. It is very popular in distributed systems. You just react to the response received from another Microservice.
Rx is based on a combination of Observer pattern, Iterator pattern and functional programming design approach.
Some people call it functional reactive programming. But it can be used in Object Oriented programming as well.
16. What is DRY?
DRY stands for Don’t Repeat Yourself. It promotes concept of code reusability.
In DRY pattern, developers build libraries and share these libraries. This sharing can result in tight coupling. DRY should be a concern within a Microservice implementation. But across 2-3 Microservices, you can ignore the DRY.
The basic design principle behind DRY is that we should not try to reinvent the wheel. At the same time, we should not share the same wheel for multiple purposes.
17. What is Semantic Versioning?
Semantic Versioning is a type of software versioning scheme. It is easy to understand by the users of a software.
In Semantic Versioning specification, each software version is specified in the format of Major.Minor.Patch.
- Major version increment means that the changes to software are not backward compatible.
- Minor version increment means that new functionality is added but changes are still backward compatible.
- Patch version increment means that a fix to bug is provided in this version.
Semantic Versioning is the recommended versioning scheme for Microservices development and release.
It also helps in managing dependencies across multiple Microservices.
18. Is it a good idea to build a Microservice or buy a commercial off the shelf software?
If an organization’s core work is related to the software to be developed then a Microservice should be built.
E.g. A hospital management company can build Microservice for Doctor/Patient checkin etc. But it can buy off the shelf software for managing parking lot.
Investment in building and maintaining a Microservice in house is worthwhile, if it becomes an asset over time for the organization.
19. Why do we break the Monolith software into Microservices?
There are many reasons to break the Monolith software into Microservices.
- Speed of Development: Monolith software takes longer time for build and deployment than a Microservice. This results in slow pace of software development. With Microservice you can develop code faster because less time is spent on overheads.
- Flexibility of Technology: With Microservice approach you are not locked into one technology for life. You can use the latest technology for building a new Microservice. Breaking a Monolith into Microservices helps in making good use of the cutting edge technologies.
- Organization Structure: In case of Monolith software, often software silos are formed within organization. With Microservices approach, you can be truly agile and create teams that are generic enough to build any Microservice on related domains.
- Security: Since Microservices do one thing at a time, you can tailor the security level as per the need of specific Microservice. E.g. In case of banking system, Microservice for storing and maintaining actual Bank Account number needs more security than the Microservice for checking account balance.
- Scalability: Microservices are easier to scale than Monolith software. You can pick the specific Microservice that requires better performance and just scale that one. In case of Monolith it becomes a herculean task to scale the complete Monolith.
20. What is Continuous Integration?
Continuous Integration (CI) is a software development approach in which developers merge their code into a common repository, several times in a day. To merge the code, every check-in should run build pipeline, and run a set of tests that ensure that common repository is always ready for deployment to production.
CI provides the benefit of early feedback for any code that is developed and merged into common repository.
There are many tools for CI that help in running build, running tests and providing early feedback to developer at the time of checking-in code to repository.
21. What is Continuous Delivery?
Continuous Delivery (CD) is an approach in which we treat each code check-in to common repository as a release candidate. CD helps us in getting code ready for deployment with every check-in.
CD involves compiling code, running unit tests, doing UAT and performance tests with every check-in. The purpose of this is to produce code of such a good quality that it can be deployed with confidence.
CD also reduces time between releases, as well as it increases agile nature of overall software development process.
CD leads to predictable deployments without any integration, testing or UAT phases.
CD provides benefits like- faster time to market, high quality code, lower deployment costs, less risk of release failure, efficient and happy teams.
22. What is Ubiquitous language?
Ubiquitous language (UL) is a term used by Eric Evans for Domain Driven Design. UL is a common language used by developers and users for common specification of the domain that they are working on. It is a rigorous language in which domain can be explained easily.
UL brings all the team members at the same page. UL has to be a crystal clear language so that it can be translated into software that a machine can understand.
23. What is the benefit of Single Service per Host model in Microservices?
In Microservices architecture, we can deploy one service on one host or we can deploy multiple services on same host. When we deploy single service on a host, then we get the benefit of avoiding single point of failure. A failure on one host will only impact one service at a time.
It also makes monitoring and security easier than multiple services on one host.
Single Service per Host is also easier to scale, in case we want a specific service to be scaled up. Whenever there is high demand for a service, we can scale up the service by increasing processing power, bandwidth etc. of that host.
24. What are different types of Tests for Microservices?
In a system based on Microservices architecture, there are multiple Microservices, therefore, testing becomes quite complex. In such a scenario it is better to divide tests into different levels.
At the lowest level are technology facing tests like- unit tests and performance tests. Often, these are completely automated.
In the middle level, we have tests for exploratory testing like- how to break the system. We run stress tests, load tests, penetration tests and usability tests.
At the top level are acceptance tests that are fewer in number than other levels. These acceptance tests help stakeholders in understanding and verifying software features. Some of these tests can be manual tests.
25. What is Mike Cohn’s Test Pyramid?
Mike Cohn has provided a model called Test Pyramid that describes the kind of automated tests required for software development. There are three levels in Test Pyramid.
- First layer of Pyramid is Unit Tests. These are the result of Test Driven Development (TDD). This is the bottom most layer of the Test Pyramid.
- Second layer is Service tests. These tests are for testing the service directly under different inputs. These tests also verify the interface provided by a service against the client expectation.
- Third layer is UI or End-to-End tests. These tests run against the entire system including UI, Front-end or any third party clients. The purpose of these tests is to verify the actual production code. This is the top most layer of the pyramid.
As per pyramid, number of tests at first layer should be the highest. At service layer, the number of tests should be less than the ones at the unit test level, but more than at the end-to-end level.
26. What is the difference between Mock or Stub for Microservice tests?
Stub: A Stub is simply a dummy object that helps in running the test. It provides fixed behavior under certain conditions. That behavior can be hard coded into it. Any other behavior of stub is never tested. And this hard coded behavior helps in actual test to proceed.
E.g. For an empty Stack you can create a stub that just returns true for empty() method. It does not care whether there is any element in stack or not.
Mock: A Mock is a dummy object in which certain properties are set initially. The behavior of this object depends on these properties. The object’s behavior can be tested along with these properties.
E.g. For a Customer object, you can mock it by setting name and age. You can set age as 15 and then test for isAdult() method that will return true for age greater than 18. Now your Mock Customer object is working for this.
A stub does not cause a test to fail.
For service level tests, you can use both Mock and Stub for testing the functionality.
27. How can we eradicate non-determinism in tests?
Non-Deterministic Tests (NDT) are unreliable tests. Some times they pass and some times they fail. When they fail, you re-run them and then they pass. Therefore, their results are not consistent. There are some suggestions from Martin Fowler to remove non-determinism from tests. These are as follows:
- Quarantine: It is better to separate Non-Deterministic Tests (NDT) from the rest of suite. This is done to identify which group of tests is healthy and which one is not healthy. This process is called Quarantine of Non-Deterministic Tests. You can put all the NDTs in a separate suite. Over a period of time, you can start solving the issues with this separate suite, while the healthy test suite keeps running for every build.
- Asynchronous: If your test depends on another service for an asynchronous call, then the results may not be always correct when the other service is down. Once you identify that this asynchronous call is the root of your problem, you can create a Test Double for that asynchronous call to resolve it.
- Remote Services: Some tests are dependent on remote services. These remote services are not up all the time. Due to which our tests do not behave consistently. It is a good idea to create a stub or a Test Double for Remote Services. This helps to rule out the unnecessary dependency on remote services.
- Isolation: At times, environment in which tests are run is not clean with each build. There are files remaining from previous run. For a consistent run of Tests, each build should clean the environment before running any tests. The tests should be run on that environment after the cleanup.
- Time: Certain tests are dependent on the time of the day. E.g. Business hours etc. Whereas, developers are running build any time of the day. In such a case any test dependent on time of the day will give different result at different time. To resolve this, you can introduce the Stub for System clock so that you pass time of the day to your environment and then start the test.
- Resource leaks: If you have resource leak, then your tests can start failing at a specific time when the resource usage exceeds the limit. In such a case, you can implement a Resource Pool to control the resource limits and then run tests with smaller number of initial resources. This will help in identifying any inconsistent results due to Resource Leaks early in the development.
28. What is a Consumer Driven Contract (CDC)?
Consumer Driven Contract (CDC) is a pattern for developing Microservices that are used by external systems. In a Microservice, there is a provider that builds it, and there are one or more consumers that use the Microservice.
General approach is for Provider to specify its interfaces in an XML like document. But in Consumer Driven Contract, each consumer of a service provides and documents the interface it expects from Provider. In this way, a Provider can never introduce a breaking change if it keeps adhering to the Consumer Driven Contract.
CDC has following characteristics:
- Closed and complete: It represents the mandatory functionality that a consumer expects from the provider.
- Union: These are union of the expectations from multiple consumers.
- Stable and Immutable: It is a stable contract that cannot change without prior communication with the consumers. So it is considered immutable.
29. What is PACT?
PACT is an open source tool to allow testing interactions between service providers and consumers in isolation against a contract.
It is a tool to implement Consumer Driven Contract in Microservices.
By using PACT you can test the consumer driven contracts between consumer and provider of a Microservice. It is an automated suite to test this interaction. It increases the overall reliability of Microservices integration in a complex system.
Nowadays, Spring Cloud Contract is another tool for implementing Consumer driven contracts.
30. How can we separate Deployment from Release of Microservices?
Deployment and Release are two separate events for Microservices. One way of doing this is blue/green deployment. In this case, there are two versions of a Microservice deployed at a time. But only one version is taking real requests. Once the other version is tested to our satisfaction, we can switch the version.
We can run a smoke-test suite to verify that the functionality is running correctly in the newly deployed version. Based on the results of smoke-test, newer version can be released to become the live version.
In this way, we can separate deployment from release of a Microservice.
31. What is Canary Releasing?
Canary Releasing is a technique to direct a small set of users to newly deployed version, so that we can verify that release is working as expected. Once we are satisfied, then we can gradually increase traffic to new version. Once all the clients are on new version, the old version is phased out.
In Canary Releasing two versions coexist for a longer period of time than blue/green deployment.
32. What is the difference between Mean Time to Repair (MTTR) and Mean Time between failures (MTBF)?
If a release goes bad, we need to repair it. The average time taken to repair a release is Mean Time To Repair (MTTR). On the other hand, we can choose an approach in which we just discard the new release and replace it with the old release. So there will be a time period in which new release failed. But the old one quickly replaced it. This is known as Mean Time Between Failures (MTBF).
In Microservices architecture, instead of spending too much effort in making the service so robust with enormous amount of test cases, we focus on MTBF. i.e. if one version of a service is doing well and the newer version fails, then we just replace it with the previous one quickly. Later on, we can fix the newer version.
33. How can we do cross-functional testing?
Cross-functional testing is verification of non-functional requirements of a system. These requirements are such characteristics of a system that cannot be implemented like a normal feature.
E.g. Number of concurrent users supported by system, usability of site etc.
Cross-functional testing is related to cross-functional requirements. Often business users do not specify cross-functional requirements in the beginning. But they expect these when software is complete and deployed to production.
It is always a good idea to ask business users about such cross-functional expectations in initial phase of the project itself.
34. What is a good tool for monitoring multiple services at a time?
Graphite is an open source database that captures metrics from services in a time series database. By using Graphite we can capture essential metrics of multiple Microservices simultaneously. And we can use a dashboard like- Grafana to monitor these metrics in almost real time.
Graphite is also great at handling large amount of data. It can also show the trends from few hours to few months within a few seconds. Many organizations like- Facebook etc. use Graphite for monitoring.
Some of the other tools to monitor Microservices are: AppDynamics, DynaTrace, SpringBoot Admin etc.
35. What is Semantic Monitoring?
At times, after the deployment we want to make sure that complete end-to-end system is working fine. To achieve this we can create a Synthetic Transaction that is hidden from outside world, but it can test actual functionality of the system.
This synthetic transaction moves across multiple services, and each service processes it. Finally, we get complete end result for this Synthetic Transaction. Based on the end result received after processing of this transaction we can confirm that system is working as expected. This technique of verifying semantic correctness of the system is known as Sematic Monitoring.
36. Why do we use Correlation IDs in Microservices architecture?
In Microservices architecture, if there is a failure in one Microservice, then we may have to go to upstream Microservice to find the source of failure. Or we may have to go to downstream Microservice to find the impact of the failure. Each Microservice is an independent entity. Therefore, we need some relation between the error in a service as well as the error in its upstream/downstream services.
To resolve this issue, we can use Correlation IDs. These are unique IDs like GUID that are passed from one service to another service during an API call. By using a GUID and failure message associated with it we can find the source of failure as well as the impact of failure.
37. What is the difference between Authentication and Authorization?
Authentication is the process of verifying credentials of a user. It checks whether a user is genuine or not by checking identity of a user. The most common way of Authentication is a User/Password check.
E.g. We use finger print or face recognition on an iPhone to check the credential of a user.
Authorization is the process of checking whether a user has access to resources or not. There can be different levels of authorization in a Microservice.
E.g. Some users may just have read access. Some admin users may have write access to certain parts.
The correct mix of Authorization and Authentication is important for implementing security features in a Microservice.
38. How does HTTPS authentication work in Microservices?
HTTPS is also known as HTTP Secure. This protocol ensures that all communication between Microservices is secure and encrypted. HTTPS is used for handling the transfer of confidential information between Microservices.
In HTTPS, the client is assured that the Server it is talking to is a genuine server. To do so, HTTPS uses SSL certificates.
Also encrypting the request and response helps in avoiding eavesdropping. SSL ensures that all communication is encrypted and decrypted in a secure way.
The drawback of encryption is that it cannot be used in proxy caching.
39. What are Client certificates?
Client certificate is another form of security that is implemented at Transport Layer instead of Application layer. Each client installs a X.509 certificate locally. This ensures that server can rely on the validity of client, if it has the right certificate.
It is more complex than SSL, since it has to manage certificates at all clients.
40. Why some big companies use API keys for providing access to public APIs?
Many big companies like- Google, Amazon etc provide public APIs to developers. These APIs come with an API key. This API key is used for various purposes:
- An API key can authenticate a client.
- An API key can impose limits of number of calls to API.
- An API key can limit the access of a client to certain APIs only.
- An API key can introduce security in Service call between client and provider.
41. What is Confused Deputy Problem in security context?
In Microservices world, a Confused Deputy is a computer security problem. In this case one service acts as deputy and accepts authenticated requests from other clients to perform an action.
Sometimes, one malicious client can hack the system and send a falsely authenticated request. Since the request is authenticated, deputy will do the same action for malicious client. This can breach the security of the system.
E.g. Let say a service depends on barcode to get the price. If a client provides incorrect barcode, the service will provide incorrect price, since it relies on the authenticity of barcode. This can lead to incorrect billing for a customer.
42. How can we secure Data at Rest in an organization?
At times, organizations are so much focused on network breach and securing the servers, that they do not pay attention to data (at rest) stored in database or in backup disks. There are certain points to remember for securing Data at Rest.
- Encryption: Data at Rest should be encrypted so that any malicious user cannot decrypt. For encryption, we should use popular algorithms and tools that are difficult to break into.
- Key Management: Data is encrypted by using Keys. These Keys should not be stored along with Data. If a person gets access to Data, he/she should not get access to Keys. For this we can use vault or key store services to store keys.
- Data Identification: It is not possible to encrypt all the data at rest. So we can identify the critical information that should always be encrypted. This helps in reducing costs of encryption and improves performance of encryption/decryption.
- On Demand Decryption: Data should not be freely decrypted. There should be a solid reason for decryption and it should be logged in the system.
- Backup Encryption: Any backups should not be left alone unencrypted. This helps in reducing the vulnerability of the system.
43. What are the different points to consider for security in Microservices architecture?
Implementing security in Microservices architecture has its own challenges. Whenever there are multiple Microservices and many interfaces between them, it is important to consider following aspects to implement correct security in Microservices architecture based system:
- Data in Motion
- Data at Rest
- Firewalls
- Operating system
- Logging
- Intrusion Monitoring
- Network segregation
44. What is Conway’s law?
Melvin Conway’s law states, “Any organization that designs a system will inevitably produce a design whose structure is a copy of the organization’s communication structure.”
In the context of software design, often organizations design software that has components for each department of the organization. It reflects the way communication flows between these departments.
E.g. Corporate websites reflect same design as the departments and users within them. Any department that prefers more bureaucracy will have more forms in their section. If a department gives importance to usability then its section will have less number of clicks to get a job done.
In the context of Microservices, Conway’s law can be used to create team structure in an organization. We can split the ownership of Microservices among multiple teams. A team developing the core of a Microservice can act as custodian of that service, while other teams are free to make changes in it.
45. What are the important Cross-Functional Requirements to consider during the design of a Microservice?
Some of the important cross-functional requirements for design consideration are:
- Availability
- Durability of data
- Extensibility
- Fault Tolerance
- Latency
- Maintainability
- Performance
- Resilience
- Robustness
- Scalability
- Security Compliance
- Testability
- Usability
- Integration Support
46. What is a Circuit Breaker pattern in the context of Microservice?
Circuit Breaker is a software design pattern similar to the one used in electrical devices.
In an electrical device, we use circuit breaker to break the flow of current in an unforeseen situation. This ensures that the electrical device is not damaged due to an unexpected issue.
In the context of Microservices, it can be implemented in various scenarios.
If the number of requests to a Microservice increases beyond a threshold then circuit breaker becomes active and blocks extra calls.
If the number of failed requests to a Microservice reach a threshold then circuit breaker becomes active and the requests are throttled for a period of time. After that circuit breaker sends a few requests to check if Microservice has recovered or not.
In Microservices, sometimes circuit breaker stores and queues up the failed requests for retry at a later time.
In certain cases, it is better to fail fast and give immediate response to clients for a synchronous request.
Circuit breaker can also be used to implement Bulkhead design pattern in Microservices.
47. What is Bulkhead design pattern?
Bulkhead is a software design pattern to create a stable and fault tolerant system. In this pattern, if one part of a system fails, then other parts keep functioning normally rather than bringing the whole system down.
While designing a system, we create separate components in a watertight compartment like manner. If one component fails, we just close access to that component and try to fix it. Rest of the system keeps working business as usual (BAU).
Netflix’s Hysterix library provides two ways to implement Bulkhead design pattern.
- Thread Isolation: In this case, if calls to a component fail then these are directed to thread pool with fixed number of threads.
- Semaphore Isolation: In this case, all callers acquire a permit before making a request. If caller doesn’t get permit then it means the component is down.
Currently Hysterix library is in maintenance mode. Nowadays, resilience4j is the open source library that provides fault tolerance functionality similar to Hysterix.
48. What is Idempotency of a Microservice operation?
Idempotency refers to getting same result even after doing same operation multiple times in a Microservice.
E.g. Let say, we have to send a reminder email to a customer for an upcoming bill payment on the due date.
Our Microservice provides an idempotent Reminder operation, so that even if we call this operation multiple times on the due date, it sends only one email per day. This will give better experience to customer instead of sending multiple reminders for same payment on same day.
49. How can you scale a Database?
To scale a Database, we have to identify our goals. Do we want to increase the availability of Database or we want to provide better performance for read or write operations on Database. Once the goals are clear, we can use different strategies for different goals.
- Read Scalability: We can use caching to increase the performance of reads. Most of the databases have inbuilt features like- index etc. to provide better read performance.
- Write Scalability: One technique to improve write scalability is Sharding. In this approach, we create multiple database nodes, each catering to one set of data. E.g. If we have two nodes, one node can store products with IDs ending from 1-5 and the other node can store products with IDs from 6-10.
- Availability: To increase availability, we can create read replicas for the database. Or we can use Cassandra like ring architecture with multiple nodes.
50. What is Command Query Responsibility Segregation (CQRS) design pattern?
Command Query Responsibility Segregation (CQRS) is a design pattern for storing and querying information. In this pattern, storing of information can be done in a system separate from the system used for querying the information. It can help us in scaling a system and in providing better performance for both reads and writes.
In this pattern, Commands are the requests to modify data in the system. Once commands are validated, data is updated.
Query requests can work on updated data-set. Query requests provide results to clients.
Command and Query logic can be implemented in different services that can live on different servers.
In case there is high load on Query service, then you just scale the Query service. Also you can support multiple formats for the response from a Query service to satisfy requirements of multiple clients. Bonus Questions:
51. How will you implement Caching in Microservice?
Caching is a performance improvement technique for getting query results from a service. It helps us in minimizing the calls to database while fetching results. In the Internet, HTTP protocol also uses caching to serve web pages faster with increased load.
In Microservices, we can implement Caching in three ways.
- Client Side: In this case, information is cached at client side and service has to inform the client when the information needs to be replaced in cache. There is very less network traffic in this case.
- Proxy Side: In this case, there is a proxy server between client and server that maintains the cache. It can be used to cache results for multiple services with less overhead.
- Server Side: In this case, server provides caching with tools like Memcache or Redis. It is very opaque to clients. With multiple clients, this is the best strategy for caching.
52. What is CAP theorem?
Eric Brewer published CAP theorem in a paper that states that it is impossible for a distributed computing system to simultaneously provide all three guarantees:
- Consistency: All nodes see the same data at the same time.
- Availability: Every request receives a response about whether the operation is success or failure.
- Partition tolerance: The system continues to operate despite arbitrary partitioning due to network failures.
Most of the systems have CP or AP. For a system to run on a network, it needs P i.e. Partition Tolerance. So CA is often ruled out.
Between CP and AP, AP systems are easier to scale. They do not have to worry about Consistency in a distributed environment. They generally rely on eventual consistency.
53. How will you implement Service Discovery in Microservices architecture?
In Microservices architecture, there are multiple Microservices that provide APIs for different purposes. At times, it is difficult for a Developer to find whether an API already exists or not.
If there is already an API provided by another Microservice, then there is no need to rewrite it. Here comes the need for Service Discovery. Following are some ways to implement Service Discovery:
- DNS: We can simply use Domain Naming System in such a way that it is intuitive to find a service. You can either use subdomains or a domain-naming template that provides convention for naming services.
- Apache Zookeeper: It is an open source software from Apache foundation for maintaining configuration information, naming, providing distributed synchronization and providing group services. It has a hierarchical namespace for storing information about services and their configuration.
- Consul: It is another REST based tool for dynamic service registry. You can use it to register a new service, add health-checks for a service etc.
- Eureka: Netflix has provided an open source system known as Eureka that provides load-balancing capabilities in addition to service discovery. It is preferred in a Java environment in AWS cloud.
54. What is a good tool for documenting the Microservices?
Swagger is a good tool to document the APIs provided by Microservices. It is an open source tool that is very easy to use. It provides interactive documentation.
You can use Swagger annotation to add documentation in REST APIs and then use Swagger to generate a web interface. By using that Web Interface you can see the list of APIs, their inputs and even invoke these APIs to get results from these APIs.
Swagger UI is a very helpful tool for a newcomer to understand different APIs provided by a Microservice.
55. What is Eureka?
Eureka is an open source tool by Netflix for locating microservices so that load balancer can discover these services and provide fail over options to middle tier servers.
Eureka plays an important role in load balancing architecture. It can help in identifying the list of nodes in a memcache ring. It can provide additional meta data details about services.
Eureka also helps in fast rollback of services in case of any failure.
56. In which scenario, implementing Microservices architecture is not a good idea?
Microservices architecture is a great architecture if it is done correctly. To do it correct, you need to think in terms of bounded contexts and create services for each context.
If you are new to a domain then you may not have expert level knowledge in that domain to create a bounded context. This can lead to poor choice of bounded context and corresponding Microservices. Therefore, we should not try Microservices architecture in a completely new domain.
At times, it is a good idea to start with Monolith software and then gradually decompose it into Microservices.
If your organization is new and does not have support for growing number of Microservices, then it is better to go with Monolith software. With time and increased maturity of the organization, you can pick up the Microservices architecture.
57. What are the major principles of Microservices?
Microservices is a constantly growing domain. There is no fixed list of principles of Microservices. Some of the major principles are:
- Business Domain Model: A Microservice implements the functional requirements in a specific business domain that is characterized by a bounded context. It does one specific thing and does it very well.
- Automation: Often there are multiple Microservices in a system. So it is essential to use automation in deployment, testing and building of software. The more we automate, the more time we save in introducing more Microservices. Automation also save precious resources involved in maintaining multiple Microservices.
- Information hiding: Microservices hide their internal implementation details. This ensures that no assumptions are made within the system about the technology stack used by a service. This information hiding also helps in changing the implementation details at any time.
- Choreography: Most of the Microservice systems adopt choreography pattern in which there is no central command. Each Microservice behaves like a state machine and it knows how to behave in different events.
- Deployment: Microservices are small parts of software that can be independently deployed. They do not require much downtime like Monolith software.
- Isolation: Any failure in Microservices architecture can be easily isolated to the specific service that causes it. It can also help in isolating the impact of failure on related services. This can ensure that one failure does not cause complete shutdown.
58. What is Monolithic Architecture?
A Monolithic architecture is a large software system that is built over the time by creating inter-connected and highly dependent modules.
Often Monolithic architecture requires alignment and high level of coordination during deploy time.
We have to coordinate and deploy different components of a Monolithic system in a specific order. This increases complexity and the amount of time it takes to deploy software.
Making changes to Monolithic system is very difficult. One change in a monolith can cause unexpected changes in other parts of the system. This requires a lot of time and effort in testing the monolith.
One advantage of Monolith architecture is that it is self-contained. Due to this many large organizations in the past have opted for Monolith architecture.
In general, in the initial phases of a startup, there is a tendency to go for Monolith development approach. If the team is new to domain, they may not have enough knowledge to create Microservices for a new domain.
59. What is an API Gateway?
API Gateway is a service from Amazon in AWS cloud. This is used for creating, publishing, monitoring and maintaining secure APIs in cloud.
It is an important part of Microservices architecture in AWS. This works as a “front door” for applications to access resources in AWS cloud.
API Gateway supports services at a large scale as well as concurrent API calls.
We can also create REST endpoints for existing services by using API Gateway.
It supports request throttling, traffic monitoring etc features to manage Microservices architecture very well.
60. Is Microservices architecture good for a single server application?
Let us think what are your options for a Single server application.
- Develop a Monolith application with UI, Backend and configuration parts.
- Develop SOA based application with XML services.
- Develop a Node application.
There can be many more options, but for simplicity sake let us consider only 3 options.
In future, if client asks for more features, we can keep adding features to same Monolith application. After some time, let say client gets a surge in traffic and becomes a big company, will we be able to scale the single server application? Most likely not.
If we go for Microservices approach, we can use same application with multiple clients. In future, if a client asks for additional features, we may add another Microservice to serve a new feature. In this way we will have a good product offering.
In case of Microservice architecture, if we need to scale the application we can do it in no time.
Same service can work in Cloud as well as in dedicated Data center.
Microservices is the right approach because its benefits are quite important.
61. What is the difference between REST and Microservices?
REST is one of the ways to implement Microservices. You can implement Microservices in multiple ways.
REST over HTTP is the most popular way to implement Microservices nowadays.
You can use REST for other purposes as well. REST is used in web apps as well as in API design. Many MVC applications also use REST to serve business data.
Microservices is an architecture style to build large scale applications that can be scaled up independently.
In Microservices we follow certain design patterns to make it loosely coupled.
Also there are certain principles and best practices of Microservices that help in building a resilient application.
In a nutshell REST is a medium to build Microservices.
62. What are some good ways of building Microservices using Java?
Spring Boot is a very good option to build a Microservice in Java programming language.
Remember, a Microservice can be implemented in any programming language.
But you need to provide access of your Microservice to clients.
Due to this we need some sort of Container or Server. Tomcat server is a popular choice for this in Java.
In Spring Boot there is support for Tomcat as well as Microservice architecture on HTTP protocol.
So it is a good option to select following stack for building Microservices:
- HTTP Protocol
- Tomcat Server
- Spring Boot Framework
- Java Language
- Docker Container
63. How will you run multiple Microservices on a single Tomcat container with the same port?
We can simply implement each Microservice as a separate endpoint and deploy within same Tomcat container. But this will essentially defeat the main purpose of Microservices architecture.
We want to use Microservices architecture so that we can scale it independently of any other Microservice.
Therefore, it is best to run separate Microservices in different Tomcat containers.
64. What is the relation between Docker and Microservices?
Let us understand the relation between Docker and Microservices by an analogy.
Docker is a Cup (Container) and Microservice is the liquid that we pour into it!!
We can pour different type of liquids in same cup. But it will get mixed up. Similarly, we can run many Microservices in same Docker container. But it is not an advisable approach. Because it will give us a jumbled set of Microservices.
Docker is a light-weight software, therefore, it is best to keep one Microservice per Docker container.
We can pour same liquid in multiple cups. Similarly, we can run same Microservice in multiple Docker containers. Multiple clients can use Microservice from different containers at the same time.
65. Is it correct for a single team to own multiple Microservices?
As per Industry practices, a team can develop a Microservice in 2 weeks to 2 months duration. Let say a team develops a Microservice in 2 months, what would they do afterwards?Will they be occupied with supporting just one Microservice?
No. The team will go on to create more Microservices. And, team will keep supporting the Microservices they have already developed.
Therefore, it is correct for a single team to own multiple Microservices.
Other teams can change the Microservices owned by a team, but ownership always stays with one master team.
66. Can we use Microservices architecture for mobile app development?
Yes, Microservices Architecture is very well suited for mobile app development.
It is a very popular design practice to develop REST over HTTP Microservices for mobile applications.
Some of the benefits of this approach are:
- We can use these services in multiple mobile devices ranging from smart phones to tablets etc.
- We can support different operating systems like- iOS, Android etc from same Microservice.
- With same backend Microservice, we can support multiple versions of software. E.g. multiple iOS and Android versions can be supported.
- We are free to change the implementation of a Microservice without worrying about its impact on the Mobile app.
67. Do we need special Microservices framework to develop Microservices?
We do not need a special Microservices framework for developing Microservices.
Microservices are very popular option for Software architecture. But there are very few options to build Microservices.
One reason for this is ever changing scene of Microservices. There are new design patterns and best practices that gets added to Microservices architecture.
We can start with REST over HTTP with a language of our choice like-Java, Python etc.
As long as we follow the best practices like- Bulkhead pattern, Blue Green deployment etc. we can use Microservices for our software development needs.
68. How will you attain high availability with Microservice API gateway?
There are many options in Amazon Web Services (AWS) to build a Microservices based system with high availability. We can use API Gateway to build the APIs. But these options are very helpful in creating a Highly Available service.
Some of these options are:
- Elastic IPs: We can failover gracefully by using Elastic IPs in AWS. An Elastic IP is a static IP that is dynamically re-mappable. We can quickly remap and failover to another set of servers so that application traffic is routed to the new set of servers. It is also very useful when we want to upgrade from old to new version of software.
- Availability Zones: We can use multiple Availability Zones to introduce resiliency in AWS system. An Availability Zone is like a logical datacenter. By deploying application in multiple availability zones, we can ensure highly availability of a Microservice.
- Amazon Machine Image: We can maintain an Amazon Machine Image for a Microservice to restore and clone environments easily in a different Availability Zone. We can use multiple Database slaves across Availability Zones and setup hot replication with these Machine images.
- Amazon CloudWatch: This is a real-time open source monitoring tool in AWS that provides visibility of a service in AWS cloud. We can take appropriate actions in case of hardware failure or performance degradation by setting alerts on CloudWatch.
- Auto scaling: We can maintain an auto-scaling group to maintain a fixed number of servers for a Microservice. In case of failure or performance degradation unhealthy Amazon EC2 instances are replaced by new ones.
69. What are the popular benchmark systems for evaluating performance of Microservices?
Microservices are nothing new when it comes to implementation. It is same REST service that you develop in a language of your choice. You can develop a Microservice in Java, Javascript, PHP, and Python etc.
Any tool and benchmark that you use for evaluating a REST service in a language of your choice is good enough for Microservices performance as well.
A few very popular options to evaluate Microservices performance are:
- AppDynamics
- NewRelic
- DynaTrace
70. What is the right approach to test a Microservice component that calls a legacy system?
First of all we have to determine, how are we calling legacy system from a Microservice.
Is it a synchronous call or an asynchronous call?
If we are calling it asynchronously, then it should not be an issue. We can simply stub the interface with legacy system and test the Microservice.
If we are calling it synchronously, then we need to find the right testing strategy.
Generally, it is not a good practice to call a legacy system from a Microservice synchronously. Calling a legacy system asynchronously is the preferred option.
In case of synchronous communication we generally create an Adaptor service to communicate with the legacy system. This Adaptor service provides mock APIs that are called by Microservice.
With an Adaptor, it is easier to test the legacy system, without worrying about any changes to it. Also it is a quick method of testing.
71. How do Microservices make use of domain-driven design?
A Microservice is a self-contained system that serves one specific purpose very well. Domain Driven Design (DDD) is mainly used to define and design such a system.
To create a Microservice, we have to first understand the exact problem and domain that will be served by the Microservice.
Then we define our entities and their interaction with DDD approach. One good option is to describe our design and domain with Ubiquitous language. It is very easy to communicate between multiple parties with this language.
Product, Architect, Developer and Tester, all of them can use Ubiquitous language to communicate the Domain Driven Design based system.
Once the vocabulary and concepts of our domain are defined, it is easier to create a Microservice and APIs to serve this domain.
72. Do we have to use only Java for implementing Microservices?
A Microservice has nothing to do with Java. One has to first think about the design of Microservice and how it interacts with the rest of the system.
When it comes to implementation we can choose any language to write our Microservice. The beauty of Microservice architecture is that we are not bound to one language. If we feel trapped in Java, we can use any other language to implement it. We can easily compare the two implementations of same Microservice.
Coming back to original question, Java is the most popular language these days. It is much easier to find software developers in Java. It is much easier to find programming resources and libraries for working in Java. It is easier to find cloud providers who can scale Java based Microservices.
If we want to do all by ourselves, and do not want to enjoy the benefits of a popular language like Java, then we can choose any language of our choice to implement Microservice.
Therefore, it is the choice of a team to pick the language and technology for implementing a Microservice.
Always remember that a Microservice has to be designed in a language agnostic way.
73. Can you use REST for choreography or are you limited to orchestration in Microservices architecture?
Selecting between Choreography and Orchestration of Microservices is an important decision for architecture.
For Orchestration, we can create a Microservice that does the Orchestration of other Microservices. It just maintains the state of each step and sequence of overall workflow. It never maintains any application data.
Application logic and data resides in the Microservice being orchestrated. This helps in creating a loosely coupled system.
In Orchestration, the important concept to remember is idempotency of a service. We can call a service with same payload multiple times, but it will give us same result. In this way, Orchestration service can call others in asynchronous mode.
It is possible to do Orchestration as well as Choreography by using REST services.
In long run, Choreography is very good when we have a handful of services. For a large set of Microservices, some service has to play the role of Orchestration Service.
74. How will you store data in Microservice architecture?
In Microservice architecture, each Microservice stores its data within itself. But that does not mean that each instance of same Microservice will have its own data store.
For performance improvement, if we implement Sharding then each instance of same Microservice maintains its own shard. The data specific to a Microservice instance is stored in its shard.
There are scenarios when we have to keep a common data-store between Microservices. This is generally done for Microservices that are computation intensive. In such a scenario, we implement a Microservice to cache the data that does not get updated very often.
75. What is the difference between decoupling and tight coupling in Microservice architecture?
We do not define relationships between Microservices in terms of decoupling and tightly coupling.
Relationships between Microservices are either loosely coupled in asynchronous mode or tightly coupled with orchestration.
In asynchronous mode, one Microservice can keep working even when other Microservice is down or slow. It is also used to create a pipeline flow in which there are different workloads on different micro services. Each Microservice can handle its workload in its own time according to Service Level Agreement it provides.
In orchestration mode, one Microservice will call multiple Microservices to complete a task. All the Microservices should be up to make the task complete. This leads to a tightly coupled architecture. The way out in this case is to make the flow idempotent. It means if some service is down during orchestration then we can mark that step as failed and mark whole task as incomplete. In second pass, we can pick up incomplete tasks and start from the point where it failed last time.
Coming back to original question, Decoupling and tight coupling are just two opposite words.
76. How is Microservices architecture different from web services?
Microservices is a new software architecture. It is based on web services. But it can be any service implemented as an independent feature that has its own database and can be deployed independently.
In a Web service we just create a service for an application that can be accessed by web protocols.
Microservices are generally implemented in REST over HTTP protocol. Webservice can be implemented in REST, SOAP etc.
Many new companies like Netflix, Amazon, Wal-Mart etc use Microservices in their enterprise level software.