The cause of the problem
Single machine Era , Most of the traditional software is single / Megalithic architecture (Monolithic). We're going to a code repository CODE
, This can lead to application expansion , Difficult to understand and modify , And limited expansion , There are many problems, such as the inability to scale on demand . How does single architecture solve the problem of multi person cooperation ? modularization , Yes , Split by function , Programming interface is defined between modules (API)
, They care about each other's functions, not their implementation .
With the development of the times , The single computer program encounters the double bottleneck of computing power and storage , Distributed architecture emerges as the times require . Monomer application through function name ( identification ) You can easily complete local function calls , In a distributed system , service
(RPC/RESTful API) Took on a similar role , But the service name alone is not enough to request service , Service name is just service capability ( Service type )
Identification of , You also need to indicate where the service is located on the network , Service instances deployed in the cloud IP
It's dynamically allocated , Expansion and contraction , Failures and updates complicate the problem , The static configuration service instance cannot adapt to the new changes , Need more refined service governance capabilities , In order to solve or simplify this problem , As a basic capability, service discovery is abstracted and provided , It tries to make the request network service as simple and transparent as calling local functions .
Service as function ( function )
. It's just that services are closely linked to the Internet , The term "network service" will appear , Service providers publish services over the web , Service consumers request services over the network , Distributed system breaks through the limitation of computing power and storage , The stability of the system is improved , It makes it possible for high concurrency and high availability of massive services , But it also increases software complexity , Introducing software layering , load balancing , Microservices , Service discovery
/ government , Distributed consistency and other new problems and challenges .
Service sub service provider (Service Provider) And service consumers (Service Consumer)
, If we want to provide massive service capability , A single service instance is obviously not enough , If you want to provide thousands of services , There needs to be a place to record the mapping of the service name to the list of service instances , therefore , It is necessary to introduce a new role ： Service intermediary , The service broker maintains a service registry
(Service Registry), The registry can be understood as a service dictionary ,key It's the service name ,value Is the list of service provider instances ;
Service registry is a bridge between service providers and service consumers , It maintains information such as the latest network location of the service provider , It is also the core part of service discovery .
When the service starts , Register service information (put) To service registry ; At the end of the service , Remove from service registry (remove) Own service information .
When a service consumer requests a service , First go to the service registry and query by name (get) List of service providers , Then select a service instance from the list , Request service from the instance .
The greatest truths are the simplest , This is the simplest service discovery model , It is also the basic principle of service discovery , thus , It seems that everything is OK, But in fact, there are still several problems that have not been clarified .
Problems and Solutions
* First question , If not, stop the service , But by the system kill
fall , It has no chance to notify the service registry to delete its service information , In this way, the registry has an additional piece of information pointing to the invalid service instance , But service consumers don't know , What should I do? ? The solution is simple ： Keep alive
(keepalive), Service provider regular ( For example, every 10 second ) Send to service broker keepalive news , Received by service intermediary keepalive Update the
keepalive timestamp, The service intermediary regularly checks the timestamp, If it is overdue, the service instance will be removed from the registry .
* The second question , How to inform service consumers of changes in service instance list ? There are only two ways , Polling and pub-sub
. Polling is the consumer's initiative to ask whether the service intermediary service list has changed , If there is a change , The new list of services is sent to the consumer . If there are too many consumers , There is pressure on the service mediation to process polling messages , There are many in the service category , When the list of services is large , It can even become a bottleneck .
pub-sub It is the service intermediary that actively informs the service consumers , Timeliness is better than polling , The disadvantage is that it will occupy a separate thread or connection resources .
* Third question , What if the service intermediary fails ? So we have to solve the single point problem , Clusters are often used to combat this vulnerability , There are many open source solutions for service registry , such as
etcd/zookeeper/consul, Essentially, a distributed consistent database is used to store registry information , It not only solves the problem of read-write performance, but also improves the stability and availability of the system .
* Fourth question , If a service consumer uses a remote service every time, it needs to query the service mediation to obtain the instance list , Re request service , It's inefficient ? The pressure on service intermediaries is not small ?
usually , The client caches the list of service instances , This makes multiple requests to the service with the same name , There is no need to repeat the query , It not only reduces the delay, but also reduces the access pressure on the service intermediary .
* The fifth question , The foregoing keepalive
There is a gap , If the service instance is not available within this interval , Then service consumers still can't perceive it , So it is still possible to send the request to a remote network machine that cannot provide services , Naturally, it's impossible work
. We can't stop this situation fundamentally , The system needs to tolerate this error , But some improvements can be made , For example, if a request for service fails to an instance, it will be blackened , Avoid multiple requests to the same invalid service instance .
* Sixth question , How can service consumers choose one from multiple service instances ? How to ensure that multiple service requests of the same service consumer are assigned to fixed service instances ( Sometimes it's necessary )?
This is actually the problem of load balancing , There are many strategies , such as rr, priority , For example, weighted random , Consistent Hashing .
Service discovery pattern
There are two main patterns of service discovery ： Client discovery mode (client-side discovery) And server discovery mode (server-side discovery).
Client discovery mode
The client is responsible for querying the list of service instances and deciding which instance to request service from , In other words, the load balancing strategy is implemented on the client side . The model includes two parts: registration and discovery .
The service instance calls the registration interface of the service mediation to register the instance , Service instance passed keepalive Service renewal , The service broker eliminates the unavailable service instances through health check .
When a service consumer requests a service , First query the service registry for the list of service instances , The registry is a service database , To improve performance and reliability , The client usually caches the list of services (
The cache is used to ensure that the registry can continue to work after it is hung ), After getting the instance list, the client selects an instance to send a service request based on the load balancing strategy .
* direct , The client can implement load balancing strategy flexibly .
* Decentralization , Non gateway , Effectively avoid single point bottleneck and reliability degradation .
* Service discovery direct SDK Integration into client , This kind of language integration is very good , Program execution performance is also very good , Convenient for troubleshooting .
* Client and service registry coupling , Service discovery logic needs to be developed for each language and framework used by the service client .
* This intrusive integration results in any service discovery change that requires client application recompilation and deployment , Strong binding violates the principle of independence .
* When a service goes online or offline, the caller will be affected , Causes the service to be temporarily unavailable .
Server discovery mode
find ： Service consumers send service requests through load balancers , The load balancer queries the service registry , Pick a service instance , And forward the request to the service instance .
register ： Service registration / Logout can be consistent with the above client discovery mode , It can also be done through the built-in service registration and discovery mechanism of the deployment platform , Container deployment platform (docker/k8s)
It can actively discover the service instance and help the service instance to complete the registration and logoff .
Compare client discovery mode , The client using server discovery mode does not save the service instance list locally , The client does not do load balancing , This load balancer has the role of service discovery , It also takes on the role of gateway , That's why it's often called
API Gateway server .
Because the load balancer is central , So it must also be a cluster , Single instance is not enough to support high concurrent access , Service discovery and load balancing for load balancer itself usually relies on DNS.
Http The server ,Nginx,Nginx Plus It is the load balancer of this kind of service-side discovery mode .
* Service discovery is transparent to service consumers , Service consumer and registry decoupling , Service discovery without client awareness .
* The service consumer only needs to send a request to the load balancer , There is no need for programming languages and frameworks for each service consumer , Develop service discovery logic SDK.
* Since all requests are forwarded through the load balancer , Therefore, load balancer may become a new performance bottleneck .
* Load Balancer ( Service gateway ) It's central , And the central architecture will have the hidden trouble of stability .
* Because the load balancer forwards the request , therefore RT It will be higher than the client direct connection mode .
Discovery and microservices
Service Mesh Service grid is a configurable infrastructure layer serving microservice applications , It aims to deal with a lot of network-based inter process communication between services .
Service Mesh Decoupling call and communication of service gateway , In Africa mesh lower , The perception of protocol and service discovery method needs to be done by application , use mesh after , Just call it ,mesh
Control the data flow of the application through the control surface .
Mesh Service discovery is actually an upgrade of the client discovery model , be based on sidecar and pilot realization ,Sidecars, The data panel (Data Plane)
, Responsible for discovering the address list of target service instance and forwarding the request .Pilots, The control panel (Control Plane), Responsible for managing all service registration information of service registry .
Service registration model
One option is self registration of service instances , Namely self-registration pattern . Another option is for other system components to manage the registration of service instances , Namely third-party
registration pattern .
The self registration pattern is described earlier , It's simple enough , No third party components are required , The disadvantage is that you have to implement the registration code for each programming language and framework used in the service .
The third-party registration service instance will not complete the registration and cancellation by itself , It's called by another Service Registrar
Is responsible for , The component will poll the deployment environment or track subscription events to sense changes in service instances , Help service instance complete automatic registration and logoff .
The main advantage of the pattern is that it decouples the service and the service registry . There is no need to implement service registration logic for every language and framework . Service instance registration is implemented by a dedicated service set . The disadvantage is that in addition to being built into the deployment environment , It is also a highly available system component , Need to be started and managed .
If a service has too many service instances for , For example, in some head companies , A service name may correspond to tens of thousands of service instances , such , Query and comparison of service changes can be slow ,IO
More than you can imagine , usually , Can use version num To solve this problem .