一、什么是服务发现?

问题:

我们现在有多少个服务?

服务越来越多时,服务 URL 配置管理变得非常乱

服务对外的地址变了,其他所有有使用到的服务都要改地址

增加服务,增加服务实例等,都要做运维工作

1.1服务端发现模式

客户端通过服务端的负载或路由访问目标服务。

服务端负责负载和转发请求,自身或者通过第三方工具,自动发现新的服务实例,并定时检测心跳维护注册表。

优点:
      服务发现功能对于客户端而言是透明的
缺点:
      增加了一次转发,集中式的做法没有去中心化

提问:
      1.nignx/F5有服务地址列表,也有负载均衡功能,属于服务端发现吗?
            主要缺了“发现”功能,服务实例动态增减并不能主动识别

2.服务实例自己往服务端发送注册请求不可以吗?
            服务实例是服务提供者,也可能是服务消费者;如果往注册中心发送注册请求,那么也可以从注册中心拉注册表,这样直接做客户端发现不是更好?

1.2客户端发现模式

客户端自身就可以确定服务提供者的可用实例地址列表和使用负载均衡策略。

服务提供者向注册中心发送注册和心跳。
服务端只负责维护注册表,并对外提供服务。

优点:
      客户端可以灵活、智能地制定负载均衡策略
      去中心化
缺点:
      客户端与注册中心耦合,需要实现与注册中心交互的代码

二、服务发现的关键角色提取

服务提供者:
      向注册中心发送请求,发送信息
服务消费者:
      向注册中心发送请求,获取信息
注册中心:
      提供接口给服务发现客户端调用
      维护服务实例信息集合
      集群之间信息同步

三、关键角色要干些什么事情

3.1服务提供者

服务提供者:向注册中心发送请求,发送信息

1.发送请求问题:

发送请求的工具用什么,okhttp、resttemplate?
请求失败怎么办,要重试吗?重试的策略是什么?

2.注册中心地址问题:
发送信息给所有注册中心还是发送一个成功就行了?
注册中心有多个的话,优先访问哪个呢,访问失败的要记录起来下次不访问了吗?
地址写在配置里,如果有增加或调整,所有客户端都要改?

3.发送注册/心跳问题:
注册和心跳调同一个接口还是分开两个接口比较好?
注册后,除了要定时发送心跳,实例信息有改变的情况下,要发给注册中心吗?

3.1.1服务提供者-发送请求问题

作为一个中间件如何提高可扩展性?
eureka的答案是装饰器模式

JeseryClient:
执行rest请求的工具,eureka有RestTemplate的替换实现方案

统计信息:
根据请求类型进行统计,请求时间总计、请求失败次数总计等

重定向:
返回的http code是302则表示要重定向(注册中心迁移?)更换重定向的url再次发起请求,最多重定向10次

失败重试机制:
已经请求失败的server url记录下来下次不再请求;
如果失败的url过多(比如全部都失败的情况,可能是客户端网络有问题),超过阀值,则清空失败的url记录,把他们重新当成可用的url ,这里要获取注册中心地址列表,用于重试

会话:
请求失败的url记录多久,永久记录吗?使用session机制如果20分钟没请求过,则重置上面的所有机制
session有效时长20分钟左右(有随机增减)

3.1.2服务提供者-注册中心地址问题

1.发送信息给所有注册中心还是一个?
不管是AP还是CP,服务提供者只需与一个注册中心交互成功就行,服务提供者不关心注册中心之间的数据同步

2.客户端如何保证发送到任意一个注册中心成功呢?
配置多个注册中心地址,失败了就换下一个再试

3.注册中心地址变更问题
配置了多个注册中心地址后,如果注册地址有增删改怎么解决
将注册中心地址放到配置中心 或 DNS txt记录,客户端定时去刷新获取
(就算是存在本地配置文件,eureka也会开启定时任务定时去取)

3.1.3服务提供者-发送心跳/注册问题

注册后,除了要定时发送心跳,实例信息有改变的情况下,要发给注册中心吗?
eureka的答案是需要:
1.实例状态变更
2.配置信息变更
LeaseExpirationDurationInSeconds 心跳有效期
LeaseRenewalIntervalInSeconds 心跳频率
3.健康检查处理器的增减(用于获取实例状态)

3.2服务消费者

服务消费者:向注册中心发送请求,获取注册表信息

1.发送请求问题(同服务提供者)

2.注册中心地址变更问题(同服务提供者)

3.全量还是增量获取应用实例信息
如果消费者本地实例信息为空,则全量获取,否则增量获取,关键逻辑在注册中心,这里较简单

将上面结论进行汇总

3.3注册中心

注册中心:

提供接口给服务发现客户端调用

维护服务实例信息集合

集群之间数据同步

3.3.1注册中心-接口

如何做增量更新?

查询是否需要缓存?

如何做增量更新?

eureka的答案是维护一个队列 recentlyChangedQueue

细心的观众会发现,为什么接收到心跳,不会增加到recentlyChangedQueue?
队列里存的是引用类型,和应用实例列表是同一个地址,接收到心跳进行实例更新,定时维护最近变动实例队列时查到实例信息变动,然后继续将其保留在队列里,这样增量查询下次一样能查到该实例的信息

为什么要自我保护?
如果失效的实例过多,有没有可能是注册中心出了问题?

上一分钟接收到心跳总数<= 实例总数*2(默认30s一次心跳) * RenewalPercentThreshold()(默认0.85)进入自我保护则不会剔除任何实例

3.3.2注册中心-集群同步

如何做集群同步?

eureka的答案还是维护队列,这里注册、心跳、下线都会入队,批量进行同步,失败的加到失败重试队列

接收到的所有请求,都要同步吗?

要经过过滤, 每种类型只取最新一条去同步即可

注册中心地址变更
同服务发现客户端一样,定时刷新注册中心地址,然后更新集群节点

3.4架构图

四、结合Region和AZ(Available Zone)

区域(Region):
从设计而言,每个 Amazon EC2 区域都与其他 Amazon EC2 区域完全隔离。这可实现最大程度的容错能力和稳定性。在区域之间传输数据需要收费。
可用区(Availability Zone ,AZ):
如果您的实例分布在多个可用区且其中的某个实例发生故障,则您可对您的应用程序进行相应设计,以使另一可用区中的实例可代为处理相关请求。可用区由区域代码后跟一个字母标识符表示;例如,us-east-1a。

地域(Region):
不同地域的云服务器 ECS、关系型数据库 RDS、对象存储服务 OSS 内网不互通。
不同地域之间的云服务器 ECS 不能跨地域部署负载均衡,即在不同的地域购买的 ECS 实例不支持跨地域部署在同一负载均衡实例下。
可用区(Zone):
可用区是指在同一地域内,电力和网络互相独立的物理区域。同一可用区内实例之间的网络延时更小。

理解region和az的概念后,我们需要做什么是不是就简单多了?

1.服务发现客户端,优先与相同的AZ进行通讯
2.服务发现客户端,查询注册中心地址列表时,只取相同region下所有AZ的注册中心地址
2.注册中心,也只需要将数据同步给相同region的所有AZ即可

不过属于哪个区,好像没有特殊的配置吧?
eureka.client.availability-zones.us-east-1=zone2,zone1
eureka中取上面配置的第一个可用区为优先使用的可用区

注:虽然region之间是数据隔离的,但是eureka也支持从其他region同步信息(通过http请求)

常见问题探讨

连连看,将如下类图与我们架构图里对象进行对应

eureka server 是ap还是cp?

服务启动后会不会马上注册到注册中心?

服务提供者注册到注册中心后,服务消费者最快多久能够查询到该提供者?

为什么接收心跳后不入队,那么更新心跳后启不是增量查询查不到了?

集群同步的队列,为什么要经过一道中转才进行消费?

部分图片摘自如下文章:

《聊一聊微服务架构下的服务发现模式》

服务发现之eureka的更多相关文章

  1. Spring Cloud官方文档中文版-服务发现:Eureka服务端

    官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR3/#spring-cloud-eureka-server 文中例子我做了一些 ...

  2. SpringCloud服务发现(Eureka)简介

    Eureka是Netflix开发的服务发现框架,SpringCloud将它集成在自己的子项目spring-cloud-netflix中,实现SpringCloud的服务发现功能. 为什么要使用Eure ...

  3. Spring Cloud官方文档中文版-服务发现:Eureka客户端

    官方文档地址为:http://cloud.spring.io/spring-cloud-static/Dalston.SR2/#_spring_cloud_netflix 文中例子我做了一些测试在:h ...

  4. springcloud实践(一)服务发现:Eureka

    Eureka 入门 是什么? Eureka 是 Netflix 开源的一个 RESTful服务,主要用于服务注册与发现. 它由Eureka server 和Eureka client组成. Eurek ...

  5. SpringCloud服务注册与服务发现之Eureka

    Eureka是SpringCloud Netflix的子模块之一,用于云端的服务发现,服务定位,实现云端中间层服务发现和故障转移.服务注册与发现对于微服务系统来说十分的重要,有了服务注册与发现,就省去 ...

  6. Spring Cloud(2):服务发现(Eureka)

    Spring Cloud Eureka是Spring Cloud Netflix项目下的一个模块,作用是服务的注册和发现,并实现服务治理.它有一个(或一组,以实现高可用)服务注册中心(eureka s ...

  7. springcloud之服务注册与发现(Eureka)

    springcloud服务注册与发现 使用Eureka实现服务治理 作用:实现服务治理(服务注册与发现) 简介: Spring Cloud Eureka是Spring Cloud Netflix项目下 ...

  8. springcloud干货之服务注册与发现(Eureka)

    springcloud系列文章的第一篇 springcloud服务注册与发现 使用Eureka实现服务治理 作用:实现服务治理(服务注册与发现) 简介: Spring Cloud Eureka是Spr ...

  9. SpringCloud之Eureka 服务注册和服务发现基础篇2

    上篇文章讲解了SpringCloud组件和概念介绍,接下来讲解一下SpringCloud组件相关组件使用.原理和每个组件的作用的,它主要提供的模块包括:服务发现(Eureka),断路器(Hystrix ...

随机推荐

  1. 利用IDEA构建springboot应用-配置文件

    application.properties配置文件(不建议采用这种配置) 配置文件采用:application.yml文件会更简便,要带空格 属性配置与类中取值 添加bean属性配置到一个类里面,采 ...

  2. 06多次查询某区间内topk问题

            题目描述:给定一个数组,需要多次查找不同区间内的,第k大或者第k小的元素.         考虑题目是多次查找,如果采用只对查询区间内的元素进行排序的思路,然后输出第k大的数的策略,那 ...

  3. 在SpringBoot中使用JWT

    JWT简介 简介 JSON Web token简称JWT, 是用于对应用程序上的用户进行身份验证的标记.也就是说, 使用 JWTS 的应用程序不再需要保存有关其用户的 cookie 或其他sessio ...

  4. data-属性的作用

    data-用于存储页面或应用程序的私有自定义数据,赋予我们在所有HTML元素上嵌入自定义data属性的能力,存储的数据能被页面的JS利用,以创建更好的用户体验. <div id="bo ...

  5. python单例模式的实现与优化

    python单例模式的实现与优化 阅读目录(Content) 单例模式 实现单例模式的几种方式 1.使用模块 2.使用装饰器 3.使用类 4.基于__new__方法实现(推荐使用,方便) 5.基于me ...

  6. [转]什么是CNN、RNN、LSTM

    . 全连层 每个神经元输入: 每个神经元输出: (通过一个激活函数) 2. RNN(Recurrent Neural Network) 与传统的神经网络不通,RNN与时间有关. 3. LSTM(Lon ...

  7. Python--day43--mysql唯一索引和外键变种之多对多

    唯一索引:(unique关键字)unique 名字 (num) 外键的变种:

  8. 2019-10-24-dotnet-列表-Linq-的-Take-用法

    title author date CreateTime categories dotnet 列表 Linq 的 Take 用法 lindexi 2019-10-24 9:4:23 +0800 201 ...

  9. H3C 通配符掩码的应用示例

  10. Js 时间戳显示和计算时间间隔

    显示时间戳 很多地方会让页面显示当前时间并实时计时功能,例:2019年5月23号 10:28::34 代码实现如下: getTime(){ var mydate = new Date(); var y ...