3、架构设计避坑:单点故障、高可用设计、数据采集层与存储层分离、避免过度设计
架构设计这事儿,说难不难,说简单也不简单。
我见过太多项目,一开始图省事,把所有东西都揉在一起。结果呢?系统一上线就出问题,采集节点挂了,数据库撑不住了,整个系统直接瘫痪。嗯,这种痛,经历过一次就忘不了。
今天咱们聊聊在线监测系统架构设计里,最容易踩的几个坑。说白了,就是四个关键词:单点故障、高可用、分层解耦、别过度设计。
3.1 单点故障:你系统里最脆弱的那个环节
什么是单点故障?就是系统里某个组件一旦挂了,整个服务就跟着完蛋。我习惯叫它「一锅端」风险。
举个例子。你想想看,如果所有采集数据都往同一台服务器上写,那台服务器宕机了会怎样?数据全丢,监控全黑。我曾经在项目中遇到过这种情况——凌晨三点,采集服务器硬盘满了,整个监控平台直接罢工。运维兄弟被电话叫醒,一脸懵。
怎么避免?记住一个原则:关键路径上不要有单点。
- 采集节点:至少部署两台,用负载均衡器分发任务
- 数据库:主从架构,或者用分布式数据库
- 消息队列:集群部署,保证消息不丢
- 网络:双网卡绑定,交换机做堆叠
3.2 高可用设计:不是堆机器那么简单
很多人以为高可用就是多买几台服务器。其实没那么简单。你想想看,两台机器如果配置一样,挂了一台,另一台能无缝接管吗?不一定。
我个人的习惯是,做高可用设计前,先问自己三个问题:
- 故障检测:怎么知道组件挂了?心跳检测?还是业务指标异常?
- 自动切换:检测到故障后,谁来接管?切换时间多长?
- 数据一致性:切换过程中,数据会不会丢?会不会重复?
举个例子。在线监测系统里,数据采集层的高可用,我一般这么设计:
# 采集节点高可用架构示意
采集节点A ——> 消息队列集群(3节点)
采集节点B ——> 消息队列集群(3节点)
|
v
数据消费服务(主备)
|
v
存储层(主从复制)
这里有个关键点:采集节点是无状态的。什么意思?就是节点A和节点B谁干活都一样,数据不保存在本地。这样即使一个节点挂了,另一个节点能立刻顶上,数据一条都不会丢。
3.3 数据采集层与存储层分离:解耦才是王道
这是很多新手容易犯的错——采集程序直接往数据库里写数据。你想想看,如果数据库压力大了,采集程序也会被拖慢,甚至卡死。反过来,采集程序出问题,数据库也可能被异常数据搞崩。
说白了,这就是耦合太紧。我习惯的做法是:中间加一层缓冲。
具体架构长这样:
采集层(传感器/网关)
|
v
消息队列(Kafka/RabbitMQ)
|
v
数据处理层(清洗、转换、聚合)
|
v
存储层(时序数据库 + 关系型数据库)
这样做的好处很明显:
- 采集层不关心数据存哪,只管往队列里扔
- 存储层不关心数据从哪来,只管从队列里取
- 任意一层出问题,都不会影响另一层
- 扩展性极好,采集节点不够就加,存储不够就扩
我记得有一次,客户要求把存储从InfluxDB换成TimescaleDB。因为采集层和存储层是分离的,我们只改了消费端的代码,采集节点一个都没动。嗯,这就是解耦的魅力。
3.4 避免过度设计:别为了架构而架构
这一点,我觉得比前面三点都重要。
你想想看,一个只有几十个监测点的系统,你非要上Kubernetes、上微服务、上分布式数据库。结果呢?运维成本比开发成本还高,团队天天忙着搭环境,业务功能反而没时间做。
我见过最夸张的一个项目,团队花了三个月搭了一套「完美」的架构,结果业务需求一变,整个架构推倒重来。为什么?因为过度设计导致系统太复杂,改不动。
怎么判断是不是过度设计?我一般用这个标准:
| 业务规模 | 推荐架构 | 不推荐 |
|---|---|---|
| < 100 个监测点 | 单体应用 + 单机数据库 | 微服务、分布式数据库 |
| 100 - 1000 个监测点 | 采集层与存储层分离 + 主从数据库 | Kubernetes、服务网格 |
| > 1000 个监测点 | 分层架构 + 消息队列 + 分布式存储 | 过度抽象、过度拆分 |
说白了,架构是为业务服务的,不是用来炫技的。能用简单方案解决的问题,就别搞复杂。
3.5 本章核心逻辑图
下面这张图,是我自己画的一个架构设计决策流程。你可以对照着看看,自己的系统在哪个阶段。
这张图的核心逻辑很简单:先解决单点故障,再解耦分层,最后检查是否过度设计。每一步都走对了,架构基本就稳了。
公众号:蓝海资料掘金营,微信deep3321