Editor's note "This is the fourth article on creating an app family using a microservices architecture." The first chapter introduces the model of MicroServices architecture and discusses the advantages and disadvantages of using microservices architecture. The second and third articles describe the communication mechanisms within the microservices architecture. In this article, we will explore issues related to service discovery.
Why Use service discovery?
Let's imagine that when the code is being written, the service that provides the rest API or the Thrift API is used to complete a service request, and the code needs to know the network location (IP address and port) of the service instance. Traditional applications run on physical hardware, and the network locations of service instances are relatively fixed. For example, the code can read a network location from a frequently changed configuration file.
And for a modern, cloud-based microservices application, this is a very troublesome problem. Its architecture
The network location of the service instance is dynamically allocated, and the service instance is constantly changing dynamically due to requirements such as scaling, invalidation, and upgrade, so the client code needs to use a more sophisticated service discovery mechanism.
There are currently two types of service discovery modes: Client discovery and Server discovery.
Let's talk about client discovery first.
Client Discovery Mode
When using client discovery mode, the client is responsible for determining the network location of the corresponding service instance and for load balancing the request. The client queries from a service registration service, which is a library of all available service instances. The client uses a load-balancing algorithm to select one of the multiple service instances and then makes the request.
The schema diagram for this pattern is displayed.
The network location of the service instance is registered to the service registry at startup, and is removed from the registry when the service terminates. Service instance registration information is typically refreshed using the heartbeat mechanism.
Netflix OSS provides a great client-side discovery model. Netflix Eureka is a service registry that provides a rest API interface for service instance registration management and querying available instances. The Netflix Ribbon is an IPC client that works with the Eureka contract to achieve load balancing of requests. We will discuss Eureka in detail later.
Client Discovery mode is also a distinct advantage. This mode is relatively straightforward, and there are no other factors to change except the service registry. In addition, because the client knows the available service registry information, the client can become smarter and more efficient with load balancing by using hash consistency (hashing consistently).
One of the biggest drawbacks of this model is the need to register different services for different programming languages, where the client needs to develop different service discovery logic for each language.
After we have analyzed the client discovery, we look at the server discovery.
Service-side Discovery mode
Another service discovery method is the service-side discovery mode Server-side discovery pattern. Shows the architecture diagram for this pattern:
The client makes a request to a service through a load balancer, and the load balancer makes a request to the service registry to forward each request to the available service instance. As with client discovery, the service instance is registered or unregistered in the service registry.
AWS Elastic Load Balancer (ELB) is an example of a server-side discovery router that is typically used to equalize traffic from the Internet, or to use ELB to equalize traffic inside a VPC. The client uses DNS to make a request via ELB (HTTP or TCP). The ELB load balancer is responsible for balancing the load between registered EC2 instances or ECS containers, there is no separate service registry, and EC2 instances and ECS instances are registered with ELB.
HTTP services and load balancers such as nginx can be used as server-side discovery equalizers. For example, this blog post describes how to use Consul Template to dynamically configure Nginx reverse proxies. Consul template is a tool that periodically configures the data reconstruction configuration file from the Consul template registry. When a file changes, a command is run. In the above blog, Consul template produces a nginx.conf file for configuring the reverse proxy, and then runs a command that tells Nginx to re-enter the configuration file. More complex examples can be dynamically reconfigured with the HTTP API or DNS Nginx Plus
Some deployment environments, such as Kubernetes and Marathon, run a proxy on each node of the cluster, and this agent discovers the load balancer as a server. To make a request to the service, the client routes the request through the proxy using the host IP address and the assigned port. The proxy transparently forwards the request to the service instance that is available in the cluster.
The server discovery model also has pros and cons. The biggest advantage is that the client does not need to focus on the details of the discovery, and the client simply sends the request to the load balancer, effectively reducing the discovery logic that the programming language framework needs to accomplish. Also, as mentioned above, some deployment environments offer these features free of charge.
This pattern is also flawed, except that the load balancer is another highly available system feature that requires configuration management, unless the deployment environment provides a load balancer.
Service Registration Form
The service registry is an important part of service discovery, which is the database that contains the network address of the service instance. The service registry needs to be highly available and updated at any time. The client can cache the network address obtained from the service registry. However, this information will eventually become obsolete and the client will not be able to discover the service instance. Therefore, the service registry consists of several servers that are synchronized using replication protocols.
As mentioned earlier, Netflix Eureka is a good example of a service registry that provides a REST API registration and request service instance. The service instance uses the POST request to register the network address, and every 30 seconds must use the Put method to update the registry, using an HTTP delete request or an instance timeout to log off. As you can see, the client can accept the registration service instance information using an HTTP GET request.
The Netflix achieves high availability is highly available by running one or more Eureka services in each AWS EC2 domain, and each Eureka server runs on EC2 instances with elastic IP addresses. The DNS text record is used to store the Eureka cluster configuration, which holds a list of network addresses from the available domains to a series of Eureka servers. When the Eureka service starts, the DNS request accepts the Eureka cluster configuration, confirms the companion location, assigns itself an unused elastic IP address.
Eureka Client-Service and service client-discovers the network address of the Eureka service to DNS requests, and clients prefer to use services within the same domain. However, if no service is available, the client uses the Eureka service of another available domain.
Some other service registry examples include:
etcd– is a highly available, distributed, consistent, key-value table for shared configuration and service discovery. Two notable cases include kubernetes and cloud Foundry.
consul– is a service for discovery and configuration. Provides an API to allow client registration and discovery services. Consul can be used for health checks to determine the availability of services.
Apache zookeeper– is a widely used service that provides high performance integration for distributed applications. Apache Zookeeper, originally a sub-project of Hadoop, has now become a top-level project.
In addition, as previously emphasized, some systems, such as Kubernetes,marathon and AWS, do not have a separate service registry, and for them, the service registry is just a built-in feature.
Now let's look at the concept of the service registry to see how the service instance is registered in the registry.
Service Registration Options
As mentioned earlier, service instances must be registered and unregistered in the registry, and there are several different ways to register and unregister. One way is to register the service instance itself, also known as the self-registration mode (self-registration pattern), another way is to provide service instance management for other systems, also called third-party registration mode (third registration pattern). Let's take a look at the self-registering mode.
Self-registration method
When using self-registration pattern, the service instance is responsible for registering and unregistering in the service registry. In addition, if necessary, a service instance sends a heartbeat to ensure that the registration information is not obsolete. Describes this architecture:
A good example is the Netflix OSS Eureka client. The Eureka client is responsible for processing the registration and logoff of service instances. Spring Cloud Project implements a variety of modes, including service discovery, which makes it easier to register automatically with Eureka service instances. The Java configuration class can be annotated with @enableeurekaclient.
Self-registering mode also has pros and cons. One advantage is that it is relatively simple and does not require additional system functionality. One of the main drawbacks is to associate a service instance with the service registry. The registration code must be implemented within each programming language and framework.
Another method, which does not require a connection service and registry, is the third-party enrollment mode.
Third-party registration mode
When using a third-party registration mode, the service instance is not responsible for registering with the service registry, but rather by another system module called the Service Manager, which is responsible for registering. Service Manager tracks changes in the running service by querying the deployment environment or subscribing to events. When the manager discovers a newly available service, it registers the service with the registry. Service Manager is also responsible for unregistering terminated service instances. Is the schema diagram for this pattern.
An example of a service manager is the Open source project Registrator, which automates the registration and logoff of service instances that are deployed as Docker containers. Reistrator supports a variety of service managers, including Etcd and consul.
Another example of a service manager is Netflixoss Prana, which is primarily for non-JVM language development services, also known as companion applications (sidecar application), and Prana using Netflix Eureka to register and unregister service instances.
Service Manager is a built-in module of the deployment environment. EC2 instances created with automatic expansion groups can be automatically registered from ELB, kubernetes services are automatically registered and available for discovery services.
The third-party registration model is also a pros and cons. The main advantage is that the service is separated from the service registry and does not require the service registration logic to be completed for each programming language and architecture, instead, the service instance is managed through a centralized managed service.
One drawback is that unless this service is built into the deployment environment, it is also necessary to configure the management of a highly available system.
Summarize
In a microservices application, the service instance runtime environment is dynamically changing. The instance network address is also dynamically changing, so the client must use the service discovery mechanism in order to access the service.
The key part of the service discovery is the service registry, which is the database of available service instances. The Service registry provides a registration management API and a request API. The service instance uses the Registration management API to implement registration and logoff.
The request API is used to discover available service instances, and there are two main service discovery modes: Client discovery and Server discovery.
In a system that uses client discovery, the client initiates a request to the service registry, selects an available instance, and then issues a service request
In a system discovered using the server, the client sends a request to the service registry to forward the request to an available instance by routing the forwarding request.
There are two main types of service instance registration and logoff. One is that the service instance is automatically registered in the service registry, that is, the self-registration mode, and the other is that a system module is responsible for processing registration and logoff, which is the third-party registration mode.
In some deployment environments, you need to configure your own service discovery architecture, for example: Netflix Eureka, ETCD, or Apache Zookeeper. In other deployment environments, this feature is brought in, such as Kubernetes and Marathon, which handles the registration and logoff of service instances. They also run proxies on each cluster node to realize the functionality of the server discovery router.
HTTP reverse proxies and load scales (such as nginx) can be used for service discovery load balancers. The service registry can push routing information to nginx to activate a real-time configuration update; For example, you can use the Consul Template. NGINX Plus supports an additional dynamic reconfiguration mechanism that allows you to use DNS to pull service instance information down from the registry and provide APIs for remote configuration.
In future blogs, we will also delve into other features of microservices. You can register the Nginx mailing list to get the latest product update tips.
Editor's note: This other blog, see the following address:
Introduction to MicroServices
building microservices:using an API Gateway
inter-process Communication in a microservices Architecture
Service discovery under the MicroServices architecture