本文来自Nginx官方博客,这是微服务架构序系列的第四篇文章。做者总共发布了七篇关于微服务的系列文章,在第一文章中介绍了传统的单体式应用的不足,以及微服务架构的优点与挑战。在第二和第三骗文章中描述了微服务内部通讯方面的内容。在这篇文章中,主要探讨微服务系统的服务发现的相关问题。nginx
咱们能够想象一下,当咱们须要远程的访问REST API或者Thrift API时,咱们必须得知道服务的网络地址(IP Address和port)。传统的应用程序都是运行在固定的物理机器上,IP Address和端口号都是相对固定的。能够经过配置文件方式来实现不按期更新的Ip Address和端口号。可是,在基于云的微服务应用中,这是一个很是难以解决的问题。以下图所示:算法
在基于云的微服务应用中,服务实例的网络地址(IP Address和Port)是动态分配的,而且因为系统的auto-scaling, failures 和 upgrades等因数,一些服务运行的实例数量也是动态变化的。所以,客户端代码须要使用一个很是精细和准确的服务发现机制。服务器
有两种主要的服务发现方式:客户端发现(client-side discovery)和服务器端发现(server-side discovery)。网络
在使用客户端发现方式时,客户端经过查询服务注册中心,获取可用的服务的实际网络地址(IP Adress 和 端口号)。而后经过负载均衡算法来选择一个可用的服务实例,并将请求发送至该服务。下图显示了客户端发现方式的结构图:架构
在服务启动的时候,向服务注册中心注册服务;在服务中止的时候,向服务注册中心注销服务。服务注册的一个典型的实现方式就是经过heartbeat机制定时刷新。Netflix OSS 就是使用客户端发现方式的一个很好的例子。 Netflix Eureka是一个服务注册中心。它提供了一个管理和查询可用服务的 REST API。 负载均衡功能是经过Netflix Ribbon(是一个IPC客户端)和Eureka一块儿共同实现的。在文章的后面将深刻的介绍Eureka。负载均衡
客户端发现方式的优缺点。因为客户端知道全部可用的服务的实际网络地址,因此能够很是方便的实现负载均衡功能(好比:一致性哈希)。可是这种方式有一个很是明显的缺点就是具备很是强的耦合性。针对不一样的语言,每一个服务的客户端都得实现一套服务发现的功能。分布式
另一种服务发现的方式就是Server-Side Discovery Pattern,下图展现了这种方式的架构示例图:ide
客户端向load balancer 发送请求。load balancer 查询服务注册中心找到可用的服务,而后转发请求到该服务上。和客户端发现同样,服务都要到注册中心进行服务注册和注销。AWS的弹性负载均衡(Elastic Load Balancer–ELB)就是服务端发现的一个例子。ELB一般是用于为外网服务提供负载平衡的。固然你也可使用ELB为内部虚拟私有云(VPC)提供负载均衡服务。客户端经过使用DNS名称,发送HTTP或TCP请求到ELB。ELB为EC2或ECS集群提供负载均衡服务。AWS并无提供单独的服务注册中心。而是经过ELB实现EC2实例和ECS容器的注册的。微服务
NGINX不只能够做为HTTP反向代理服务器和负载均衡器,也能够用来做为一个服务发现的负载均衡器。例如,这篇博客(Scalable Architecture DR CoN: Docker, Registrator, Consul, Consul Template and Nginx)介绍如何使用Consul Template 动态的配置NGINX功能。工具
Kubernetes 和 Marathon 是在经过集群中每一个节点都运行一个代理来实现服务发现的功能的,代理的角色就是server-side discovery,客户端经过使用主机的IP Address和Port向Proxy发送请求,Proxy再将请求转发到集群中任何一个可用的服务上。
服务器端发现方式的优势是,服务的发现逻辑对客户端是透明的。客户只需简单的向load balancer发送请求就能够了。这就避免了为每种不一样语言的客户端实现一套发现的逻辑。此外,许多软件都内置实现了这种功能。这种方式的一个最大的缺点是,你必须得关心该组件的高可用性。
服务注册中心是服务发现的核心。它保存了各个可用服务实例的网络地址(IP Address和Port)。服务注册中心必需要有高可用性和实时更新功能。
上面提到的 Netflix Eureka 就是一个服务注册中心。它提供了服务注册和查询服务信息的REST API。服务经过使用POST请求注册本身的IP Address和Port。每30秒发送一个PUT请求刷新注册信息。经过DELETE请求注销服务。客户端经过GET请求获取可用的服务实例信息。
Netflix的高可用(Netflix achieves high availability )是经过在Amazon EC2运行多个实例来实现的,每个Eureka服务都有一个弹性IP Address。当Eureka服务启动时,有DNS服务器动态的分配。Eureka客户端经过查询 DNS来获取Eureka的网络地址(IP Address和Port)。通常状况下,都是返回和客户端在同一个可用区Eureka服务器地址。
其余可以做为服务注册中心的有:
etcd ----- 高可用,分布式,强一致性的,key-value,Kubernetes和Cloud Foundry都是使用了- - etcd。
consul -----一个用于discovering和 configuring的工具。它提供了容许客户端注册和发现服务的API。Consul能够进行服务健康检查,以肯定服务的可用性。
zookeeper ------ 在分布式应用中被普遍使用,高性能的协调服务。 Apache Zookeeper 最初为Hadoop的一个子项目,但如今是一个顶级项目。
咱们已经了解了服务注册中心的概念,接下来咱们看看服务是若是注册到注册中心的。有两种不一样的方式来处理服务的注册和注销。一种是服务本身主动注册-本身注册(self-registration)。另外一种是经过其余组件来管理服务的注册-第三方注册(third-party registration)。
使用Self-Registration的方式注册,服务实例必须本身主动的到注册中心注册和注销。好比可使用heartbeat机制了实现。下图为这种方式的示意图:
Netflix OSS Eureka client就是使用这种方式进行服务注册的。Eureka的客户端处理了服务注册和注销的全部工做。
Self-Registration方式的优缺点:一个明显的优势就是,很是简单,不须要任何其它辅助组件。而缺点也是比较明显的,使得各个服务和注册中心的耦合度比较高。服务的不一样语言的客户端都得实现注册和注销的逻辑。另外一种服务注册方式,能够达到解耦的功能,就是third-party registration方式。
使用Third-Party方式进行服务注册时,服务自己没必要关心注册和注销功能。而是经过其余组件(service registrarhandles)来实现服务注册功能。能够经过如事件订阅等方式来监控服务的状态,若是发现一个新的服务实例运行,就向注册中心注册该服务,若是监控到某一服务中止了,就向注册中心注销该服务。下图显示了这种方式的结构图示意图:
third-party Registration方式的优势是使服务和注册中心解耦,不用为每种语言实现服务注册的逻辑。这种方式的缺点就是必须得考虑该组件的高可用性。
在微服务的应用系统中,服务实例的数量是动态变化。各服务实例动态分配网络地址(IP Address 和Port)。所以,为了为客户端可以访问到服务,就必需要有一种服务的发现机制。
服务发现的核心是服务注册中心。服务注册中心保存了各个服务可用的实例的相关信息。服务注册中心提供了管理API和查询API。使用管理API进行服务注册、注销。系统的其余组件能够经过查询API来得到当前可用的服务实例信息。
有两种主要的服务发现方式:客户端发现(client-side service discovery)和服务端发现( server-side discovery)。在使用客户端服务发现的方式中,客户经过查询服务注册中心,选择一个可用的服务实例。在使用服务器端发现系统中,客户访问Router/load balancer,经过Router/load balancer查询服务注册中心,并将请求转发到一个可用服务实例上。
服务注册和注销的方式也有两种。一种是服务本身主动的将本身注册到服务注册中心,称为self-registration。另外一种是经过其余组件来处理服务的注册和注销,称为third-party registration。
在有些环境中,服务发现功能须要本身经过服务注册中心(好比:Netflix Eureka, etcd, Apache Zookeeper)实现,而有些环境中,服务发现功能是内置的。例如,Kubernetes和Marathon。
Nginx能够做为HTTP反向代理和负载平衡器,也能够用来做为一个服务发现的负载均衡器。经过向nginx推送routing information来修改nginx的配置,好比使用:Consul Template动态修改NGINX的配置. NGINX Plus 也支持动态修改配置功能。
在从此的文章中,咱们将继续深刻分析微服务的其余方面的内容。
原文做者发布的关于微服务系列文章的地址:(点击译文连接查看)
Introduction to Microservices
Building Microservices: Using an API Gateway
Building Microservices: Inter-Process Communication in a Microservices Architecture
Service Discovery in a Microservices Architecture
Event-Driven Data Management for Microservices
Choosing a Microservices Deployment Strategy
Refactoring a Monolith into Microservices
【做者信息】
原文做者:Chris Richardson,他是早期基于Java的Amazonite EC2 PaaS 平台 CloudFoundry 的创始人,如今他为企业提供如何开发和部署应用的咨询服务。
原文连接:https://www.nginx.com/blog/service-discovery-in-a-microservices-architecture/
翻译自MaxLeap团队_云服务研发成员:Lam Yu【注】原文解释连接过多,放置于译文处,如需查考,请点击译文查看:译文连接