什么是服务发现?
服务 → ip:port list的查找表
为什么需要服务发现?
虚拟化,容器技术,云平台 --> ip 动态分配
微服务化 --> 应用拆分,相互调用增加
方案演进
硬编码:只适用稳定的服务方
dns: 缓存导致更新扩散有延迟,故障转移问题
dns + loadbalancer/VIP: 基础设置配置方案(mysql,redis)
服务发现做什么?
服务注册/注销
失败节点检测
服务列表查询
实现分类
发现
client-side discovery: client请求前从registry查询ip:port列表,选择一个发请求 (eureka)
server-side discovery: 加一个lb/router,做代理转发,从registry获取服务ip的逻辑放到代理层 (nginx,k8s)
注册
self-registration:服务方在启动跟停止时主动上报注册中心 (eureka, nacos)
third-party registration:第三方模块代替服务方向注册中心上报 (consul, nacos)
实现细节 - 关注点
client端查询:缓存及更新
server端查找表维护:注册信息同步及失败节点检测
服务发现实现案例
eureka
client端:
所有查询走本地缓存
两个定时任务
- 心跳:默认30s一次,服务续期
- 缓存刷新:第一次全量,后面拉delta,即全部app的hash,发生变化触发全量刷新
server端:
客户端查询&注册表维护:多级缓存,读写分离,内层实时写,外层只读存储,30s更新一次
集群成员信息同步:定时任务,从已知节点同步
集群间数据同步:所有注册,下线,心跳,淘汰请求走异步队列同步peer node
失败检测:默认超3个周期无心跳,进入淘汰队列
- 自我保护机制:如果一次清理超过15%,停止,保留当前全部数据直到恢复或人为干预,避免网络抖动触发大量服务下线
保证可用性,不保证一致性,server间数据同步可能延迟
consul
两种agent模式:
server → 负责维护注册表 & rpc响应
client → 转发请求 & 心跳检查
client端缓存:
agent支持参数指定最大过期时间
agent block query数据变更,client查询永远走缓存,超过3天不请求,不再监听
状态同步:
一个dc内client与server是一个集群,可以相互发现与广播信息,client不一定要配置server信息
server端,dc间wan gossip,dc内server之间raft保证一致性
client端参与lan gossip,广播成员以及服务状态,优先udp,重试几次降级到tcp
所有rpc请求均转发到对应dc内的leader处理
跨dc请求,由请求发起方的dc leader转发到目标dc的leader (dc间不同步数据)
server数据默认不做持久化
保证一致性,牺牲写性能
读一致性级别
- default: leader leasing期限内提供读
- consistent:leader每次rpc都跟folowler确认,有延迟
- stale:任意时刻,任何节点都能提供读
失败检测:
agent主动进行心跳检测,失败检测通过集群内所有节点监控传播
agent下线,注册到该agent下的服务信息都会丢失
lifeguard,增强swim协议,动态调整超时时间,降低误判率
几类服务发现产品对比
eureka | consul | nacos | etcd | zk | |
api | 服务发现rest api | rest api & dns | rest api & dns | rest api & grpc | zkClient |
watcher | long polling (eureka2) | long polling | udp | key watcherclient long polling,server端定时任务遍历日志找某个版本之后的变更通知 | key watcherclient 注册handler到本地,server保存回掉信息,触发时调用 |
心跳检查 | client heartbeat | server探活(支持mysql,redis之类无法嵌入client的基础服务) | 注册时配了healthcheck的server端检查,client端默认注册就会启动beat定时任务 | put key & ttl 并定时续期 | 依赖临时节点,跟server心跳保持 |
客户端缓存策略&更新策略 | 定时刷新,最多60s延迟 | 可手动指定缓存期限 | 一个service一个schedule任务定时更新 | ||
持久化 | 无 | 可手动持久化,用于还原备份 | 支持 | v3支持,写wal | 支持,快照 + 事务日志 |
cap | ap | cp(raft) | ap(distrio) & cp (raft) | cp(raft) | cp(zab) |