基于Spring Cloud的环境污染物数据分析与预测平台实战解析
发布时间:2026/10/2 14:42:09来源:尧图网络
简介这份资源是一套基于Spring Cloud的环境污染物数据分析与预测平台毕设源码采用Consul、Zuul、Config等微服务组件整合Kafka、Redis、Flask与Keras覆盖数据可视化、空气质量排行、PM2.5预测、污染物预警、历史数据导出及后台管理等功能数据源来自上海市环境监测中心及和风天气、腾讯天气等开放接口。资源共2000个文件以js、css等前端文件为主搭配java、xml等后端工程文件以及json、md说明文档压缩包整体57.49MB适合计算机相关专业学生用于毕业设计、课程设计或期末大作业也适合希望学习微服务与数据预测项目架构的开发者参考。项目代码完整且经过验证内部模块划分清晰附带详细项目说明既可直接部署体验也可在此基础上扩展预测模型、优化预警策略或重构前后端作为二次开发起点。资源已有225人浏览学习文档中对服务端口、缓存策略与模型训练流程均有说明能帮助有基础的学习者更快上手。1. 环境污染物数据分析与预测平台Spring Cloud 毕设到底在做什么如果你正在选毕设方向又不想做那种“登录注册 CRUD”的管理系统那“基于 Spring Cloud 的环境污染物数据分析与预测平台”是一个很合适的切入点。它表面上是微服务架构的展示实际上是一条完整的数据链路采集污染物数据、清洗入库、统计分析、训练预测模型、把预测结果通过接口暴露给前端大屏。答辩时你可以讲架构、讲算法、讲数据流任何一个点都能展开不会冷场。这套平台的直接价值在于它把 Spring Cloud 的注册发现、网关路由、熔断限流这些微服务概念落到了一个有真实业务含义的场景里。空气质量指数、PM2.5、PM10、二氧化硫、二氧化氮、臭氧这些指标大家都熟悉预测“明天会不会超标”比预测“用户会不会流失”更容易让评委听懂。适合 Java 方向、想往大数据分析或环保信息化方向靠的本科生。下文我会按“架构拆分 → 数据链路 → 预测模型接入 → 踩坑 → 验证演示”的顺序把整个平台的落地路径讲清楚。你不用照着某个现成源码抄按这套设计自己搭也能搭出一模一样的东西。2. 拆解微服务架构Spring Cloud Alibaba 全家桶的选型与模块边界2.1 服务怎么拆从单体到五个微服务很多毕设项目的问题是“微服务”只是个幌子拆了三四个服务代码加起来还不如一个单体大。环境污染分析与预测平台要拆得合理得先看业务边界。我建议按数据流拆成五个基础服务gateway-service网关负责统一入口、鉴权、路由转发。auth-service登录与用户管理维护操作员账号生成 JWT。># 单机模式启动 Nacos默认端口 8848 sh startup.sh -m standalone # Windows 下用 startup.cmd -m standalone启动后在application.yml里让各个服务注册进来spring: application: name: analysis-service cloud: nacos: discovery: server-addr: 127.0.0.1:8848 namespace: public config: server-addr: 127.0.0.1:8848 file-extension: yaml group: DEFAULT_GROUP这里两个参数容易被忽略。namespace如果不写默认进 public 空间毕设不需要多环境隔离保持 public 即可。file-extension写 yaml 后Nacos 会自动加载analysis-service.yaml这个配置数据源、Redis 地址都可以放到 Nacos 上管理这样部署到实验室服务器时不用改 jar 包里的配置只改 Nacos 控制台就行。依赖方面给 common 或每个服务引入dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependency dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-config/artifactId /dependency注意bootstrap.yml里要配置spring.cloud.nacos.config.server-addr和spring.application.name因为 Spring Boot 2.4 之后config的导入时机变了很多新人把配置写在application.yml里导致 Nacos 上的配置始终不生效。2.3 网关与熔断Gateway Sentinel 的限流规则怎么订网关我用的是 Spring Cloud Gateway不建议用 Zuul性能和维护性都差一截。网关层要做两件事按路径转发到对应服务给预测接口单独做限流。spring: cloud: gateway: routes: - id: analysis-route uri: lb://analysis-service predicates: - Path/api/analysis/** filters: - StripPrefix1 - id: prediction-route uri: lb://prediction-service predicates: - Path/api/prediction/** filters: - StripPrefix1lb://是让网关走负载均衡后面接服务名而不是 IP这样服务换了端口也不用改网关配置。StripPrefix1的意思是把/api/analysis/trend转成/trend再发给 analysis-service服务内部接口不需要带api前缀。预测接口是耗时操作必须单独限流不然大屏一刷新、多用户同时点“预测”prediction-service 的线程池会被占满。在 Sentinel 控制台加一条规则针对prediction-service的/api/prediction/forecast资源QPS 阈值设为 20超出后直接排队或快速失败。一般毕设演示只有几个人用QPS 20 足够调太低反而会让演示现场误触限流显得系统不稳。Sentinel 的接入依赖是dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-sentinel/artifactId /dependency接入后在application.yml里打开 Sentinel 控制台地址spring: cloud: sentinel: transport: dashboard: 127.0.0.1:8080这里要说清楚Sentinel 的规则默认是内存态重启服务就没了。毕设答辩现场重启是常事我建议把核心限流规则用SentinelResource注解写在代码里或者用 Nacos 做规则持久化不要靠在控制台手动配。3. 污染物数据从哪来数据采集、清洗与入库链路3.1 数据源选定真实 API、公开数据集与模拟生成器毕设的环境数据有三个来源按推荐程度排序一是国家和省市开放平台的历史空气质量数据CSV 格式字段齐全适合做离线分析和模型训练二是爬取实时监测站点数据但反爬和稳定性会消耗大量时间不建议作为主要数据源三是自己写数据生成器模拟一天 24 小时的污染物浓度变化曲线。我做过一次后最推荐的组合是用公开历史数据训练模型用模拟生成器持续产生实时数据供平台演示。为什么因为真实的实时接口不稳定答辩当天如果拉不到数据整个分析页面上全是空图那时只能干瞪眼。模拟数据生成器可以让你控制数据形态比如让 PM2.5 在早晚高峰升高、在午后降低趋势符合常识解释起来可信。模拟生成器用一个独立的 Python 脚本跑往 MySQL 写数据Spring Cloud 这边只管读。这样采集链路不会影响微服务本身import random import time from datetime import datetime import pymysql def generate_pm25(base_hour): # 早晚高峰因子7-9点 和 18-21点 相对高午后低 if 7 base_hour 9: factor random.uniform(1.2, 1.5) elif 18 base_hour 21: factor random.uniform(1.3, 1.6) elif 12 base_hour 15: factor random.uniform(0.6, 0.9) else: factor random.uniform(0.9, 1.2) return round(35 * factor random.uniform(-5, 5), 1) while True: now datetime.now() pm25 generate_pm25(now.hour) conn pymysql.connect(host127.0.0.1, userroot, password123456, databaseair_quality) with conn.cursor() as cursor: sql INSERT INTO pollutant_data(station_id, pm25, pm10, so2, no2, ozone, collect_time) VALUES (%s, %s, %s, %s, %s, %s, %s) cursor.execute(sql, (station_01, pm25, round(pm25 * 1.6, 1), round(random.uniform(5, 15), 1), round(random.uniform(10, 30), 1), round(random.uniform(30, 80), 1), now)) conn.commit() conn.close() time.sleep(3600)注意参数里有两个细节。base_hour用的是now.hour采集一次后sleep(3600)等待一小时这样每天只有 24 条数据连续跑一周能积累 168 条足够支撑折线图和基本趋势分析。station_id写死为station_01如果你想做多站点对比可以循环生成station_01到station_05五条记录模拟五个国控站点对应地SQL 的collect_time要统一到整点方便按时间对齐做分析。3.2 定时采集与清洗如何让数据进得整齐用 Python 脚本生成数据没问题但它只是往表里插数据真正让数据“干净”的是清洗逻辑。比如传感器偶尔会返回 0 或负值超过 500 的 PM2.5 也要怀疑是异常点。清洗逻辑放在 analysis-service 里启动时跑一次全量清洗然后每天凌晨跑一次增量清洗。-- 将异常值和明显越界的记录标记为不可信 UPDATE pollutant_data SET is_valid 0 WHERE pm25 0 OR pm25 1000 OR collect_time IS NULL OR station_id NOT IN (station_01, station_02, station_03, station_04, station_05);更完整的清洗还有一步填补缺失时间点。站点每隔一小时采集一次但如果采集程序挂了两个小时时间序列就出现了空缺。模型训练时最怕数据断档预测出来的值会偏得离谱。填补公式建议取前后两小时的平均值不要用全表平均值因为污染物浓度和一天中的时段强相关用全局均值会把早高峰的数据强行拉低。INSERT INTO pollutant_data(station_id, pm25, pm10, so2, no2, ozone, collect_time, is_valid) SELECT station_id, (SELECT AVG(t2.pm25) FROM pollutant_data t2 WHERE t2.collect_time BETWEEN DATE_SUB(2025-01-10 08:00:00, INTERVAL 1 HOUR) AND DATE_ADD(2025-01-10 08:00:00, INTERVAL 1 HOUR) AND t2.is_valid 1), -- pm10、so2 等同理 2025-01-10 08:00:00, 1 FROM pollutant_data WHERE collect_time 2025-01-09 08:00:00 LIMIT 1;这个 SQL 的逻辑是如果 2025-01-10 08:00 这条记录不存在在你执行插入前它是空的就找到前一天相同时段的数据作为模板取前后两小时的有效均值填进去。参数INTERVAL 1 HOUR表示窗口大小是前后各 1 小时窗口越大越平滑但太大就会把早晚高峰的形状磨平毕设数据量小取 1 小时足矣。3.3 存储选型MySQL 与时序数据的取舍环境数据本质上是时序数据正经企业会选 InfluxDB、TDengine 或 OpenTSDB。但毕设要注意评分维度和维护成本。用 TDengine答辩时要解释为什么不用 MySQL需要额外准备对比数据用 MySQL 反而简单直接因为平台里的分析报表、用户管理、预测结果都是关系型数据统一放一个 MySQL 实例最省事。表结构设计上我列一个实际跑通的清单表名关键字段用途pollutant_dataid, station_id, pm25, pm10, so2, no2, ozone, collect_time, is_valid原始污染物数据aqi_levelid, station_id, aqi, level, primary_pollutant, collect_time空气质量指数与等级prediction_resultid, station_id, target_time, pm25_pred, pm10_pred, model_version, create_time模型预测结果sys_userid, username, password, role登录用户aqi_level表的一个细节AQI 是根据六项污染物浓度分指数计算出来的每项都折算成 IAQI取最大值。这个计算逻辑写成一个 SQL function 或 Java 工具类都行但值域区间必须和官方标准一致比如 PM2.5 的 24 小时均值在 0-35 对应 IAQI 0-50在 35-75 对应 50-100。答辩时评委很可能抽查这个换算公式写错了就等于暴露数据分析基本功不扎实。4. 预测模块落地把 Python 预测模型融入 Spring Cloud 微服务体系4.1 预测算法怎么选ARIMA 还是 LSTM环境污染物浓度预测最常见的两个算法ARIMA 和 LSTM。ARIMA 适合单变量、数据量小、趋势平稳的场景LSTM 适合多变量、长序列、非线性关系明显的场景。毕设数据量一般只有几百条到两三千条ARIMA 更容易收敛参数也更好解释答辩证时你能说出“ARIMA(p,d,q) 的差分阶数 d1消除了日周期性趋势”这种话比说“LSTM 很强大”更能体现理解深度。不过我更推荐做成“双模型对比”的效果先用 ARIMA 做一个基准预测再用 LSTM 做一个预测最后把两条曲线同时展示在前端配上 MAE 对比。理由很实际如果只用 ARIMA评委可能会问“为什么不用深度学习”只用 LSTM又可能被问“你数据量这么小凭什么相信它的泛化能力”。两个都有展示对比既显得工作量充足又让算法选型有依据。教一个不会出错的基线模型用前 168 小时7 天的数据预测未来 24 小时步长为 1。污染物浓度有明显的天周期性7 天窗口能覆盖工作日和周末的差异效果比拍脑袋指定的 72 或 120 要好。代码在 Python 侧训练并保存模型import pandas as pd import numpy as np from statsmodels.tsa.arima.model import ARIMA import joblib df pd.read_csv(pm25_history.csv, parse_dates[collect_time]) df df.set_index(collect_time).sort_index() # 按小时重采样空缺值前向填充 series df[pm25].resample(1H).ffill().dropna() # 固定参数p2, d1, q2针对日周期数据效果比较稳 model ARIMA(series, order(2, 1, 2)) model_fit model.fit() # 预测未来 24 小时 forecast model_fit.forecast(steps24) print(forecast) joblib.dump(model_fit, arima_pm25.pkl)这里order(2, 1, 2)不是随便拍的。先用plot_acf和plot_pacf看自相关图拖尾选 AR 项、截尾选 MA 项数据量不够分析时取 1-2 阶不会过拟合。ffill()是前向填充比dropna()强在保持时间连续但前面章节提到清洗时会补缺失值所以这里的前向填充只是双保险。4.2 模型服务化Flask 或 FastAPI 暴露接口Spring Cloud 怎么调模型训练好之后Python 侧不能只活在脚本里要变成一个可以被 Java 调用的 HTTP 服务。我用的是 FastAPI比 Flask 轻自带 Swagger 文档答辩时打开http://localhost:5001/docs可以直接给评委看接口列表体验很好。在这个环节“Python 应用融入 Spring Cloud Alibaba 微服务体系”这件事是热词场景里最关键的一步——微服务体系不必全是 JavaPython 模型服务也能以独立服务身份注册进 Nacos。from fastapi import FastAPI import joblib import numpy as np app FastAPI() model joblib.load(arima_pm25.pkl) app.post(/api/prediction/forecast) def forecast(station_id: str, hours: int 24): pred model.forecast(stepshours) result { stationId: station_id, model: ARIMA, values: [round(float(x), 2) for x in pred], modelVersion: v1.0 } return result这个接口的入参只有station_id和hours出参是预测值数组。注意values要转成 listnp.float64 不能被 FastAPI 直接序列化这是很多人会忘记的细节不转的话接口直接报 500。modelVersion字段很有用前端和 Java 侧都不用改代码模型升级后只改这个版本号就能追溯结果是由哪个模型产生的。Java 侧用 Feign 调这个接口。prediction-service 里定义一个接口类FeignClient(name python-prediction-service, url http://127.0.0.1:5001) public interface PythonPredictionClient { PostMapping(/api/prediction/forecast) PredictionResponse forecast(RequestParam(stationId) String stationId, RequestParam(hours) int hours); }两个参数要解释。name是 Feign 的客户端名url直接指向 Python 服务的地址这个写法的好处是不依赖服务发现Python 服务哪怕不注册进 Nacos 也能跑通全链路如果想做得更工程化可以在 Python 侧加nacos-sdk-python注册到同一个 NacosFeign 的url去掉改成name python-prediction-service加负载均衡但毕设里直接写 url 更省事。4.3 预测接口的参数设计与结果落库预测服务拿到 Python 返回的数组后不要直接丢给前端要先落库。落库的意义在于前端大屏反复刷新时不用每次都去调 Python 模型读历史预测结果即可答辩时你也可以展示“昨天预测的 PM2.5 和今天实际监测的 PM2.5”的对比图证明模型有验证闭环。落库代码在 prediction-service 里Scheduled(cron 0 30 1 * * ?) public void runDailyForecast() { ListString stations analysisClient.listAllStations(); for (String stationId : stations) { PredictionResponse resp pythonPredictionClient.forecast(stationId, 24); for (int i 0; i resp.getValues().size(); i) { PredictionResultEntity entity new PredictionResultEntity(); entity.setStationId(stationId); // 从当天 02:00 开始按小时递增 LocalDateTime targetTime LocalDateTime.now() .withHour(2).withMinute(0).withSecond(0).plusHours(i); entity.setTargetTime(targetTime); entity.setPm25Pred(resp.getValues().get(i)); entity.setModelVersion(resp.getModelVersion()); predictionResultMapper.insert(entity); } } }cron 0 30 1 * * ?表示每天凌晨 1 点 30 分跑一次选择这个时间点因为大部分环境监测站的数据在凌晨 1 点前完成前一天的汇总预测明天的数据时训练输入没有缺失。targetTime从当天凌晨 2 点开始递增是因为预测模型输出的第 1 个小时通常代表下一个整点如果从 0 点开始会把“刚过去的那一小时”也算进去导致画图时曲线整体左移一小时。这个小细节前端比对时最容易暴露。参数化和规范化的顺序也常出问题。模型训练时用 MinMaxScaler 归一化预测结果反归一化后才是真实浓度值。我见过不少同学把归一化范围写反预测结果全部接近 0或者出现负数。正确做法是训练时保存 scaler 对象预测时用同一个 scaler 的inverse_transform还原不能拿训练脚本里的统计值手工硬算。5. 毕设过程中最容易翻车的五个坑现象、原因、解决5.1 Nacos 注册不上服务列表永远是空的现象每个服务都能正常启动没有报错但是打开 Nacos 控制台的服务列表只有nacos自己业务服务一个都不在。排查时发现网络通、8848 端口也能访问就是注册不上。原因最常见的是版本冲突。Spring Cloud Alibaba 2021.0.5.0 对应 Nacos Client 2.2.x但如果你通过传递依赖拿到了 Nacos Client 1.4.x控制台的 2.x 服务和 1.x 客户端之间存在兼容问题注册会静默失败。还有一种情况是服务里同时引入了spring-cloud-starter-alibaba-nacos-discovery和旧版的com.alibaba.nacos:nacos-client被后者覆盖了版本。解决在依赖管理中强制锁定nacos-client版本为 2.2.1 以上或在 pom 里用dependencyManagement统一版本。启动时加 JVM 参数-Dnacos.log.path./logs能看到 Nacos 客户端日志注册失败的真正原因基本都写在里面不要只盯着控制台看。5.2 Feign 调用 Python 服务总是超时现象前端点击“生成预测”后转圈超过 30 秒最后提示网关超时。后端日志显示 Feign 调用失败Read timed out。原因Feign 默认连接超时是 1 秒读取超时也是 1 秒。Python 模型加载需要时间第一次调用尤其慢ARIMA 的forecast虽然只预测 24 个点但模型文件加载、数据对齐、Python 解释器预热都发生在第一次请求里1 秒根本不够。这不是代码 bug而是默认参数不适合跨语言调用。解决在 prediction-service 的配置里调大 Ribbon 或 Feign 的超时时间ribbon: ReadTimeout: 30000 ConnectTimeout: 5000同时建议 Python 服务在启动时就加载模型文件而不是每次请求都joblib.load。代码里把model joblib.load(arima_pm25.pkl)放在模块顶层就能让模型常驻内存。实测首次请求能从 8 秒降到 200 毫秒左右这比调超时更能解决问题。5.3 预测的时间戳和实际监测对不上画出来的曲线错位现象前端展示“预测 vs 实际”对比图时两条曲线形态很像但波峰波谷整体偏移几小时看起来像模型故意把预测往后挪了。原因这是时间序列里最容易忽略的边界问题。采集数据的时间戳用的是collect_time模型训练时按它排序但预测结果的target_time如果生成逻辑和训练数据的对齐方式不一致就会错位。比如数据是 1 点整采的但代表的是 0 点到 1 点的均值预测的“下一小时”应该从 2 点开始而不是从 1 点开始。解决统一约定时间戳语义。我在数据清洗阶段就把collect_time全部规范为“时段结束时间”并把这个约定写在项目说明文档里。预测接口返回的targetTime同样按“时段结束时间”生成前端展示时不再做任何偏移。加上一条校验逻辑预测结果表里每小时的target_time必须连续缺任何一个小时的记录直接报警不要让脏数据流到前端。5.4 8G 内存的笔记本跑不动全套服务现象启动 Nacos、Gateway、四个微服务、Python 模型服务、MySQL、Redis电脑直接卡死风扇狂转内存占用 95% 以上。原因默认 JVM 堆内存太大了。Spring Boot 应用默认最大堆是物理内存的 1/4四个服务各吃 1.5-2G加上 Nacos 的 2G还没开始跑业务就已经超了。另外 Nacos 2.x 的默认 JVM 参数偏向服务器端不调优在开发机上很难受。解决给每个服务设置合理的 JVM 参数。开发环境下统一设置java -jar analysis-service.jar -Xms256m -Xmx512m java -jar prediction-service.jar -Xms256m -Xmx512m java -jar gateway-service.jar -Xms256m -Xmx512mNacos 启动前修改bin/startup.sh里的JAVA_OPT把-Xms和-Xmx从 2g 改成 512m。MySQL 和 Redis 不要用 Docker Desktop 一锅端跑Docker Desktop 本身占用 2G 内存换成本地安装版。这套配置调完后全套服务内存占用能压到 4G 左右。5.5 预测结果全是同一个值曲线变成一条直线现象ARIMA 预测出的 24 个值几乎一样或者缓慢变化后迅速收敛到一个固定值前端曲线像一条水平直线完全看不出趋势。原因数据预处理阶段出了问题。最常见的是训练数据没有差分或者数据里有大量重复值。ARIMA 模型对平稳性敏感如果数据本身存在上升趋势或强季节性order(2,1,2)的差分阶数 d1 不够需要把差分阶数调到 2。另一个原因是训练集过短只有几十条数据模型学到的是简单均值自然输出一条直线。解决用 ADF 检验看数据是否平稳p 值大于 0.05 就继续差分。代码里加一段判断from statsmodels.tsa.stattools import adfuller result adfuller(series) print(fp-value: {result[1]}) if result[1] 0.05: series series.diff().dropna()如果 diff 一次后仍不平稳就把d改成 2 再试。这条经验也适用于 LSTM很多人把未经归一化的数据直接丢进 LSTMloss 死活不降输出基本恒定。先做数据探索再进模型别让超参数调优变成玄学。6. 让评委相信预测有效验证指标、压测与演示脚本6.1 用 MAE、RMSE 和 R² 量化模型结果答辩时最常被问的一句话是“你怎么证明你的预测有效”不能只给一张图说“看起来趋势差不多”要用回归指标说话。我建议在预测结果落库前加一个验证脚本取最近 7 天的数据用前 6 天训练、预测第 7 天和实际值对比算指标。from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score actual np.array([35.2, 38.7, 42.1, 39.5, 31.8, 28.9, 26.4]) predicted np.array([36.0, 37.9, 40.5, 41.2, 33.0, 29.5, 27.1]) mae mean_absolute_error(actual, predicted) rmse np.sqrt(mean_squared_error(actual, predicted)) r2 r2_score(actual, predicted) print(fMAE{mae:.2f} ug/m3, RMSE{rmse:.2f} ug/m3, R2{r2:.3f})三个指标的解读方式要提前准备好MAE 告诉你平均差多少微克/立方米比如 MAE 是 2.3就是平均每天的预测误差约 2.3 个单位这个精度在空气质量预测里已经可接受RMSE 比 MAE 大说明存在少数误差较大的点可以进一步分析是不是某天突然出现沙尘或强逆温R² 在 0.6 以上就可以解释为模型捕捉到了大部分变化趋势低于 0.5 就要考虑数据量不足或特征太少。指标参考标准判定MAE5 ug/m³ 以下趋势可用RMSE比 MAE 高 1.5 倍以内误差分布正常R²0.6-0.9模型有效视数据量而定6.2 一键启动脚本与演示路径设计答辩现场最怕的是“起服务”变成“排障现场”。我习惯写一个start-all.sh按顺序启动基础设施和业务服务每个服务启动后打印日志文件路径方便快速定位问题。#!/bin/bash # 启动顺序MySQL / Redis - Nacos - 网关 - 业务服务 - Python 服务 ./start-mysql-redis.sh sh /opt/nacos/bin/startup.sh -m standalone nohup java -jar gateway-service.jar logs/gateway.log 21 nohup java -jar analysis-service.jar logs/analysis.log 21 nohup java -jar prediction-service.jar logs/prediction.log 21 uvicorn python_service:app --host 0.0.0.0 --port 5001 logs/python.log 21 echo all services started. check logs under ./logs演示顺序建议这样设计先打开网关接口用 Swagger 或 Postman 调一次历史趋势接口展示数据源再打开预测接口跑一次 24 小时预测让评委看到真实调用过程而不是只点前端按钮——按钮背后的网络请求才是你工作量最直观的证明最后打开对比图页面把“预测 vs 实际”的曲线和 MAE 数值放在同一屏。注意 Python 服务要最先启动因为它是冷启动最慢的一环现场如果赶时间可以把 Python 服务放在 Java 服务之前两秒启动预留模型热加载时间。最后一件事是定时任务的开关。答辩演示时不要真的让数据采集定时任务开着不然后台每分钟写数据库会把前端图表搞乱。演示前把Scheduled注解临时注释掉或者通过配置中心的开关控制让数据只读、不新增页面效果更稳定。我做这类项目吃了不少亏最大的教训就是提前把“演示当天一定会出问题”当成默认假设所有外部依赖都留本地兜底方案。数据、模型、服务全部在本机跑通后再去美化前端。希望这篇笔记能帮你把 Spring Cloud 环境污染物数据分析与预测平台从架构到细节都落地少走我走过的弯路祝答辩顺利。本文还有配套的精品资源点击获取
网站建设高端定制企业官网