背景
微服务是目前java主流架构,微服务架构技术栈有,服务注册中心,网关,熔断限流,服务同学,配置中心等组件,其中,熔断限流主要3个功能特性,限流,熔断,快速失败。Sentinel是阿里开源的熔断限流组件,sentinel dashboard是演示级别,表现在metrics采集是单机版,metrics存储存在内存,不支持分布式,高可用,因此需要改造。
此前博文(sentinel dashboard分布式改造设计解释_sentinel-dashboard-CSDN博客),介绍分布式改造设计,本系列介绍落地的设计和实现解释
本文介绍改造第一部分,metrics拉取器的分布式改造,metrics存储和搜索elasticsearch实现,第二部分介绍discovery组件分布式改造, transport上下线监控和相关处理。
参考和术语
限流 控制调入流量,防止流量过大造成系统崩溃
熔断/快速失败 断路有延迟的服务,防止雪崩效应;断路探测,恢复服务路由
技术架构
改造后的技术架构
公用组件
AppManagement 收集机器与app资料,增加discovery zookeeper实现
metrics fetcher
- transport登记为分片,znode内容是app,ip,port
- transport心跳改为基于zk实现
- 采集使用定时调度,包括分片,容错,实例服务,实例监听服务,分布式组件选举,主节点负责分配服务实例,监听fectcher实例变更
- metrics存储,onesearch
dashboard
查询metric,rule更新和发布,依赖discovery组件
分布式组件
改造使用分布式服务组件,本节介绍一下
上图分布式组件组件,这里只介绍改造用到的服务,其他详细可参看参考
- znode服务 znode读写,znode监听器设置
- 选主服务 metrics fetcher主节点选举
- 运行实例服务 metrics fetcher worker注册为实例,执行分片
- 监听服务 zookeeper的worker机制
- 分片服务 分布式调度间接提供,fetcher以分布式调度作业运行
- 失效转移服务 分布式调度间接提供,fetcher下线,失效服务重置下线fetcher的分片,主节点重新分配
分布式调度引擎
metrics fetcher使用分布式调度elastic-jobx的作业执行,elastic-jobx重构自elastic-job,提供分片,容错,任务执行等能力。5. 分布式组件也是elastic-job core包分离出来,独立成为分布式组件,elastic-jobx依赖分布式组件,对原elastic-job分片,容错等重构,解决elastic-job分片的问题。
elastic-jobx本文不详细介绍,详细可以参看参考本人其他博客
工程结构
原有dashboard拆分为3个工程
core vo类,实体类,Repository接口,discovery组件,console和fetcher依赖core
console web工程,查询,规则更新/发布,app/机器资料库
metrics fetcher metrics拉取器,拉取作业
实现解释
本章开始解释代码实现
znode
基于zookeeper的分布式绕不开znode的设计,上图是分布式改造的znode设计图,其中transport是改造增加,其他是分布式支撑服务和调度引擎,分布式支撑服务介绍过,有兴趣可参看资料,这里只介绍transport相关
/appname/transport sentinel transport域,
/instances transport实例域,
Item transport实例,临时节点,代表sentinel保护资源,如,服务,transport下线对应的分片需要移除
/election transport选主节点
/latch 选举节点,注意区分,调度引擎也有选举节点/latch
/instance 选出主节点实例,ip:port
spring/springboot
spring boot升级到3.0.1,spring 升级到6
分布式服务组件
分布式服务组件使用sentinel的初始化机制,实现InitFun,构建分布式服务组件3件套
上图sentinel-elastic-platform类图,分布式支撑类
ElasticPlatformInit 实现InitFun,接入sentinel的初始化机制,构建zk客户端和TransportService
TransportService/TransportZNode 前者负责实际读写znode,后者封装transport节点路径,TransportService引用leader服务
BaseTransportListenerManager znode监听器的管理器,监听器通常在业务层实现,后续章节解释监听器
transport
transport的改造主要在心跳发送器,实现被动式(passive)心跳实现,写入app/ip/port等Machine信息,基于zookeeper的watcher机制实现健康检测。监听与zookeeper连接状态,即上节的ConnectionStateListener实现,下线重连重写Machine信息。另外一部分,transport原有command中心模块没有改变
上图是心跳发送器涉及的znode,红框标出,/transport/item写入transport的ip:port,
上图写入transport信息的方法,TransportNode获取transport item的znode路径,
上图写入分片和分片的config节点,使用curator事务,config节点内容matchine对象
最后,zookeeper连接状态监听
zookeeper连接,重写transport实例,分片
拉取作业
拉取作业实现为分布式调度引擎elastic-jobx的作业,elastic-jobx提供分片,容错和定时功能,关于elastic-jobx本章不详细介绍,可参看参考资料
作业的实现比较简单,实现SimpleJob接口,唯一的参数ShardingItemContext,其属性configStr写入分片的config节点,携带执行配置,这里是MachineInfo对象,作业从该对象获取ip,port,构建metrics拉取url,从而获取metrics
作业一次只执行一个分片,elastic-jobx有两个分片策略,eager和on_demand,其中eager一次分完所有分片,但执行是多线程,每个线程一个分片执行,因此无论作业实现,metrics fetcher都要考虑线程安全
metrics拉取
了解过坊间metrics采集改造大多采用推方式,即transport往设定的dashboard(集群)推送,个人觉得这种方式侵入性比较大,服务不断往外推送,当接收的dashboard不在线或者网络不好对原有服务影响较大,另外,服务众多,同时向dashboard推送,dashboard需要较多的资源,因此,拉的方式比较合适,本改造保留拉取方式
metrics拉取器逻辑与原来基本一致,elastic-jobx多个分片单作业例多线程执行,作业实现和fetcher修改为可多线程进入,获取app/机器资料,使用机器资料的ip,port构建拉取url,去掉了app/机器的健康检查,app/机器的有效性通过zookeeper的watcher机制保证
metrics存储/搜索
metrics存储库(Repository)和搜索,使用onesearch实现,有onesearch加持事情变得非常简单
注意:这里说的是dashboard的metrics存储,transport也有metrics存储,使用文件
metrics schema
schema对于elasticsearch不是必要,但通常定义schema产生一个mapping, 严格定义字段的类型,对业务来说是非常关键,保证类型的正确,同时,schema还可以定义字段值的getter,boost,Text类型的搜索方式等
上图是MetricEntity的索引定义,需要注意的是,timestamp是保留字,需要加``引用
metrics存储
metrics存储是onesearch下实现非常简单,下图是save方法,索引单个实体,构建索引资源IndexResource,调用文档服务写入文档
还有saveAll方法,批量写入
metrics搜索
原有搜索基本没有可用性,使用onesearch的表达式搜索方便实现强大搜索功能
下图是搜索
分页,排序,构建搜索请求,返回类型MetricVo
值得注意是搜索词,如果resource字段设置为Text类型,使用搜索词,Query搜索算分的拟合度,得到结果更丰富;如果resource字段设置为Keyword类型,使用filter,wildcard匹配,得到的是否的结果,对于resource,后者可以满足要求
示例
首先介绍一下示例场景
左图是模拟sentinel保护资源, 3个资源,也就是3个分片, 运行FlowQpsDemo;右图是fetcher,2个fetcher,
*注意: transport的metrics存储在本地文件,而且目录系统变量user.home,同一台机器打开多个服务(受保护资源),需设置属性csp.sentinel.log.use.pid=true,否则多个transport存储metrics的文件冲突,该属性默认为false,当然也可以不同服务不同的系统变量user.home;同时,设置csp.sentinel.api.port不同的端口
下图是运行中zookeeper快照
Instances fetcher实例,即worker,名称格式IP@-@jvmId
sharding 分片znode,其instance 分配给哪个worker
transport/instances transport的实例,代表着受保护服务,discovery组件将会监控该节点维护app/机器资料
上图采集的指标
NEXT
下一篇介绍discover和transport上下线处理