微服务理论系列(一):服务发现四问四答

在开始之前,我们先来回顾下业内对于微服务架构的定义。简单来说,微服务就是用一组小服务的方式来构建一个应用,服务独立运行在不同的进程中,服务之间通过轻量的通讯机制(如 RESTful 接口)来交互,并且服务可以通过自动化部署方式独立部署。

1.什么是服务发现,在微服务架构中,服务发现的作用是什么?

之前做单体式应用开发时很少提及服务发现,因为传统单体应用动态性不强,不会频繁的更新和重新发布,也较少进行自动伸缩。传统单体应用的网络位置很少发生变化,在发生变化时,由运维人员手工更新一下它们的配置文件,也不是什么太大的问题。

而微服务架构则完全不同,微服务会被频繁的更新和重新发布,频繁的根据负载情况进行动态伸缩,微服务实例还可能受资源调度影响而从一台服务器迁移到另一台服务器。

总而言之,在微服务架构中,微服务实例的网络位置发生变化是一种常态,所以必须提供一种机制,使得服务消费者在服务提供者的网络位置发生变化时,能够及时获得最新的位置信息,一般是提供一个网络位置稳定的服务注册中心,服务提供者的网络位置被注册到注册中心,并在网络位置发生变化的时候及时更新,而服务消费者定期向注册中心获取服务提供者的最新位置信息,这就是最基本的服务发现机制。较为复杂的服务发现实现除了服务提供者的位置信息外,还可以向服务消费者提供服务提供者的描述信息、状态信息和资源使用信息,以供服务消费者实现更为复杂的服务选择逻辑。

2.服务发现的具体流程是怎样的?

服务发现的流程比较简单,去年我翻译了 Chris Richardson 的一些微服务文章,对服务发现的流程做了些基本的描述,比较完备的说,服务发现流程应该分为两种模式:

客户端发现:

  1. 服务提供者的实例在启动时或者位置信息发生变化时会向服务注册表注册自身,在停止时会向服务注册表注销自身,如果服务提供者的实例发生故障,在一段时间内不发送心跳之后,也会被服务注册表注销。
  2. 服务消费者的实例会向服务注册表查询服务提供者的位置信息,然后通过这些位置信息直接向服务提供者发起请求。

服务端发现:

  1. 第一步与客户端发现相同。
  2. 服务消费者不直接向服务注册表查询,也不直接向服务提供者发起请求,而是将对服务提供者的请求发往一个中央路由器或者负载均衡器,中央路由器或者负载均衡器查询服务注册表获取服务提供者的位置信息,并将请求转发给服务提供者。

这两种模式各有利弊,客户端发现模式的优势是,服务消费者向服务提供者发起请求时比服务端发现模式少了一次网络跳转,劣势是服务消费者需要内置特定的服务发现客户端和服务发现逻辑;服务端发现模式的优势是服务消费者无需内置特定的服务发现客户端和服务发现逻辑,劣势是多了一次网络跳转,并且需要基础设施环境提供中央路由机制或者负载均衡机制。目前客户端发现模式应用的多一些,因为这种模式的对基础设施环境没有特殊的要求,和基础设施环境也没有过多的耦合性。

3.目前都有哪些服务发现的解决方案?各有什么优缺点?

其实可选方案并不多,所以选择起来也并不纠结。DNS 可以算是最为原始的服务发现系统,但是在服务变更较为频繁,即服务的动态性很强的时候,DNS 记录的传播速度可能会跟不上服务的变更速度,这将导致在一定的时间窗口内无法提供正确的服务位置信息,所以这种方案只适合在比较静态的环境中使用,不适用于微服务。

基于 ZooKeeper、Etcd 等分布式键值对存储服务来建立服务发现系统在现在看起来也不是一种很好的方案,一方面是因为它们只能提供基本的数据存储功能,还需要在外围做大量的开发才能形成完整的服务发现方案。另一方面是因为它们都是强一致性系统,在集群发生分区时会优先保证一致性、放弃可用性,而服务发现方案更注重可用性,为了保证可用性可以选择最终一致性,这两方面原因共同导致了 ZooKeeper、Etcd 这类系统越来越远离服务发现方案的备选清单,像 SmartStack 这种依赖 ZooKeeper 的服务发现方案也逐渐发觉 ZooKeeper 成了它的薄弱环节。

Netflix 的 Eureka 是现在最流行的服务发现方案,服务端和客户端都是 Java 编写的,针对微服务场景,并且和 Netflix 的其他开源项目以及 Spring Cloud 都有着非常好的整合,具备良好的生态,如果你使用 Java 语言开发,Eureka 几乎是你的最佳选择。与 ZooKeeper、Etcd 或者依赖它们的方案不同,Eureka 是个专门为服务发现从零开始开发的项目,Eureka 以可用性为先,可以在多种故障期间保持服务发现和服务注册功能可用,虽然此时会存在一些数据错误,但是 Eureka 的设计原则是“存在少量的错误数据,总比完全不可用要好”,并且可以在故障恢复之后按最终一致性进行状态合并,清理掉错误数据。

前面为什么说 Eureka“几乎是”最佳选择,因为它还有个强大的对手 Consul。Consul 是 HashiCorp 公司的商业产品,它有一个开源的基础版本,这个版本在基本的服务发现功能之外,还提供了多数据中心部署能力,包括内存、存储使用情况在内的细粒度服务状态检测能力,和用于服务配置的键值对存储能力(这是一把双刃剑,使用它可以带来便捷,但是也意味着和 Consul 的较强耦合性),这几个能力 Eureka 目前都没有。而 Consul 的商业版本功能更为强大,如果你不介意依赖单一公司提供的商业产品,也可以从 Consul 的开源版本开始用起。

最后还有一个比较有趣的方案是 SkyDNS,这是一个结合古老的 DNS 技术和时髦的 Go 语言、Raft 算法的有趣项目,主要在 Kubernetes 里使用,因为 Kubernetes 有一层较为稳定的 Service 抽象,有点类似于问题 2 里描述的服务端服务发现方式,所以不存在 DNS 时间窗口的问题。

这里我就不对上述的各个方案做具体功能特性上的对比了,我在做方案选型时不太喜欢做这种微观对比,因为具体的功能特性是易变的,今天 Consul 出一个新功能,明天 Eureka 出一个新特性,如果依赖这个做选择,会摇摆不定,我更注重这些方案背后的一些根深蒂固的必然性,比如 ZooKeeper 永远都不会为了服务发现放弃它的强一致性,所以即使它有再多适合服务发现的功能特性,它也不会成为服务发现的优选方案,再比如 Consul 由一家商业软件公司提供,那么必然或多或少的存在商业软件的某些弊端,如果你非常在意这些弊端,Consul 再强大,你也不会选择它。

4.落地服务发现的难点是什么?

落地服务发现的难点主要来自于分布式系统本身的复杂性和对业务系统的侵入性。因为几乎所有服务提供者和服务消费者都对服务发现服务存在依赖,如果服务发现服务出现问题,将会造成大范围的影响,所以服务发现服务自身的可用性至关重要。

为了保证服务发现服务本身的可用性,除了对服务发现服务进行本地的多节点部署之外,往往还需要跨越多个可用区甚至多个数据中心部署,以确保服务发现服务可以在多个层次的软硬件故障中存活。在服务提供者和服务消费者数量众多时,服务发现服务的性能也可能会成为问题。上述这些问题和分布式系统普遍存在的问题一致,只要在技术上做出充分准备,都是可以解决的,在此不做赘述。

更大的难点在某种程度上是非技术问题,现有的服务发现方案都或多或少的对业务系统存在侵入性,会改变业务系统的开发模式,例如在开发阶段需要引入特殊的客户端和服务的注册、查询过程。给开发带来新的复杂度倒不是什么特别大的问题,因为这些复杂度可以通过技术工具降低,比如普元现在在做的微服务开发平台就可以使这些开发过程中的额外工作自动化,更重要的是服务发现方案一旦确定,之后再做更换的成本会非常高,在对方案进行推广的时候,很可能会引起业务部门的担忧,并因此遇到阻力。

原文地址:https://www.cnblogs.com/weiBlog/p/10205053.html

时间: 2024-08-01 13:03:17

微服务理论系列(一):服务发现四问四答的相关文章

springcloud微服务系列之服务注册与发现组件Eureka

一.Eurake的简介二.使用Eureka进行服务的注册消费1.创建一个服务注册中心2.创建服务的提供者3.创建服务的消费者总结 一.Eurake的简介 今天我们来介绍下springcloud的核心组件Eureka,Eurake是负责微服务架构中服务治理的功能,负责各个服务实例的注册与发现. Eureka包含了服务器端和客户端组件.服务器端,也被称作是服务注册中心,用于提供服务的注册与发现. 客户端组件包含服务消费者与服务生产者.在应用程序运行时,服务生产者向注册中心注册自己的服务实例,当消费者

SpringCloud系列四:Eureka 服务发现框架(定义 Eureka 服务端、Eureka 服务信息、Eureka 发现管理、Eureka 安全配置、Eureka-HA(高可用) 机制、Eureka 服务打包部署)

1.概念:Eureka 服务发现框架 2.具体内容 对于服务发现框架可以简单的理解为服务的注册以及使用操作步骤,例如:在 ZooKeeper 组件,这个组件里面已经明确的描述了一个服务的注册以及发现操作流程,在整个 Rest 架构里面,会存在有大量的微服务的信息. 在 SpringCloud 之中使用了大量的 Netflix 的开源项目,而其中 Eureka 就属于 Netflix 提供的发现服务组件,所有的微服务在使用之中全部向 Eureka 之中进行注册,而后客户端直接利用 Eureka 进

.Net Core 商城微服务项目系列(二):使用Ocelot + Consul构建具备服务注册和发现功能的网关

1.服务注册 在上一篇的鉴权和登录服务中分别通过NuGet引用Consul这个包,同时新增AppBuilderExtensions类: public static class AppBuilderExtensions { public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app,IApplicationLifetime lifetime,ServiceEntity serviceEntity) {

.Net Core 微服务容器系列基础目录篇

1.开场白 HI,各位老铁,大家端午好,之前写了些关于.net core商城系列的文章,有点乱,今天心血来潮想着整理一下(今天只是先把目录列出来,后面的每篇文章这两天会进行重新修改的,目前先将就看下). 简单介绍一下,博主目前就职于某电商公司,目前工作用的是.net core,业余时间也会看下Java,公司内部目前也是多语言并存,毕竟很多工具和技术对于这两种语言都是相通的,所以多了解下哈. 本系列项目将会以.net core+Docker+K8s来搭建,当然你用java来改写一下也是没问题的,因

微服务架构下的服务发现

编者的话]这是关于使用微服务架构创建应用系列的第四篇文章.第一篇介绍了微服务架构的模式,讨论了使用微服务架构的优缺点.第二和第三篇描述了微服务架构内部的通讯机制.这篇文章中,我们将会探讨服务发现相关问题. 为什么要使用服务发现? 我们设想一下当正在写代码时,使用了提供REST API或者Thrift API的服务,为了完成一次服务请求,代码需要知道服务实例的网络位置(IP地址和端口).传统应用都运行在物理硬件上,服务实例的网络位置都是相对固定的.例如,代码可以从一个经常变更的配置文件中读取网络位

【微服务干货系列】使用微服务架构之前,你必须知道的

正如敏捷之父MartinFowler所说的那样,单体架构和微服务并非简单的二选一,两者都是模糊的定义.这就意味着大多数系统都将在一个模糊的边界区域.非常多开发团队已经认识到微服务架构比单体架构更优越.可是也有其它团队感觉到这是一种消弱生产力的负担,就像不论什么软件架构,微服务架构相同有利弊.为了能做出一个明智的选择.你必须了解这些应用并将它们运用到你特定的环境中. 微服务的"定义" 假设须要准确的给微服务下一个定义,抱歉,笔者找了非常长时间,也没有一个准确的定义,最接近微服务的定义来自

微服务探索与实践—服务注册与发现

前言 微服务从大规模使用到现在已经有很多年了,从之前的探索到一步步的不断完善与成熟,微服务已经成为众多架构选择中所必须面对的一个选项.服务注册与发现是相辅相成的,所以一般会合起来思索.其依托组件有很多,比如Zookeeper,Consul,Eureka等等. 本文,我们将探讨服务注册和发现的概念及其使用机制,以使得微服务能够在不知道其确切位置(通常是URL)的情况下消费其他服务.由于本文主要是个人实践的一些总结,总会有不足之处,也希望各位看官帮忙完善.本系列前一篇文章请移步总述 服务注册与发现探

微服务~Eureka实现的服务注册与发现及服务之间的调用

微服务里一个重要的概念就是服务注册与发现技术,当你有一个新的服务运行后,我们的服务中心可以感知你,然后把加添加到服务列表里,然后当你死掉后,会从服务中心把你移除,而你作为一个服务,对其它服务公开的只是服务名称,而不是最终的服务地址URL,这对于云平台,容器化架构来说是非常重要的! 安装单独的Eureka服务(server) 服务注册-aspnetcore建立Eureka客户端(client) 服务发现-实现服务与服务的调用 一 安装单独的Eureka服务 安装tomcat,到apache官网ht

ASP.NET Core 微服务初探[1]:服务发现之Consul

在传统单体架构中,由于应用动态性不强,不会频繁的更新和发布,也不会进行自动伸缩,我们通常将所有的服务地址都直接写在项目的配置文件中,发生变化时,手动改一下配置文件,也不会觉得有什么问题.但是在微服务模式下,服务会更细的拆分解耦,微服务会被频繁的更新和发布,根据负载情况进行动态伸缩,以及受资源调度影响而从一台服务器迁移到另一台服务器等等.总而言之,在微服务架构中,微服务实例的网络位置变化是一种常态,服务发现也就成了微服务中的一个至关重要的环节. 服务发现是什么 其实,服务发现可以说自古有之,我们每