其它中间件

前言

汇总之前工作中的其它边角中间件的相关工作原理及最佳实践经验

ShardingSphere

1. 核心原理

ShardingSphere 是一款分布式数据库中间件,核心功能包括数据分片、读写分离、数据加密、分布式事务等。

  • 数据分片

    • 逻辑表与物理表映射:将逻辑表(如 user)按分片规则拆分为多个物理表(如 user_0, user_1)。
    • 分片算法
      • 精确分片算法:基于分片键(如 user_id)的哈希或取模计算分片。
      • 范围分片算法:按时间范围(如订单表按月份分片)。
    • 绑定表:关联表(如 orderorder_item)共享分片键,避免跨分片 JOIN。
  • 读写分离

    • 基于主从架构,写操作路由到主库,读操作路由到从库(支持权重负载均衡)。
  • 分布式事务

    • 支持 XA、Seata 等事务模型,保障跨库操作的原子性。
  • SQL 重写与执行引擎

    • SQL 解析:解析 SQL,提取分片键并计算路由。
    • 结果归并:合并多个分片的查询结果(如 LIMIT 10 需各分片先排序再合并)。

2. 最佳实践

1. 分片键设计

  • 选择高频查询字段:如订单表的 user_id,避免全表扫描。
  • 避免数据倾斜
    • 哈希分片时建议分片数为 2 的幂(如 8、16),便于扩容。
    • 时间分片时预留未来分片(如按月分片时提前创建下月表)。

2. SQL 兼容性

  • 限制复杂 SQL
    • 避免跨分片 JOIN,可通过冗余字段或绑定表优化。
    • 分页查询需谨慎:LIMIT 100000, 10 会导致全分片扫描。
  • 禁止未带分片键的更新/删除:可能触发全分片广播,引发性能问题。

3. 事务与一致性

  • 本地事务优先:单分片操作尽量使用本地事务。
  • 分布式事务场景
    • 强一致性需求:使用 XA 事务(性能较低)。
    • 最终一致性:结合消息队列补偿(如订单创建后发 MQ 通知其他服务)。

4. 性能优化

  • 分片数规划
    • 单表数据量建议不超过 500 万行,分片数不超过物理节点数的 3 倍。
  • 连接池配置
    • 使用 HikariCP 替代默认连接池,设置合理的 maximumPoolSize
  • 避免全分片广播:如 UPDATE user SET status=1 会触发所有分片执行,改用分片键条件。

5. 数据迁移与扩容

  • 在线扩容
    • 一致性哈希分片算法可减少数据迁移量。
    • 使用 ShardingSphere-Scaling 工具实现不停机迁移。
  • 历史数据归档:将冷数据迁移到独立库表(如 user_archive)。

6. 监控与日志

  • 启用 Metrics:对接 Prometheus 监控慢 SQL、连接池状态。
  • 日志排查
    • 开启 sql.show 配置,打印实际执行的 SQL。
    • 使用 Tracing 功能跟踪分片路由路径。

3. 典型问题与解决方案

  • 问题1:分页查询性能差
    方案:改用 ES 维护全局索引,或通过业务设计规避深分页(如滚动查询)。

  • 问题2:分片键变更导致路由失效
    方案:禁止修改分片键字段,或设计冗余分片键(如 user_iduser_id_hash)。

  • 问题3:跨分片统计 SUM/COUNT 慢
    方案:预聚合统计结果,定期写入统计表。

4. 生态工具整合

  • ShardingSphere-Proxy:无侵入式分片(适合老旧系统改造)。
  • ShardingSphere-JDBC:轻量级 Java 驱动,适合微服务架构。
  • ShardingSphere-UI:可视化配置管理分片规则。

ElasticJob

ElasticJob 工作原理总结

ElasticJob 是 Apache ShardingSphere 下的分布式任务调度框架,核心解决分布式场景下的任务分片、高可用、弹性调度等问题。以下是其核心原理及使用注意事项:

一、核心工作原理

  1. 任务分片机制
    • 将任务拆分为多个分片(Sharding),每个分片由不同节点执行。
    • 分片策略支持:平均分配、自定义表达式(如按地域、业务ID哈希等)。
    • 分片上下文:任务执行时获取当前分片参数(如分片总数、当前分片索引)。
  2. 分布式协调与注册中心
    • 依赖 ZooKeeper/Etcd 作为注册中心,管理节点状态、分片信息、故障转移。
    • 节点启动时向注册中心注册,主节点负责分片计算与任务触发。
  3. 弹性扩缩容
    • 动态扩容:新增节点时,自动触发分片重新分配(ReSharding),负载均衡。
    • 节点宕机:故障节点分片由存活节点接管,通过注册中心监听机制实现秒级故障转移。
  4. 任务调度流程
    1. 主节点选举:通过注册中心选举主节点,负责分片计算。
    2. 分片分配:主节点计算分片与节点的映射关系,写入注册中心。
    3. 任务触发:节点根据分片参数拉取任务数据,执行各自分片。
    4. 故障恢复:节点失效后,剩余节点重新分片并接管任务。
  5. 任务类型
    • Simple Job:单机定时任务。
    • Dataflow Job:处理数据流,支持 Fetch/Process 分离。
    • Script Job:直接执行脚本(如 Shell、Python)。

二、使用注意事项

  1. 分片策略选择
    • 根据数据量和业务特性选择分片策略,避免数据倾斜。
    • 分片数建议为节点数的整数倍(如 2 倍),确保扩容后负载均衡。
  2. 注册中心高可用
    • ZooKeeper/Etcd 需集群部署,避免单点故障。
    • 监控注册中心连接状态,网络波动可能导致任务中断。
  3. 任务幂等性
    • 分片重分配可能导致任务重复执行,业务逻辑需保证幂等(如通过唯一键去重)。
  4. 资源竞争与锁机制
    • 跨分片操作共享资源时,需引入分布式锁(如 Redis 锁、数据库乐观锁)。
  5. 动态分片限制
    • 修改分片数或节点数会触发 ReSharding,期间任务可能短暂暂停。
    • 避免频繁扩容/缩容,防止分片抖动。
  6. 监控与日志
    • 启用 ElasticJob 的运维界面(如 ElasticJob-Lite-UI)监控任务状态、分片分布。
    • 记录任务执行日志,尤其是分片参数和执行结果,便于排查问题。
  7. 版本兼容性
    • ElasticJob 与注册中心(ZooKeeper/Etcd)、Spring 等依赖版本需严格匹配。
  8. 资源隔离
    • 为 ElasticJob 分配独立线程池,避免任务阻塞影响其他业务。
  9. 任务超时与重试
    • 配置合理的超时时间,避免僵尸任务。
    • 结合 JobErrorHandler 自定义错误处理(如重试、告警)。

三、典型问题与解决

  • 分片不均:调整分片策略,或手动指定分片参数。
  • 任务堆积:增加节点数或优化任务逻辑(如批量处理)。
  • 注册中心断连:配置合理的会话超时时间(如 ZooKeeper 的 sessionTimeoutMs)。
  • 主节点瓶颈:主节点压力大时,可分离调度器与应用节点。

四、最佳实践

  1. 分片数初始设置为节点数的 2~3 倍,预留扩容空间。
  2. 对数据库操作的任务,按表 ID 哈希分片,避免跨节点事务。
  3. 生产环境禁用 monitorExecution=false(关闭分片状态监控),防止状态不一致。
  4. 使用 Dataflow Job 时,采用 streaming-process 模式逐条处理,降低内存压力。

其它分布式调度方案

以下是目前主流的分布式调度方案及其核心特性的总结,结合了技术架构、功能特点及适用场景的分析:

1. Elastic-Job

  • 核心特性
    • 无中心化设计:基于 ZooKeeper 实现分布式协调,无单点故障风险,节点自治触发调度。
    • 弹性扩缩容:动态调整分片,节点增减时自动重新分配任务,支持秒级故障转移。
    • 任务分片:支持将任务拆分为多分片并行执行,开发者需自行处理分片与数据的映射关系。
    • 作业类型:支持 Simple(简单任务)、Dataflow(数据流处理)、Script(脚本执行)三种类型。
    • 运维支持:提供独立运维界面(如 ElasticJob-Lite-UI),监控任务状态与分片分布。
  • 适用场景:高并发、需水平扩展的分布式任务,如电商库存同步、大数据批处理等。

2. XXL-JOB

  • 核心特性
    • 中心化调度:通过调度中心统一管理任务,支持动态修改任务参数及状态。
    • 轻量级:部署简单,开箱即用,支持通过 Web 界面操作任务(如启动、暂停、终止)。
    • 失败重试与告警:任务失败后自动重试,支持邮件告警。
    • 跨语言支持:通过 HTTP 调用实现多语言任务集成。
  • 适用场景:中小型项目,需快速搭建且对中心化设计无排斥的场景,如订单状态更新、日志清洗等。

3. Saturn(唯品会开源)

  • 核心特性
    • 多语言支持:支持 Java、Python、Go 等多种语言开发任务。
    • 分片调度优化:基于 Elastic-Job 1.x 改进,提供更灵活的分片策略和负载均衡。
    • 高可用与监控:通过 ZooKeeper 实现节点状态监控,任务失败自动转移。
    • 统一控制台:提供 Web 界面(Saturn Console)管理任务与执行器。
  • 适用场景:多语言混合开发环境,如跨团队协作的分布式数据处理任务。

4. LTS(Light Task Scheduler)

  • 核心特性
    • 多样化任务类型:支持实时任务、定时任务及 Cron 任务。
    • 动态任务管理:允许运行时提交、修改或停止任务,支持 Spring 集成。
    • 监控与日志:内置 JVM 监控、任务执行日志记录,便于问题排查。
    • 高扩展性:通过注册中心(如 ZooKeeper)实现节点动态扩展。
  • 适用场景:需实时任务处理的场景,如金融交易对账、实时风控计算等。

5. Antares

  • 核心特性
    • 基于 Quartz 优化:重写任务执行逻辑,确保任务在集群中仅由一个节点执行。
    • 预分片机制:通过预先分片提升任务执行效率,支持通过控制台(Antares-Tower)管理任务。
    • IP 黑名单:可过滤不执行任务的节点,增强安全性。
  • 适用场景:对任务执行唯一性要求高的场景,如定时生成唯一报表、数据去重处理等。

6. TBSchedule(淘宝开源)

  • 核心特性
    • 高性能:采用无锁化设计,支持每秒数万次任务调度。
    • 动态分片:任务分片可动态调整,适应负载变化。
    • 容错机制:节点故障时自动迁移任务,保障高可用。
  • 适用场景:高吞吐量场景,如电商秒杀、支付对账等。

选型建议

  1. 任务类型与复杂度
    • 简单任务优先选择 XXL-JOB;需分片处理选 Elastic-Job 或 Saturn。
  2. 架构偏好
    • 去中心化选 Elastic-Job;中心化选 XXL-JOB 或 LTS。
  3. 扩展性需求
    • 高弹性扩缩容场景适用 Elastic-Job;多语言支持选 Saturn。
  4. 监控与运维
    • 需完善监控时选择 LTS 或 Antares。

趋势与挑战

  • 智能化调度:部分框架(如 Elastic-Job)开始结合机器学习优化分片策略。
  • 云原生适配:Elastic-Job-Cloud 等方案支持 Mesos/Kubernetes,适应云环境资源调度。
  • 安全性增强:通过 IP 黑名单(Antares)、用户权限控制(cronsun)提升安全性。

Dianpin CAT

一、CAT 核心工作原理

CAT(Central Application Tracking) 是大众点评开源的分布式实时监控系统,专注于应用性能管理(APM)和错误追踪。其核心流程如下:

1. 数据采集与传输

  • 埋点机制
    • 通过代码埋点(注解、AOP)或中间件代理(如 Dubbo/MySQL 拦截器)采集数据。
    • 记录 Transaction(事务,如方法调用)、Event(事件,如异常)、Metric(指标,如 QPS)三类数据。
  • 消息树(Message Tree)
    • 以树形结构记录调用链路(如 ServiceA → ServiceB → SQL),支持跨服务追踪。
  • 数据传输
    • 客户端通过 TCP 或 HTTP 将数据实时发送至 CAT 服务端,支持高并发(默认使用 Netty 异步传输)。

2. 数据处理与存储

  • 实时聚合
    • 服务端按分钟级窗口聚合数据(如统计接口耗时、错误率)。
    • 使用内存队列缓冲数据,通过多线程异步写入存储。
  • 存储设计
    • 原始日志:按小时分片存储到本地文件(如 /data/applogs/cat/2023020112)。
    • 聚合报表:HBase 或 MySQL 存储统计结果(如每小时 QPS、平均耗时)。

3. 可视化与告警

  • Dashboard
    • 实时展示 TransactionEventMetric 报表,支持按应用、接口、IP 等维度过滤。
    • 调用链路追踪(Trace)可视化,快速定位性能瓶颈。
  • 告警规则
    • 配置阈值告警(如错误率 > 1%、耗时 > 1s),支持邮件、企业微信通知。

二、最佳实践

1. 埋点设计规范

  • 关键路径埋点
    • 核心业务逻辑(如订单创建、支付回调)、外部依赖(如 RPC、DB、缓存)。
    • 避免过度埋点导致性能损耗和数据冗余。
  • 事务命名规范
    • 使用层级命名(如 Service.order.create),便于聚合分析。
  • 异常处理
    • 捕获异常后通过 logEvent("Error", e.getMessage()) 上报,附加参数(如订单号)。

2. 性能优化

  • 采样率控制
    • 高 QPS 接口启用采样(如 10%),通过 CAT.setSamplingRate(0.1) 降低数据量。
  • 异步上报
    • 使用 Cat.logMetricForDuration 异步记录耗时,避免阻塞业务线程。
  • 客户端调优
    • 调整 Netty 客户端线程池大小(如 cat.threads.pool.size=50)。

3. 存储与查询优化

  • 日志分片
    • 按小时分目录存储,避免单文件过大(可配置 cat.server.localReportBaseDir)。
  • 索引优化
    • 对常用查询字段(如 serviceNamestatus)建立索引,加速 Trace 查询。

4. 告警与监控

  • 分层告警
    • P0 级:核心接口错误率 > 5%(立即通知)。
    • P1 级:耗时 > 2s(每小时汇总通知)。
  • 自定义报表
    • 通过 CAT API 生成业务定制报表(如每日支付成功率趋势)。

5. 高可用部署

  • 集群部署
    • 至少部署 3 个 CAT Server 节点,通过 Nginx 负载均衡。
    • 存储层使用 HBase 集群或 MySQL 主从。
  • 容灾策略
    • 客户端本地缓存未发送数据(cat.queue.blocking.size=1000),网络恢复后重试。

三、典型问题与解决方案

  • 问题1:CAT 客户端导致应用 CPU 飙升
    原因:高频埋点或同步阻塞上报。
    方案:启用采样率、异步上报,优化埋点粒度。

  • 问题2:Trace 链路不完整
    原因:跨线程或异步调用未传递上下文(如线程池未继承 Trace ID)。
    方案:使用 Cat.Context 传递上下文,或集成 TransmittableThreadLocal

  • 问题3:存储空间不足
    原因:原始日志未定期清理或分片过大。
    方案:配置日志保留策略(如保留 7 天),启用压缩存储。

四、与其他系统集成

  • 与日志系统联动
    • 将 CAT 的 Error 事件同步到 ELK,实现日志关联分析。
  • 与 Prometheus 整合
    • 通过 cat-client-prometheus 插件暴露 Metric 数据,接入 Grafana 监控大盘。

其它分布式监控解决方案

1. Prometheus + Grafana

核心功能:指标采集、存储、告警、可视化。
工作原理

  • Pull 模型:主动从目标节点拉取指标(HTTP端点)。
  • 时间序列数据库:本地存储 + 远程存储(如 Thanos/Cortex)。
  • PromQL:灵活查询语言,支持多维聚合。

优点

  • 云原生首选,与 Kubernetes 深度集成。
  • 社区生态丰富(Exporter 齐全,如 Node Exporter、JMX Exporter)。
  • 动态服务发现(支持 Consul、DNS、K8s 等)。

缺点

  • 单机存储受限,集群方案(Thanos)增加复杂度。
  • 无原生链路追踪(需结合 Jaeger/SkyWalking)。

适用场景:容器化环境、微服务指标监控。

2. ELK Stack (Elasticsearch + Logstash + Kibana)

核心功能:日志采集、存储、分析、可视化。
工作原理

  • Logstash/Filebeat:采集并处理日志,发送到 Elasticsearch。
  • Elasticsearch:分布式搜索与分析引擎。
  • Kibana:可视化仪表盘。

优点

  • 日志处理能力强,支持全文检索。
  • 扩展性好,可处理 PB 级数据。

缺点

  • 实时性较弱(默认近实时,延迟约 1 秒)。
  • 资源消耗高(尤其 Elasticsearch 内存占用大)。

适用场景:日志集中管理、故障排查。

3. Jaeger + OpenTelemetry

核心功能:分布式链路追踪、性能分析。
工作原理

  • OpenTelemetry:统一埋点 SDK,采集 Trace/Metric/Log。
  • Jaeger:存储和展示调用链路,支持 DAG 可视化。

优点

  • 标准化协议(OpenTelemetry),多语言支持完善。
  • 细粒度跟踪(支持每个 Span 的自定义 Tag)。

缺点

  • 数据存储成本高(高频调用产生海量 Span)。
  • 无原生指标告警(需集成 Prometheus)。

适用场景:微服务调用链分析、性能瓶颈定位。

4. Zabbix

核心功能:基础设施监控、告警、自动化。
工作原理

  • Agent/SNMP:被动采集主机、网络设备指标。
  • 集中式架构:Server 负责数据处理和告警。

优点

  • 传统监控王者,支持设备类型广泛(服务器、交换机等)。
  • 告警策略灵活(支持依赖关系、维护窗口)。

缺点

  • 扩展性差(大规模集群性能下降明显)。
  • 配置复杂,学习曲线陡峭。

适用场景:物理机/虚拟机监控、中小企业运维。

5. SkyWalking

核心功能:APM(应用性能监控)、链路追踪、拓扑分析。
工作原理

  • 探针自动注入:Java Agent 无代码侵入采集数据。
  • 服务拓扑:动态生成服务依赖关系图。

优点

  • 开箱即用,集成指标、日志、Trace 三支柱。
  • 对 Java 生态支持最佳(支持 Spring Cloud、Dubbo)。

缺点

  • 非 Java 语言支持较弱(如 Go/Python 需手动埋点)。
  • 社区生态不如 Prometheus 活跃。

适用场景:Java 微服务全栈监控。

6. Datadog

核心功能:全栈监控(Infra、APM、日志、Synthetics)。
工作原理

  • SaaS 服务:Agent 上报数据到云端。
  • AI 驱动分析:自动检测异常模式。

优点

  • 一体化方案,降低工具链维护成本。
  • 强大的 Dashboard 和协作功能(支持团队注释)。

缺点

  • 成本高昂(按 Host/Metric 数量计费)。
  • 数据隐私风险(数据存储在第三方)。

适用场景:多云环境、企业级付费用户。

横向对比表

方案 核心能力 数据实时性 扩展性 学习成本 部署复杂度 成本
Prometheus + Grafana 指标监控、告警 高(需扩展) 低(开源)
ELK Stack 日志分析
Jaeger 链路追踪 低(开源)
Zabbix 基础设施监控 低(开源)
SkyWalking APM、链路追踪 低(开源)
Datadog 全栈监控(SaaS) 高(付费)

选型建议

  1. 云原生环境

    • 指标监控:Prometheus + Grafana。
    • 链路追踪:Jaeger + OpenTelemetry。
    • 日志:ELK 或 Loki(轻量级替代)。
  2. 传统架构

    • 基础设施监控:Zabbix。
    • Java 应用 APM:SkyWalking。
  3. 企业级付费需求

    • 一体化 SaaS:Datadog 或 New Relic。
  4. 混合方案

    • Prometheus(指标) + ELK(日志) + Jaeger(Trace) + Grafana(统一展示)。

关键考量因素

  • 数据规模:海量日志选 ELK,高频指标选 Prometheus。
  • 实时性:交易系统优先 Jaeger/SkyWalking,批量处理可接受 ELK 延迟。
  • 团队技能:熟悉 K8s 选 Prometheus,传统运维团队选 Zabbix。
  • 成本:中小企业优先开源方案,预算充足可考虑 Datadog。