4、总体技术架构选型:后端框架(Spring Cloud/Go)、前端框架(Vue/React)、数据库选型(MySQL/Redis/时序库)

好,咱们直接切入正题。这一章聊的是技术选型,说白了就是「用什么家伙干活」。PIS系统统一管理平台,跟普通的后台管理系统不一样——它要管多条线路,实时性要求高,数据量大,而且不能随便宕机。我这些年踩过的坑,很多都跟选型有关。选对了,后面开发顺风顺水;选错了,重构起来真要命。

4.1 后端框架:Spring Cloud vs Go

先聊后端。这个选择题其实挺有意思的。我个人的习惯是:团队熟悉什么,就用什么。但PIS系统有它的特殊性,咱们得掰开揉碎了看。

核心结论:如果团队以Java为主,选Spring Cloud;如果团队有Go基础,或者对性能有极致要求,选Go。我个人更倾向于Spring Cloud + 部分Go微服务的混合方案。

4.1.1 Spring Cloud 方案

Spring Cloud在Java生态里,基本是「事实标准」了。为什么?因为它全家桶太全了——服务注册、配置中心、网关、熔断、负载均衡,开箱即用。

我记得有一次做PIS项目,客户要求对接12条线路,每条线路有自己的子系统。用Spring Cloud的Eureka做服务发现,Gateway做统一入口,Feign做服务间调用,一个月就把骨架搭起来了。嗯,这里要注意:Spring Cloud的版本兼容性是个坑。我建议用Spring Cloud Alibaba那套,Nacos做注册中心和配置中心,Sentinel做限流降级,比Netflix那套稳定得多。

// 一个典型的PIS服务注册配置
spring:
  application:
    name: pis-line-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.1.100:8848
      config:
        server-addr: 192.168.1.100:8848
        file-extension: yaml

4.1.2 Go 方案

Go的优势在哪?轻量、高性能、部署简单。PIS系统里,有些模块对延迟特别敏感——比如实时到站信息推送、设备状态采集。这些场景用Go写,一个goroutine就能搞定,内存占用还低。

我曾经在一个项目中,用Go重写了PIS的「数据采集网关」。原来Java版本跑了8个实例,换成Go后,2个实例就扛住了,CPU占用还降了60%。说实话,当时挺震撼的。

但Go也有短板:生态不如Java成熟。比如分布式事务、消息队列的客户端库,Go的成熟度差一些。我的建议是:核心业务逻辑用Spring Cloud,高并发、低延迟的模块用Go。两者通过gRPC通信,各取所长。

避坑指南:我曾经在一个项目里,强行用Go写了全部后端。结果到了后期,业务逻辑越来越复杂,Go的泛型(当时还没出)和错误处理让人抓狂。后来我学乖了——复杂业务用Java,简单高效用Go。

4.2 前端框架:Vue vs React

前端选型,其实比后端更「感性」。Vue和React都能做PIS管理平台,但体验上差别不小。

4.2.1 Vue 方案

我个人偏爱Vue。为什么?上手快、模板语法直观、生态统一。PIS管理平台有很多「数据展示型」页面——线路图、实时数据表、告警列表。Vue的模板语法,写起来就像在写HTML,设计师看了都能改两笔。

我建议用Vue 3 + Element Plus + Vite这套组合。Vite的HMR(热更新)快到飞起,开发体验极好。Element Plus的组件库,表格、表单、弹窗、树形控件,基本覆盖了PIS管理平台的所有需求。

// 一个PIS线路状态监控的Vue组件示例
<template>
  <div class="line-monitor">
    <el-table :data="lineData" border stripe>
      <el-table-column prop="lineName" label="线路名称" />
      <el-table-column prop="status" label="运行状态">
        <template #default="scope">
          <el-tag :type="scope.row.status === '正常' ? 'success' : 'danger'">
            {{ scope.row.status }}
          </el-tag>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

4.2.2 React 方案

React的优势在于灵活性和生态。如果你的PIS平台需要做很多「自定义交互」——比如拖拽式线路编辑、实时画布渲染,React的Hooks和JSX会更顺手。

但说实话,PIS管理平台这种「中后台系统」,React的灵活性反而容易「过度设计」。我见过一个团队用React写PIS,结果每个页面都要自己封装组件,开发效率比Vue慢了一倍。

我的建议:如果团队Vue熟,就用Vue;如果团队React熟,就用React。非要选一个,PIS管理平台我推荐Vue——因为它的模板语法和组件库,更适合「数据展示+表单操作」这种场景。

4.3 数据库选型:MySQL + Redis + 时序库

数据库选型,是PIS系统的「地基」。我见过太多项目,因为数据库选型不对,后期性能崩得一塌糊涂。

4.3.1 MySQL:关系数据的基石

MySQL用来存什么?线路信息、车站信息、设备台账、用户权限、配置数据。这些数据的特点是:结构化、关联性强、读写比例均衡。

我建议用MySQL 8.0+,字符集用utf8mb4(支持emoji,你懂的,车站名有时候会有特殊字符)。表设计上,注意分库分表——PIS系统线路多,每条线路的数据可以独立一个库,或者按线路ID做分表。

注意:MySQL不适合存「高频时序数据」。我曾经有个客户,把列车到站记录全塞MySQL里,一天几百万条,三个月后查询慢得像蜗牛。后来我帮他迁移到时序库,问题才解决。

4.3.2 Redis:缓存与实时数据

Redis在PIS系统里,作用太大了。我总结三个核心场景:

  • 缓存热点数据:线路基础信息、车站列表、设备状态——这些数据变化不频繁,但查询频繁。用Redis缓存,响应时间从几十毫秒降到几毫秒。
  • 实时状态存储:列车当前位置、到站倒计时、设备在线状态。这些数据「实时更新、频繁读取」,Redis的String和Hash结构完美适配。
  • 分布式锁与计数器:多线路并发操作时,用Redis做分布式锁,防止数据冲突。
// 用Redis存储列车实时位置
// Key: train:position:{lineId}:{trainId}
// Value: {"stationId":"S001","arrivalTime":"2024-01-15 10:30:00","direction":"上行"}
redisTemplate.opsForValue().set(
    "train:position:line1:T001",
    JSON.toJSONString(positionData),
    30, TimeUnit.SECONDS  // 30秒过期,自动清理旧数据
);

4.3.3 时序库:海量监控数据的归宿

PIS系统会产生大量「时序数据」——设备运行日志、列车到站记录、客流统计、告警事件。这些数据的特点是:写入频繁、查询按时间范围、几乎不更新

我推荐用InfluxDBTDengine。前者生态成熟,后者国产化且性能更强。我个人更倾向TDengine——它对物联网场景做了很多优化,比如「超级表」设计,可以按线路、设备类型做自动分区,查询效率极高。

数据类型 存储方案 典型数据量 查询特点
线路/车站基础信息 MySQL 千级 按ID查询,低频更新
设备台账 MySQL 万级 按线路/类型查询
实时位置/状态 Redis 千级(实时) 毫秒级读写
设备运行日志 时序库 亿级/月 按时间范围聚合查询
告警事件 时序库 + MySQL 百万级/月 实时告警查Redis,历史告警查时序库

我的经验:时序库的「保留策略」一定要提前规划。比如设备日志保留30天,告警事件保留90天。过期数据自动删除或归档,不然存储成本会失控。我曾经有个项目,忘了设保留策略,三个月后硬盘满了,半夜被叫起来扩容……嗯,那种滋味不好受。

4.4 整体架构总结

好了,咱们把选型串起来,看看整体架构长什么样:

  • 后端:Spring Cloud(核心业务)+ Go(高并发模块),gRPC通信
  • 前端:Vue 3 + Element Plus + Vite
  • 数据库:MySQL(关系数据)+ Redis(缓存/实时数据)+ TDengine(时序数据)
  • 消息队列:RocketMQ或Kafka(用于线路间数据同步,下一章会细讲)

这套架构,我在三个PIS项目里验证过。说实话,不是最「炫酷」的,但绝对是最「稳」的。你想想看,PIS系统是给地铁用的,稳定性比什么都重要。选型的时候,别追求新技术,要追求「经过验证的成熟方案」。

下一章,咱们聊聊「微服务拆分与通信」——怎么把PIS系统拆成十几个微服务,还能让它们高效协作。嗯,那才是真正考验架构能力的地方。