Diving deep inside microservices
World of micro-services

Diving deep inside microservices

In the previous episode, we got to know what microservices are and how they are beneficial while developing a complex solution which needs to serve multiple features. That was more like an introduction to the world of microservices, now let’s dive deep into some core concepts.

To ensure the development and deployment of a successful microservice system, a few things need to be considered and implemented -

1. Properly Scoped Functionality and Security

Each microservice handles a single business functionality. The scope of each microservice must be defined with appropriate business requirements and define what the service will do and what not. This also includes -

  • The kind of data storage service will use and if it should use a common database or have its own.
  • Each microservice must choose the way it is going to communicate with other microservices. We will take a look at various communication methods later on.
  • What kind of users are going to interact with a service and what security measures should be provided to access the service endpoints.

2. APIs

Presenting an API to call services in some way represents the old challenge of integration. For an overall application to run properly, each of the individual services must be able to reliably send and receive data, and testing that APIs operate properly is necessary to ensure that everything hangs together. As individual services mature, they may add new functionality that requires a richer API. This, in turn, implies that the new API must be exposed alongside the old one. Absent this, every API change cascades into requiring all callers to update their code and retest, which results in the same problem that monolithic applications pose.

It’s a good idea to avoid jumping into API coding immediately. Instead, do some work on paper or whiteboards to define what a specific service must expose to operate properly.

3. Traffic Management

In the real world, a service might get overloaded, run slowly, may take more time to respond or even worse, a service might simply stop working due to a software or hardware crash. From the perspective of the calling service, it should always track its calls and be prepared to terminate them if the response takes too long. From the perspective of the called service, the API design should include the ability to send a response that indicates overload. This response typically referred to as “backpressure”, signals that the calling service should reduce or redirect its load. One important note here about managing traffic: Calling services should have a graceful way to handle a nonresponsive called service.

4. Monitoring

The monitoring system for a microservices-based application must allow for ongoing resource change, be able to capture monitoring data in a central location, and display information that reflects the frequently changing nature of microservices applications. Most microservices monitoring systems place a monitoring agent on each service instance, where it can track specific instance data. These monitoring systems can also capture application-created log information. All of this data migrates to a centralized database, where the system does cross-correlation, allowing monitoring alerts or humans to track important event data.


Managing microservices and their communication is a quite complex process and needs to be handled in a different way than monolithic applications.

1. API Gateway

API Gateway is an important part of microservices architecture. It acts as an entry point for all client requests. It acts as a reverse proxy which receives a request from clients and routes them to appropriate microservices. API gateway comes with its own set of important functions-

  1. Routing: Routes requests to appropriate microservices based on URI, and header. Also provides load balancing to make sure the requests are evenly distributed for a particular microservice.
  2. Authentication & Authorization: As it's an entry point for all requests, user authentication & access can be placed for specific microservices.
  3. Caching: Cache responses from microservices to improve performance.
  4. Service Composition: It can compose responses from multiple microservices.
  5. API management: It provides a platform for monitoring API in terms of metrics, logs, etc.

As great as the Geteways sound, they have their fair share of disadvantages.

  1. Single Point of failure - As the API gateway connects the client to microservices.
  2. Increased complexity - API gateway introduces additional components & configurations and hence becomes hard to troubleshoot issues.
  3. Latency - API Gateway can introduce additional network latency because all requests must pass through it.

These disadvantages can be easily overcome by having multiple instances of Gateway service with proper monitoring. Cloud-based API gateways could be a better solution for this. There are commercial products which provide an interface to implement API gateways whereas some might prefer building their custom solution.

2. Service registry & discovery

Service discovery and registry is a key concept in microservices which allows services to dynamically discover and communicate with each other. This adds a layer of abstraction such that no two services need to know another service to get a task done.

Service Registry: A service registry is a database which keeps track of all available services in the system. Each microservice registers itself to this registry by providing some information like IP, port, metadata, and availability.

Service Discovery: Service discovery is the process of discovering the location of the services in the system. When a service needs to communicate with another service, it queries the service registry and in return, it provides the list of available instances of queried service. Using this information services communicate with each other.

Service registry and discovery enable microservices to operate independently and communicate with each other without having to know the exact location of each other. This allows for a flexible and scalable system, where new services can be added or removed easily without affecting other services in the system.

There are a few methodologies that are followed while designing microservices discovery architecture.

1. Server-Side Service Discovery: A service registry is used to maintain a list of available services, and microservices communicate with the registry to discover the location of the services they need to access. There are again two approaches to server-side service discovery.

  • Centralized Service Discovery - There is a single service registry that contains information about all available services. When a microservice needs to communicate with another service, it queries the central service registry to discover the location of the service. This requires centralized infrastructure such as load balancing to route requests to appropriate services.
  • Decentralized Service DIscovery -? Each service instance registers itself with a discovery service, which maintains a list of available services. When a microservice needs to communicate with another service, it queries the discovery service to discover the location of the service. This approach removes the need for centralized infrastructure but requires additional overhead for managing discovery service.

The main difference between these two approaches is where the information about services is stored. API gateway has to communicate with either a central registry or multiple instances of discovery services to route requests. Each approach introduces its own set of challenges in terms of information consistency.

Client-Side Service Discovery

Client-side discovery is an alternative approach where the client-side code is responsible for discovering available services and deciding which instance to communicate with. In this approach, the client-side code sends requests to a load balancer or proxy, which routes the request to an available service instance.

Server-side discovery is more suitable for larger and more complex systems, while client-side discovery may be more appropriate for simpler systems with a smaller number of services.

3. Communication

Communication is a very important part of microservices as it involves the interaction of more than a few independent entities probably hosted in different locations with different implementations. Few communication methods are used which allow these services to interact with each other.

  1. Request-Response: This is a synchronous communication pattern in which a calling service makes a request and waits for the response. This pattern is commonly used when an immediate response is required.
  2. Publish-Subscribe (Pub-Sub): This is an asynchronous mode of communication where a service publishes an event, and other services subscribe to that event. All the subscribing service gets a notification upon the event being published. This pattern is widely used in event-driven architecture and decoupled communication.
  3. Point-to-point messaging: This is an asynchronous pattern in which a service sends a message to another service without waiting for a response without getting blocked.
  4. RPC: RPC is a client-server communication model that enables a client to make a request to a remote server and receive a response synchronously or asynchronously. RPC protocols are often designed to be lightweight and efficient, which makes them well-suited for use in distributed systems where performance is a critical concern.
  5. Circuit Breaker: This is a pattern used to improve system resilience in the face of service failures. A circuit breaker monitors requests to a service and, if the service is unavailable, stops sending requests until the service is available again.

Designing and implementing effective communication patterns is crucial to ensure that services can communicate reliably and efficiently, and that the system as a whole is scalable, resilient, and maintainable.

4. Service Coordination

When multiple independent entities are involved in getting a particular task done, it is important to have appropriate coordination between them considering response and failure handling. This can be achieved by following some popular techniques.

  1. Choreography: Here each service is responsible for knowing how to interact with other services in the system. Each service knows what to send, whom to send and what to expect. This means that each service has a clear understanding of its role in the overall system, and can make independent decisions about how to interact with other services. It is more flexible and decentralized, however, it becomes more difficult to manage the interactions and overall flow of messages in complex systems.
  2. Orchestration: In this method of coordination, all services rely on a central entity (orchestrator), which is responsible for all the interactions between microservices. The orchestrator defines the flow of messages between services and is responsible for managing the state and context of the overall system. It provides a central point of control and simplifies the management of complex interactions, however, it can be more rigid and less adaptable to changes.

A system may use service choreography for simple interactions between services but rely on service orchestration for more complex workflows or business processes.

No alt text provided for this image
God of micro-services

Feeling like this! Well, we just scratched the surface. There lies a whole pandemic worth of concepts under the iceberg of microservices.

Microservices Code Structure

Once all the requirements are sorted and one begins to implement each service, it needs to be considered how the code should be written for each service. There are generally two ways to write a complete microservices system.

  1. Standard Structure: In this, the services are written in completely different repositories. This mode of writing code allows more efficient collaboration for complex systems of services as teams can be assigned to one service without worrying about affecting others. This makes it easy to test and deploy the services. However, managing multiple repositories can become complex, and coordinating changes across multiple repositories can be challenging and the common code gets repeated in each service. The common code can be written and used by making it an importable package. For example, in node js, the common code can be written and used as an npm package to be used in all services.
  2. Monorepo Structure: As the name implies, complete code for all services lives in the same repository with a sharable codebase and dependencies. But it does make it more difficult to work independently on each service as it may affect other services’ code base. One needs to be careful and needs to test other services for any breaking changes.

No alt text provided for this image
Chaos Micro-services

Conclusion

Microservices are the logical response to the shortcomings of monolithic applications in a time of frequent functionality change and constant operational churn. A microservices architecture allows much greater application flexibility and performance, but it's complex.?

In this article, we dived deep into the world of microservices. Though it was much brief overview. There are more than enough concepts in microservices that people have written a whole series of books on it. These concepts can be implemented to ensure a resilient, robust and scalable microservices system.

要查看或添加评论,请登录

Sarvaha Systems的更多文章

社区洞察

其他会员也浏览了