上一篇【第13篇】Server部署详解:解读指挥中心的控制面板
下一篇【第15篇】SkyWalking存储选型指南:为档案馆挑选最佳建材
上一篇我们解读了OAP Server的配置面板。但单节点的指挥中心就像一个光杆司令——一旦他倒下,整个可观测性帝国就瘫痪了。更严重的是,当数据量暴涨时,单节点根本扛不住。
今天,我们要把光杆司令升级为联合指挥部——多个OAP节点协同作战,有备用指挥官接替,有协调器统一调度,有共享的档案馆存储数据。
1. OAP集群的必要性
1.1 单节点的三大隐患
┌──────────────────────────────────────────────────────────────────┐ │ 单节点 OAP 的三大隐患 │ │ │ │ ① 可用性风险:单节点 = 单点故障 │ │ ┌─── OAP(唯一) ───┐ │ │ │ 挂了 = 全挂 │ ← 一个故障,全线崩溃 │ │ └─────────────────┘ │ │ │ │ ② 性能瓶颈:单节点的处理能力有上限 │ │ ┌─── OAP ─────────┐ │ │ │ 数据聚合 → 慢 │ ← QPS越高,处理越慢 │ │ │ 数据写入 → 慢 │ ← ES写入瓶颈 │ │ │ 数据查询 → 慢 │ ← 内存缓存不够 │ │ └─────────────────┘ │ │ │ │ ③ 数据倾斜:部分服务的数据量远超其他 │ │ ┌─── OAP ─────────┐ │ │ │ 用户服务→海量 │ ← 一个热门服务就占满资源 │ │ │ 订单服务→中等 │ │ │ │ 后台服务→少量 │ │ │ └─────────────────┘ │ └──────────────────────────────────────────────────────────────────┘1.2 集群解决了什么
集群化后,每个问题都得到解决:
| 单节点问题 | 集群解决方案 |
|---|---|
| 单点故障 | 多节点冗余,任一节点挂了不影响全局 |
| 性能瓶颈 | 多节点分摊负载,聚合和写入并行 |
| 数据倾斜 | 自然负载均衡,数据自动分配到不同节点 |
2. 集群协调器选型
2.1 协调器的作用
OAP集群中的节点需要互相知道彼此的存在——谁在线、谁挂了、数据怎么分片。协调器就像联合指挥部的通讯官:
┌──────────────────────────────────────────────────────────────────┐ │ 集群协调器在OAP集群中的角色 │ │ │ │ ┌──────────┐ │ │ │ OAP-1 │──→ 注册 ──→ 协调器:"我在线,192.168.1.100" │ │ └──────────┘ │ │ ┌──────────┐ │ │ │ OAP-2 │──→ 注册 ──→ 协调器:"我在线,192.168.1.101" │ │ └──────────┘ │ │ ┌──────────┐ │ │ │ OAP-3 │──→ 注册 ──→ 协调器:"我在线,192.168.1.102" │ │ └──────────┘ │ │ │ │ 协调器(Nacos/ZK/Consul/Etcd) │ │ ├─→ 维护节点列表 │ │ ├─→ 通知节点变更 │ │ └─→ 协调数据分片 │ │ │ │ OAP-1收到通知 ──→ 知道OAP-2和OAP-3在哪里 │ │ Agent连接OAP-1 ──→ OAP-1可以转发数据到正确的节点 │ └──────────────────────────────────────────────────────────────────┘2.2 五种协调器对比
┌──────────────────────────────────────────────────────────────────┐ │ 集群协调器选型对比表 │ │ │ │ ┌──────┬──────┬──────┬──────┬──────┬──────┐ │ │ │ 特性 │Nacos │ ZK │Consul│ Etcd │ K8s │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │运维 │ 中 │ 高 │ 中 │ 中 │ 低 │ │ │ │复杂度│ │(重量级│ │ │(K8s │ │ │ │ │ │) │ │ │原生) │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │社区 │ 大 │ 大 │ 中 │ 中 │ 大 │ │ │ │活跃度│(阿里)│(Apache│ │(CNCF │(CNCF │ │ │ │ │ │) │ │) │) │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │选型 │已有 │已有 │已有 │已有 │纯K8s │ │ │ │建议 │Nacos │ZK │Consul│Etcd │环境 │ │ │ │ │基础 │基础 │基础 │基础 │ │ │ │ ├──────┼──────┼──────┼──────┼──────┼──────┤ │ │ │性能 │★★★★ │★★★ │★★★★ │★★★★ │★★★ │ │ │ │ │ │(会话 │ │ │(API │ │ │ │ │ │开销) │ │ │限速) │ │ │ └──────────────────────────────────────────────────┘ │ │ │ │ 核心原则:不引入新基础设施,复用已有的 │ └──────────────────────────────────────────────────────────────────┘2.3 选型决策流程
选择协调器不需要纠结——最简单的原则是"用你已有的":
┌──────────────────────────────────────────────────────────────────┐ │ 协调器选型决策树 │ │ │ │ 你的基础设施中已有哪个? │ │ │ │ │ ├──→ Nacos? ──→ 用Nacos(推荐,运维最轻) │ │ │ │ │ ├──→ ZooKeeper? ──→ 用ZK(老牌稳定) │ │ │ │ │ ├──→ Consul? ──→ 用Consul(轻量现代) │ │ │ │ │ ├──→ Etcd? ──→ 用Etcd(CNCF生态) │ │ │ │ │ ├──→ 纯K8s? ──→ 用K8s原生(最省资源) │ │ │ │ │ └──→ 都没有? ──→ 先用standalone单节点 │ │ 后续引入Nacos(最轻量) │ └──────────────────────────────────────────────────────────────────┘3. Nacos作为集群协调器的完整配置
3.1 为什么推荐Nacos
Nacos是阿里开源的服务发现与配置管理平台,在国内微服务生态中使用率极高。如果你的团队已经在用Nacos做服务注册,用它作为SkyWalking的集群协调器是零额外成本的选择。
Nacos的优势:
- 轻量级,启动快,运维简单
- 支持命名空间隔离(不同环境用不同命名空间)
- Web UI方便查看注册信息
- 性能足够(单个Nacos节点可支撑数千服务实例)
3.2 OAP Server的Nacos配置
# application.yamlcluster:selector:${SW_CLUSTER:nacos}nacos:# Nacos服务器列表(多个用逗号分隔)serverList:${SW_CLUSTER_NACOS_SERVER_LIST:127.0.0.1:8848}# 命名空间ID(不同环境用不同命名空间)namespace:${SW_CLUSTER_NACOS_NAMESPACE:public}# 服务分组group:${SW_CLUSTER_NACOS_GROUP:skywalking}# 集群名称clusterName:${SW_CLUSTER_NACOS_CLUSTER_NAME:default}# Nacos认证信息(如果Nacos启用了认证)username:${SW_CLUSTER_NACOS_USERNAME:nacos}password:${SW_CLUSTER_NACOS_PASSWORD:nacos}3.3 Nacos环境准备
# 方式一:单机Nacos(开发/测试环境)dockerrun-d\--namenacos\-eMODE=standalone\-p8848:8848\nacos/nacos-server:v2.2.3# 方式二:集群Nacos(生产环境)# 至少3个节点dockerrun-d\--namenacos1\-eMODE=cluster\-eNACOS_SERVERS="nacos1:8848 nacos2:8848 nacos3:8848"\-eSPRING_DATASOURCE_PLATFORM=mysql\-eMYSQL_SERVICE_HOST=mysql-host\-p8848:8848\nacos/nacos-server:v2.2.33.4 验证Nacos注册
OAP启动后,可以在Nacos的控制台看到注册信息:
# 通过Nacos API查询curl"http://nacos-host:8848/nacos/v1/ns/instance/list?serviceName=skywalking&groupName=skywalking&namespaceId=public"# 返回结果中应包含所有OAP节点的IP和端口4. Elasticsearch存储集群配置
4.1 为什么ES也要集群
OAP集群解决了计算节点的可用性,但数据存储也需要集群化。如果ES是单节点,数据还是单点存储:
┌──────────────────────────────────────────────────────────────────┐ │ 完整的高可用架构 │ │ │ │ ┌───────────────────┐ ┌───────────────────┐ │ │ │ OAP集群(3节点) │ │ ES集群(3节点) │ │ │ │ ┌───┐ ┌───┐ │ │ ┌───┐ ┌───┐ │ │ │ │ │O1 │ │O2 │ O3 │───→│ │E1 │ │E2 │ E3 │ │ │ │ └───┘ └───┘ │ │ └───┘ └───┘ │ │ │ │ Nacos协调 │ │ 分片+副本 │ │ │ └───────────────────┘ └───────────────────┘ │ │ │ │ │ │ │ │ │ │ 计算层高可用 存储层高可用 │ │ 任一OAP挂了 任一ES挂了 │ │ 其他节点接替 副本分片接替 │ │ 数据仍在ES中 数据不丢失 │ └──────────────────────────────────────────────────────────────────┘4.2 ES集群配置
# application.yamlstorage:selector:${SW_STORAGE:elasticsearch}elasticsearch:# ES集群节点列表(至少写2个,保证连接可靠性)clusterNodes:${SW_CLUSTER_NODES:es-node1:9200,es-node2:9200,es-node3:9200}# ES协议(如果ES启用了TLS)protocol:${SW_STORAGE_ES_PROTOCOL:http}# 索引分片数(根据ES节点数调整,一般=节点数)indexShardsNumber:${SW_STORAGE_ES_INDEX_SHARDS_NUMBER:3}# 索引副本数(至少1,保证单节点故障数据不丢)indexReplicasNumber:${SW_STORAGE_ES_INDEX_REPLICAS_NUMBER:1}# 超大数据集(Trace数据)的分片倍数superDatasetIndexShardsFactor:${SW_STORAGE_ES_SUPER_DATASET_INDEX_SHARDS_FACTOR:5}# 批量写入参数bulkActions:${SW_STORAGE_ES_BULK_ACTIONS:5000}bulkSize:${SW_STORAGE_ES_BULK_SIZE:50}flushInterval:${SW_STORAGE_ES_FLUSH_INTERVAL:30}concurrentRequests:${SW_STORAGE_ES_CONCURRENT_REQUESTS:2}分片与副本的配置建议:
| 规模 | ES节点数 | indexShardsNumber | indexReplicasNumber | superDataset倍数 |
|---|---|---|---|---|
| 小规模 | 3 | 1 | 1 | 3 |
| 中规模 | 5 | 3 | 1 | 5 |
| 大规模 | 7+ | 5 | 2 | 7 |
4.3 ES集群部署脚本
# 使用Docker Compose部署ES集群cat>docker-compose-es.yml<<'EOF' version: '3.8' services: es-node1: image: elasticsearch:8.12.0 environment: - cluster.name=skywalking-es - node.name=es-node1 - discovery.seed_hosts=es-node2,es-node3 - cluster.initial_master_nodes=es-node1,es-node2,es-node3 - "ES_JAVA_OPTS=-Xms2g -Xmx2g" - xpack.security.enabled=false volumes: - es-data1:/usr/share/elasticsearch/data ports: - "9200:9200" es-node2: image: elasticsearch:8.12.0 environment: - cluster.name=skywalking-es - node.name=es-node2 - discovery.seed_hosts=es-node1,es-node3 - cluster.initial_master_nodes=es-node1,es-node2,es-node3 - "ES_JAVA_OPTS=-Xms2g -Xmx2g" - xpack.security.enabled=false volumes: - es-data2:/usr/share/elasticsearch/data es-node3: image: elasticsearch:8.12.0 environment: - cluster.name=skywalking-es - node.name=es-node3 - discovery.seed_hosts=es-node1,es-node2 - cluster.initial_master_nodes=es-node1,es-node2,es-node3 - "ES_JAVA_OPTS=-Xms2g -Xmx2g" - xpack.security.enabled=false volumes: - es-data3:/usr/share/elasticsearch/data volumes: es-data1: es-data2: es-data3: EOFdocker-compose-fdocker-compose-es.yml up-d5. 负载均衡器配置
5.1 为什么需要负载均衡
Agent连接OAP时,如果只连一个节点,那这个节点挂了Agent就断线了。负载均衡器就像指挥中心的调度台——把Agent的连接均匀分配到各个OAP节点,并在节点故障时自动切换:
┌──────────────────────────────────────────────────────────────────┐ │ 负载均衡器在SkyWalking集群中的位置 │ │ │ │ Agent1 ──→ ┌──────────┐ ──→ OAP-1 │ │ Agent2 ──→ │ LB │ ──→ OAP-2 │ │ Agent3 ──→ │(Nginx/ │ ──→ OAP-3 │ │ Agent4 ──→ │ HAProxy) │ │ │ └──────────┘ │ │ │ │ LB功能: │ │ ├─→ 健康检查:定期检测OAP节点是否在线 │ │ ├─→ 负载分配:将Agent连接均匀分配 │ │ └─→ 故障切换:节点挂了自动路由到其他节点 │ │ │ │ 注意:gRPC使用HTTP/2,LB必须支持HTTP/2 │ └──────────────────────────────────────────────────────────────────┘5.2 Nginx配置(推荐)
# nginx.conf - SkyWalking OAP gRPC负载均衡 # gRPC需要HTTP/2支持 # Nginx 1.13.10+开始支持gRPC代理 stream { upstream skywalking_grpc { # gRPC负载均衡(最少连接模式) least_conn; server 192.168.1.100:11800; server 192.168.1.101:11800; server 192.168.1.102:11800; } server { listen 11800; # 将gRPC流量代理到OAP集群 proxy_pass skywalking_grpc; # 连接超时 proxy_connect_timeout 5s; # 会话保持(gRPC需要长连接) proxy_session_timeout 3600s; } } http { upstream skywalking_rest { # REST API负载均衡(轮询模式) round_robin; server 192.168.1.100:12800; server 192.168.1.101:12800; server 192.168.1.102:12800; } server { listen 12800; location / { proxy_pass http://skywalking_rest; } } }5.3 HAProxy配置(备选)
# haproxy.cfg - SkyWalking OAP负载均衡 frontend grpc_front bind *:11800 mode tcp # gRPC流量识别(HTTP/2 preamble) option tcp-check default_backend grpc_back backend grpc_back mode tcp balance leastconn option httpchk GET /api/status http-check expect status 200 server oap1 192.168.1.100:11800 check server oap2 192.168.1.101:11800 check server oap3 192.168.1.102:11800 check frontend rest_front bind *:12800 mode http default_backend rest_back backend rest_back mode http balance roundrobin server oap1 192.168.1.100:12800 check server oap2 192.168.1.101:12800 check server oap3 192.168.1.102:12800 check5.4 Agent连接负载均衡器
Agent不需要知道所有OAP节点——只需要知道负载均衡器的地址:
# agent.config - Agent连接LB collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:lb-host:11800} # 多个LB地址(LB本身也需要高可用) collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:lb1:11800,lb2:11800}6. 完整集群部署——Docker Compose实战
把所有组件整合到一个Docker Compose文件中:
# docker-compose-cluster.ymlversion:'3.8'services:# Nacos集群协调器nacos:image:nacos/nacos-server:v2.2.3environment:MODE:standaloneports:-"8848:8848"# ES存储集群(3节点)es-node1:image:elasticsearch:8.12.0environment:-cluster.name=skywalking-es-node.name=es-node1-discovery.seed_hosts=es-node2,es-node3-cluster.initial_master_nodes=es-node1,es-node2,es-node3-"ES_JAVA_OPTS=-Xms2g -Xmx2g"-xpack.security.enabled=falsevolumes:-es-data1:/usr/share/elasticsearch/dataes-node2:image:elasticsearch:8.12.0environment:-cluster.name=skywalking-es-node.name=es-node2-discovery.seed_hosts=es-node1,es-node3-cluster.initial_master_nodes=es-node1,es-node2,es-node3-"ES_JAVA_OPTS=-Xms2g -Xmx2g"-xpack.security.enabled=falsevolumes:-es-data2:/usr/share/elasticsearch/dataes-node3:image:elasticsearch:8.12.0environment:-cluster.name=skywalking-es-node.name=es-node3-discovery.seed_hosts=es-node1,es-node2-cluster.initial_master_nodes=es-node1,es-node2,es-node3-"ES_JAVA_OPTS=-Xms2g -Xmx2g"-xpack.security.enabled=falsevolumes:-es-data3:/usr/share/elasticsearch/data# OAP集群(2节点)oap1:image:apache/skywalking-oap-server:9.3.0environment:-SW_CLUSTER=nacos-SW_CLUSTER_NACOS_SERVER_LIST=nacos:8848-SW_STORAGE=elasticsearch-SW_CLUSTER_NODES=es-node1:9200,es-node2:9200,es-node3:9200-SW_STORAGE_ES_INDEX_SHARDS_NUMBER=3-SW_STORAGE_ES_INDEX_REPLICAS_NUMBER=1depends_on:-nacos-es-node1ports:-"11800:11800"-"12800:12800"oap2:image:apache/skywalking-oap-server:9.3.0environment:-SW_CLUSTER=nacos-SW_CLUSTER_NACOS_SERVER_LIST=nacos:8848-SW_STORAGE=elasticsearch-SW_CLUSTER_NODES=es-node1:9200,es-node2:9200,es-node3:9200-SW_STORAGE_ES_INDEX_SHARDS_NUMBER=3-SW_STORAGE_ES_INDEX_REPLICAS_NUMBER=1depends_on:-nacos-es-node1# SkyWalking UIui:image:apache/skywalking-ui:9.3.0environment:-SW_OAP_ADDRESS=oap1:12800depends_on:-oap1ports:-"8080:8080"volumes:es-data1:es-data2:es-data3:7. 小结
集群部署的本质是"消除单点"——从指挥中心升级为联合指挥部:
- OAP集群:多节点分摊负载,任一节点故障不影响全局
- 协调器选型:用你已有的基础设施(Nacos/ZK/Consul/Etcd)
- Nacos配置:最轻量的协调器,零额外运维成本
- ES集群:分片+副本保证数据可用性
- 负载均衡:Nginx/HAProxy在Agent和OAP之间做流量分配
下一篇文章,我们将专门讨论存储选型——从H2到MySQL到ES,不同规模应该用什么存储方案。
上一篇【第13篇】Server部署详解:解读指挥中心的控制面板
下一篇【第15篇】SkyWalking存储选型指南:为档案馆挑选最佳建材