discovery服务发现

背景/Background

比较老的注册中心大部分使用ZooKeeper来实现, 但是由于ZooKeeper为CP系统,无法保证分布式下的可用性,需要使用AP系统

根据 Netflix Eureka 开发并优化出go版本服务注册发现系统Discovery,与caster深度结合 ,客户端使用HTTP协议与注册中心交互。

相关文档/Reference

Eureka文档:https://github.com/Netflix/eureka/wiki

设计目标/Design Goals

业务目标:

1,实现AP系统服务注册发现,保证数据最终一致性(非强一致性,勿要将 discovery 用作协调器)。

2,与平台深度结合,基于k8s pod实现滚动发布,蓝绿发布。

3,网络闪断时服务可开启自我保护,保证健康的服务可用

4,实现各个语言sdk,基于HTTP协议保证交互简易。

性能指标:

1,注册数据的分布式最终一致性

2,renew接口 QPS 20k ,其他接口QPS 10k下可用

概览/Overview

基本流程

  1. 通过appid(服务名)和Addr(IP:Port)定位实例

  2. Provider 注册后定期(30s)心跳一次,注册, 心跳,下线都需要进行同步,注册和下线需要进行长轮询推送

  3. Consumer 启动时拉取实例,发起30s长轮询

  4. Server 定期(60s) 检测失效(90s)的实例,失效则剔除。短时间里丢失了大量的心跳连接(15分钟内心跳低于期望值*85%),开启自我保护,保留服务不过期。

重要步骤

1.心跳的复制(Peer to Peer)检查数据一致性(网络抖动或分区导致数据不一致):

注册时根据当前时间生成dirtyTime, A向B同步实例心跳时:

返回-404 表示 (1)B中不存在实例 (2)B中dirtyTime较小 A携带自身dirtyTime向B发起注册请求,把最新信息同步过去。

返回-409 表示 (1)B中dirtyTime较大 不同意采纳A的信息而是将自身实例的信息放在消息体里返回B更新本地

2.网络分区时的自我保护

当网络分区发生时,每个Discovery节点,会持续的对外提供服务,接收该分区下新实例的服务注册和发现。

短时间丢失大量心跳,进入自我保护,保证健康的实例不被剔除,同时保留”好数据“与”坏数据“

自我保护:每分钟的心跳数小于阈值(实例数量285%),每15分钟重置心跳阈值

非自我保护下,随机分批逐次剔除,尽量避免单个应用被全部过期。

3.客户端

长轮询+服务端推送变化,让服务发现的实时性更高

订阅式客户端,推送客户端关注的实例变化

Eureka客户端缓存,即便所有的都失效,依旧可以调用服务

多注册中心

1.同一个机房内部,discovery节点通过广播进行注册信息同步。

2.跨机房注册信息同步时,discovery节点会将信息推送到其他的机房slb,再由slb通过负载均衡把信息推送到机房内部节点。机房内部在进行广播同步。

  • 注意: 跨机房同步时,注册信息为单向同步,slb收到信息后LB到机房内部节点,内部节点只在内部广播,不会推送到其他slb。

系统架构

架构图

image-20220917165555068

多注册中心架构图

image-20220917165617494
刘小恺(Kyle) wechat
如有疑问可联系博主