Service registration and discovery in microservice architecture

Why use service discovery?

Imagine if you were writing code to call a service with a REST API or Thrift API, and your code needed to know the network address (IP address and port) of a service instance. In traditional applications running on physical hardware, the network address of the service instance is relatively static, and your code can read the network address from a configuration file that is rarely updated.

In a modern, cloud-based microservices application, this problem becomes much more complicated, as shown in the following diagram: 
When there is no service discovery, the connected service cannot be determined 
The network address of the service instance is dynamically assigned. Also, the configuration of service instances changes frequently due to automatic scaling, failures, and updates. As a result, your client-side code needs a more granular service discovery mechanism.

There are two main service discovery patterns: client-side discovery and server-side discovery. Let's first look at client-side service discovery.

Client Service Discovery Mode

When using client-side service discovery, the client is responsible for determining the network addresses of available service instances, and load balancing around them. The client sends a request to the service registry, which is a database of available service instances. The client uses a load balancing algorithm to select an available service instance to respond to the request. The following figure shows the architecture of this mode: 
Client Discovery Mode 
when a service instance is started, its network address will be written to the registry; When the service instance is terminated, it is removed from the registry. The registry of this service instance is dynamically refreshed through a heartbeat mechanism.

Netflix OSS provides a good example of client-side service discovery. Netflix Eureka is a service registry that provides a REST API for managing service instance registration and querying available instances. Netflix Ribbon is an IPC client that handles load balancing of available service instances with Eureka. Eureka is discussed in depth below.

The client-side service discovery model has advantages and disadvantages. This pattern is relatively straightforward, but apart from the service registry, there is no other dynamic part. Moreover, since the client knows the available service instances, it can be intelligent and apply explicit load balancing decisions, such as always using the hash algorithm. A major drawback of this pattern is that there is a one-to-one correspondence between clients and service registries, and client-side service discovery logic must be implemented for each programming language and framework used by the service client.

Server-side service discovery mode

The following diagram shows the architecture of this pattern. A 
Server-side service discovery mode 
client sends a request to a service through a load balancer, which queries the service registry and routes the request to an available service instance. Through client-side service discovery, service instances are registered and deregistered on the service registry.

AWS' ELB (Elastic Load Blancer) is a server-side service discovery router. An ELB is usually used to balance external traffic from the Internet, and it can also be used to balance traffic to a VPC (Virtual Private Cloud). When a client sends a request (HTTP or TCP) through ELB, DNS is used, and ELB will balance the traffic of these registered EC2 instances or ECS (EC2 Container Service) containers. Without another service registry, EC2 instances and ECS containers will only be registered on the ELB.

HTTP servers and load balancers like Nginx and Nginx Plus can also be used as server-side service discovery load balancers. For example, Consul Template can be used to dynamically configure Nginx's reverse proxy.

Consul Template periodically generates arbitrary configuration files from data stored in the Consul service registry. Whenever a file changes, a shell command is run. For example, Consul Template can generate an nginx.conf file that configures the reverse proxy, and then run a command to tell Nginx to reload the configuration. There is also a more sophisticated implementation that dynamically reconfigures Nginx Plus via the HTTP API or DNS.

Some deployment environments, such as Kubernetes and Marathon, run an agent on each host in the cluster. This proxy assumes the role of a server-side service discovery load balancer. To send a request to a service, a client routes the request through the proxy using the host's IP address and the port assigned by the service. This proxy will send requests directly to the service instances available on the cluster.

The server-side service discovery model also has advantages and disadvantages. The biggest advantage is that the details of service discovery are abstracted from the client, and the client only needs to send requests to the load balancer, and does not need to implement service discovery logic for every language and framework used by the service client; in addition, this This mode also has some problems unless the load balancer is provided by the deployment environment and is another available system component with high requirements to start and manage.

Service Registry

The service registry is a key part of service discovery. It is a database containing the network addresses of service instances and must be highly available and up-to-date. Clients can cache network addresses obtained from the service registry. However, this information eventually becomes invalid and the client cannot find the service instance. So, the service registry consists of a cluster of servers that maintain consistency through application protocols.

As mentioned above, Netflix Eureka is a good example of a service registry. It provides a REST API for registering and querying service instances. A service instance registers its network location with a POST request and re-registers with a PUT request every 30 seconds. An entry in the registry is deleted due to an HTTP DELETE request or an instance registration timeout, and the client retrieves the registered service instance via an HTTP GET request.

Netflix achieves high availability by running one or more Eureka servers in each EC2 Availability Zone. Each Eureka server running on an EC2 instance has an elastic IP address. DNS TEXT records are used to store the Eureka cluster configuration, which is actually a mapping from a list of Availability Zones to Eureka server network addresses. When an Eureka server starts, it sends a request to DNS, retrieves the configuration of the Eureka cluster, locates the node, and assigns itself an unoccupied elastic IP address.

Eureka clients (services and service clients) query DNS to find the network address of the Eureka server. The client prefers to use the Eureka server in this availability zone. If there is no Eureka server available, the client will use the Eureka server in another availability zone.

Examples of other service registrations include:

  • Etcd : A highly available, distributed, consistent key-value store for shared configuration and service discovery. Kubernetes and Cloudfoundry both use etcd;
  • Consul : A tool for discovering and configuring services. Clients can use the API it provides to register and discover services. Consul can perform monitoring detection to achieve high availability of services;
  • Apache Zookeeper : A commonly used high-availability coordination service designed for distributed applications. Zookeeper was originally a sub-project of Hadoop and is now a top-level project.

Some systems, such as Kubernetes, Marathon and AWS do not have an explicit service registry component, this functionality is built into the infrastructure.

Let's take a look at how service instances are registered in the registry.

Service Registration

As mentioned earlier, service instances must be registered and deregistered from the registry, and there are many ways to handle the registration and deregistration process. One option is for service instances to register themselves, the self-registration pattern. Another option is for other system components to manage the registration of service instances, ie third-party registration mode.

The Self-Registration Pattern

在self-registration模式中,服务实例负责从服务注册表中注册和注销。如果需要的话,一个服务实例发送心跳请求防止注册过期。下图展示了这种模式的架构: 
self-registration mode 
Netflix OSS Eureka客户端是这种方式的一个好例子。Eureka客户端处理服务实例注册和注销的所有问题。Spring Cloud实现包括服务发现在内的多种模式,简化了Eureka的服务实例自动注册。仅仅通过@EnableEurekaClient注释就可以注释Java的配置类

self-registration模式同样也是优劣并存。优势之一在于简单,不需要其它组件。缺点是服务实例和服务注册表相对应,必须要为服务中用到的每种编程语言和框架实现注册代码。

第三方注册模式(The Third-Party Registration Pattern)

在third-party registration模式中,服务实例不会自己在服务注册表中注册,由另一个系统组件service registrar负责。service registrar通过轮询部署环境或订阅事件去跟踪运行中的实例的变化。当它注意到一个新的可用的服务实例时,就会到注册表中去注册。service registrar也会将停止的服务实例注销,下图展示了这种模式的架构。 
Third-party registration model 
service registrar的一个例子是开源的Registrator项目。它会自动注册和注销像Docker容器一样部署的服务。Registrator支持etcd和Consul等服务注册。

另一个service registrar的例子是NetflixOSS Prana。主要用于非JVM语言编写的服务,它是一个和服务实例配合的『双轮』应用。Prana会在Netflix Eureka上注册和注销实例。

service registrar是一个部署环境的内置组件,由Autoscaling Group创建的EC2实例可以被ELB自动注册。Kubernetes服务也可以自动注册。

third-party registration模式主要的优势在于解耦了服务和服务注册表。不需要为每个语言和框架都实现服务注册逻辑。服务实例注册由一个专用的服务集中实现。缺点是除了被内置到部署环境中,它本身也是一个高可用的系统组件,需要被启动和管理。

总结

在一个微服务应用中,服务实例在运行时的配置也会动态变化,包括他们的网络地址。为了满足客户端向服务发送请求的需要,必须要实现服务发现机制。

服务发现的关键部分是服务注册表。服务注册表是一个可用的服务实例的数据库。服务注册表提供了一个管理API和一个查询API。服务实例的注册和注销通过管理API实现,查询API用来寻找可用的服务实例。

有两种主要的服务发现模式:客户端服务发现和服务器端服务发现。客户端服务发现系统中,客户端查询服务注册表,选择一个可用的实例,响应一个请求;在服务器端服务发现系统中,客户端通过一个路由器发送请求,这个路由器会去查询服务注册表,并将请求发送给可用的实例。

有两种形式可以实现服务实例的注册和注销,一种是self-registration模式,一种是third-party registration模式。

一些部署环境中,需要通过类似Netflix Eureka,etcd或Apache Zookeeper的组件,启动自己的服务发现基础设施。其它的部署环境中,服务发现是内置的。比如,Kubernetes和Marathon处理服务实例的注册和注销,还会在每个集群host上运行一个代理,作为服务器端服务发现路由器的角色。

一个HTTP反向代理和Nginx也可以被用做服务器端服务发现负载均衡器。服务注册表可以推送路由信息到Nginx,引起配置更新,比如可以用Consul Template。Nginx Plus支持动态的重配置机制,可以从注册表中拉取服务实例相关的信息,还提供了远程配置的API。

 

微服务与微服务间分布式调用最主要的概念便是: protocol-aware heterogeneous interoperability; 各微服务可各自拥有自身的 platform (Java,C#, Scala…等等), 但, 各微服务间却只能藉由单一共同的协议 (protocol); 如: REST; 进行分布式的调用 

 

微服务架构的产品或许会有数百甚至数千个微服务所构成。所以, 部署微服务时, 便很难经由手工来完成, 而必须相当程度的依赖自动化的 DevOps 工具。

 
 服务注册与发现  部署  监控
Zookeeper
Doozer
Etcd
SmartStack
Eureka
NSQ
Serf
Spotify
DNS
SkyDNS
Consul
 Cloud Foundry
Gradle
Docker
Docker Hub
Docker Machine
Kitematic
Docker Compose
Docker Swarm
AWS
Jenkins
Continuum
Hudson
Artifactory
Terraform
Grunt
OpenShift
SonarCube
Logstash
New Relic
Graphite
Mesosphere / DCOS
Winston
Hystrix

 

Original article: Microservice Architecture

Reprinted from: http://blog.csdn.net/jiaolongdy/article/details/51188798

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326684190&siteId=291194637