微服务的实例的网络位置都是动态分配的,而且因为扩展、失效和升级等需求,服务实例会经常动态改变,因此,需要一种更加复杂的服务发现机制。
目前有两大类服务发现模式:客户端发现和服务端发现。
1. 客户端发现模式 当使用客户端发现模式时,客户端负责决定相应服务实例的网络位置,并且对请求实现负载均衡。客户端从一个服务注册服务中查询,其中是所有可用服务实例的库。客户端使用负载均衡算法从多个服务实例中选择出一个,然后发出请求。
服务实例的网络位置在启动时注册到服务注册表中,并且在服务终止时从注册表中删除。
服务实例注册信息一般是使用心跳机制来定期刷新的。
客户端发现模式相对比较直接,除了服务注册表,没有做其它改变。除此之外,因为客户端知道可用服务注册表信息,因此客户端可以通过使用哈希一致性(hashing consistently)变得更加聪明,更加有效的负载均衡。
这种模式最大的缺点是需要针对不同的编程语言注册不同的服务,在客户端需要为每种语言开发不同的服务发现逻辑。
成功案例:Netflix OSS 使用了客户端发现模式。
Netflix Eureka 是一个服务注册表,为服务实例注册管理和查询可用实例提供了REST API接口。Netflix Ribbon 是一种IPC客户端,与Eureka 合作工作实现对请求的负载均衡。
2. 服务端发现模式 客户端通过负载均衡器向某个服务提出请求,负载均衡器向服务注册表发出请求,将每个请求转发给可用的服务实例。跟客户端发现一样,服务实例在服务注册表中注册或者注销。
服务端发现模式最大的优点是客户端无需关注发现的细节,客户端只需要简单的向负载均衡器发送请求,实际上减少了编程语言框架需要完成的发现逻辑。
3. 服务注册表 服务注册表是服务发现很重要的部分,它是包含服务实例网络地址的数据库。服务注册表需要高可用而且随时更新。客户端可以缓存从服务注册表获得的网络地址。然而,这些信息最终会变得过时,客户端也无法发现服务实例。因此,服务注册表由若干使用复制协议保持同步的服务器构成。
服务注册表例子:
- etcd – 是一个高可用,分布式的,一致性的,键值表,用于共享配置和服务发现。两个著名案例包括Kubernetes和Cloud Foundry。
- consul – 是一个用于发现和配置的服务。提供了一个API允许客户端注册和发现服务。Consul可以用于健康检查来判断服务可用性。
- Apache ZooKeeper – 是一个广泛使用,为分布式应用提供高性能整合的服务。
4. 服务注册方式 4.1 自注册方式当使用自注册模式时,服务实例负责在服务注册表中注册和注销,并且,服务实例也要发送心跳来保证注册信息不会过时。下图描述了这种架构:
自注册模式的优点是相对简单,不需要其他系统功能。
自注册模式的缺点是把服务实例跟服务注册表联系起来,必须在每种编程语言和框架内部实现注册代码。
4.2 第三方注册方式 当使用第三方注册模式时,服务实例并不负责向服务注册表注册,而是由另外一个系统模块,叫做服务管理器,负责注册。
服务管理器通过查询部署环境或订阅事件来跟踪运行服务的改变。
当管理器发现一个新可用服务,会向注册表注册此服务。
服务管理器也负责注销终止的服务实例。
下图是这种模式的架构图。
参考文献:
1. http://dockone.io/article/771