中间件学习路径:日志、消息、网关与数据高可用

使用方式

中间件学习的难点不是安装,而是理解每种组件在系统里承担的状态:连接、队列、分区、副本和一致性。这条路径按“可观测 → 异步解耦 → 流量入口 → 数据高可用”推进。

四个阶段按依赖顺序排列,每个阶段建议留 3–4 小时:

每个阶段都要至少制造一次故障,观察组件如何降级,而不是只看健康状态的截图。

阶段一:日志与搜索

目标:能把分散的日志采集、缓冲、索引、查询串起来,并说清全文索引和标签索引的成本差异。

阅读顺序:

  1. elasticsearch — 倒排索引、分片、副本和查询模型。
  2. logstash — input、filter、output 管道的缓冲和背压。
  3. kibana — 索引模式、查询和可视化。
  4. loki — 只索引标签、不索引全文的日志存储模型。
  5. vector — 轻量采集、转换和路由,适合作为 agent。
  6. filebeat — 文件采集、registry 和多行日志处理。
  7. opensearch — Elasticsearch 的开源分支与兼容差异。
  8. loki-vs-elk — 两种日志方案的选型边界。
  9. logql-cheatsheet — Loki 查询语法速查。
  10. opensearch-dashboards — OpenSearch 的查询与看板入口。

动手任务:用 Docker Compose 搭一套 Loki + Vector,采集容器日志,按标签查询错误日志;再对比一次全文搜索和标签过滤的查询成本。

docker compose up -d
docker compose logs vector --tail 20
curl -s 'http://localhost:3100/loki/api/v1/labels'
curl -sG 'http://localhost:3100/loki/api/v1/query_range' \
  --data-urlencode 'query={container="app"} |= "ERROR"' \
  --data-urlencode 'limit=20'

过关标准:

阶段二:消息与协调

目标:理解消息系统如何在生产者、broker、消费者之间传递状态,以及顺序、重复和积压从哪来。

阅读顺序:

  1. kafka-broker — topic、partition、offset 和 broker 的职责。
  2. zookeeper — 元数据、选举和 Kafka 旧架构中的角色。
  3. schema-registry — 消息格式演进和兼容性策略。
  4. rabbitmq — exchange、queue、ack 和路由模型。
  5. kafka-connect — 用连接器把外部系统接入 Kafka。
  6. redpanda — 兼容 Kafka 协议的另一套存储实现。
  7. ksql — 在流上做持续查询和聚合。
  8. kafka-cheatsheet — Kafka 常用命令速查。
  9. kafka-vs-rabbitmq — 日志流与任务队列的选型差异。

动手任务:用 Compose 启动 Kafka 和 Schema Registry,创建一个三分区 topic,用 key 验证分区内顺序,再启动两个消费者观察 rebalance 和积压。

docker compose up -d kafka schema-registry
docker compose exec kafka kafka-topics --bootstrap-server localhost:9092 \
  --create --topic events --partitions 3 --replication-factor 1
docker compose exec kafka kafka-console-producer --bootstrap-server localhost:9092 \
  --topic events --property parse.key=true --property key.separator=:
docker compose exec kafka kafka-console-consumer --bootstrap-server localhost:9092 \
  --topic events --group lab --property print.key=true
docker compose exec kafka kafka-consumer-groups --bootstrap-server localhost:9092 \
  --describe --group lab

过关标准:

阶段三:网关与接入

目标:能让外部流量安全、可观测地进入系统,理解反向代理、负载均衡、VIP 和身份认证的职责边界。

阅读顺序:

  1. nginx — 反向代理、upstream、超时和缓冲区。
  2. haproxy — L4/L7 负载均衡、健康检查和连接队列。
  3. keepalived — VRRP 虚拟 IP 和主备切换。
  4. keycloak — OIDC/OAuth2 身份提供方、realm 和客户端。
  5. openresty — 基于 Nginx 的可编程网关。
  6. oauth2-proxy — 给没有原生认证的应用加上统一登录。
  7. nginx-cheatsheet — Nginx 配置与排障速查。
  8. haproxy-vs-nginx — 负载均衡与反向代理的选型。
  9. nginx-vs-caddy — 自动 HTTPS 与配置复杂度的权衡。

动手任务:用 Nginx 反向代理两个后端,配置健康检查和超时;用 HAProxy 做一次主动健康检查;再用 Keycloak + oauth2-proxy 保护一个测试应用。

nginx -t
curl -I -H 'Host: demo.local' http://127.0.0.1/
docker compose exec haproxy sh -c 'echo "show stat" | socat stdio /var/run/haproxy.sock'
curl -s http://localhost:8080/realms/lab/.well-known/openid-configuration

过关标准:

阶段四:数据与高可用

目标:理解连接池、主从切换、分片副本和向量索引,能判断故障时数据是否安全、服务是否可写。

阅读顺序:

  1. pgbouncer — 连接池模式、事务边界和连接复用。
  2. redis-cluster — 16384 个 hash slot、主从和故障转移。
  3. patroni — PostgreSQL 高可用、etcd 共识和 leader 切换。
  4. qdrant — 向量集合、分片、副本和检索参数。
  5. elasticsearch-cluster — 主节点、数据节点、分片分配和脑裂防护。
  6. proxysql — MySQL 读写分离、连接池和查询规则。
  7. mysql-router — InnoDB Cluster 的路由和故障转移。
  8. pgvector — 在 PostgreSQL 内做向量检索的索引与权衡。
  9. orchestrator — MySQL 拓扑发现和主从切换。
  10. valkey — Redis 兼容实现与迁移注意点。

动手任务:搭一套 PostgreSQL + PgBouncer,观察连接复用;搭三主三从 Redis Cluster,制造一次主节点故障并确认槽位迁移;在 Qdrant 建集合写入向量并查询。

docker compose up -d postgres pgbouncer
psql -h 127.0.0.1 -p 6432 -U app -c 'select count(*) from pg_stat_activity;'
redis-cli -c -p 7000 cluster info
redis-cli -c -p 7000 cluster nodes
curl -s http://localhost:6333/collections

过关标准:

常见误区

读完自测

合上页面,先回答,再展开对照。

  1. Kafka 如何保证同一业务实体的消息顺序?增加分区会带来什么影响?
  2. PgBouncer 的事务池模式为什么要求应用不能依赖会话级状态?
  3. Redis Cluster 的主节点故障后,客户端为什么可能短暂写入失败?
答案
  1. 用业务实体 ID 作为消息 key,Kafka 对 key 做哈希后固定写到同一个分区,分区内 offset 有序。增加分区会改变 key 到分区的映射,同一 key 的历史消息和新消息可能落在不同分区,顺序不再有保证;扩容前要评估这一点。
  2. 事务池模式在事务结束后就把连接归还给池,下一个事务可能复用给其他客户端。会话级临时表、SET 会话变量、预备语句和会话锁都可能丢失或串扰,因此应用必须把状态放在事务内或外部存储。
  3. 主节点故障后,集群需要先判定失败、提升从节点并迁移槽位。这段时间内部分槽位没有可写主节点,客户端会收到 CLUSTERDOWN 或重定向失败;如果客户端缓存了旧拓扑,还会继续访问失效节点,直到刷新路由表。

相关条目