实战案例|某3C工厂智能生产调度AI系统架构重构:架构师复盘技术债务清理
先给大家讲个真实的车间故事某3C工厂生产手机摄像头模组,某天早上8点接到客户紧急订单——要求当天18点前交付5000个模组(正常交期是3天)。车间主任立刻找IT人员调排程,结果传统调度系统跑了2小时才出方案,还提示“设备A与订单B产能冲突”。IT人员只好手动改参数,又花了1小时,等方案确定时,已经11点了。更糟的是,下午2点设备C突然故障,系统无法实时调整,导致10个订单延迟,客户扬言要扣款。这不
实战案例|某3C工厂智能生产调度AI系统架构重构:架构师复盘技术债务清理
关键词:3C工厂、智能生产调度、AI系统架构、技术债务清理、微服务、领域驱动设计(DDD)、事件驱动
摘要:本文以某3C工厂(生产手机零部件)智能生产调度系统的重构实战为背景,复盘架构师如何从技术债务诊断→领域建模破局→微服务拆分落地→AI模块解耦的全流程。通过“像整理杂乱衣柜”的类比,拆解传统单体架构的“缠结痛点”,用DDD划清业务边界,用微服务实现“专业的事交给专业模块”,最终将调度响应时间从2小时压缩到10分钟,AI模型迭代周期从1周缩短至1天。文章结合真实代码示例、架构图和业务场景,讲透“技术债务不是洪水猛兽,而是未偿还的‘业务借款’”的核心逻辑。
一、背景介绍:3C工厂的“调度焦虑症”
1.1 为什么3C工厂需要智能调度?
先给大家讲个真实的车间故事:
某3C工厂生产手机摄像头模组,某天早上8点接到客户紧急订单——要求当天18点前交付5000个模组(正常交期是3天)。车间主任立刻找IT人员调排程,结果传统调度系统跑了2小时才出方案,还提示“设备A与订单B产能冲突”。IT人员只好手动改参数,又花了1小时,等方案确定时,已经11点了。更糟的是,下午2点设备C突然故障,系统无法实时调整,导致10个订单延迟,客户扬言要扣款。
这不是个例。3C工厂的生产特点是**“多品种、小批量、高频变”**:
- 产品型号每月更新10+次(比如手机摄像头从1200万像素升级到2400万);
- 客户订单经常“插单”(临时加单或改交期);
- 设备类型多(贴片机、焊接机、检测机等20+种),状态实时变化(故障、保养、切换型号)。
传统调度系统(基于Excel宏或单体ERP)的问题像“老汽车跑高速”:
- 反应慢:批处理排程,跑一次要几小时;
- 刚性强:改一个参数要停整个系统;
- AI弱:预测模型硬编码在业务逻辑里,换算法要重写代码;
- 数据散:订单、设备、生产数据存在不同数据库,取数要跨3个系统。
这些问题堆积成技术债务——就像家里的旧衣柜:一开始塞几件旧衣服没关系,后来越堆越多,想找件新衣服要翻半小时,最后干脆放弃整理,买新衣柜(重构)。
1.2 重构的目标与范围
- 核心目标:
- 清理技术债务:解决“改不动、跑不快、联不上”的问题;
- 提升业务价值:支持“分钟级排程”“实时调整”“AI快速迭代”;
- 面向未来:架构能适配3年内的业务扩张(比如新增5条生产线、接入AGV机器人)。
- 范围:生产调度核心模块(订单排程、设备分配、实时调度)+ AI决策模块(设备故障预测、交期准确率优化)。
- 预期读者:架构师、制造行业IT工程师、AI算法工程师(想了解“AI如何落地生产系统”的同学)。
1.3 术语表:先搞懂“行话”
为了避免“鸡同鸭讲”,先定义几个核心术语:
术语 | 通俗解释 |
---|---|
3C工厂 | 生产电脑(Computer)、通讯(Communication)、消费电子(Consumer Electronics)的工厂,比如手机零部件厂 |
生产调度 | 给“订单”分配“设备”和“时间”,像餐厅给客人安排“桌子”和“上菜顺序” |
技术债务 | 为了快速上线而做的“临时选择”(比如硬编码、不写注释),后来需要花时间修复的“成本” |
微服务 | 把大系统拆成小服务,每个服务只做一件事(比如“订单服务”只管订单创建,“设备服务”只管设备状态) |
DDD(领域驱动设计) | 和业务人员一起画“业务地图”,明确“哪些事情属于同一类”(比如“订单交期”和“订单数量”是一伙的,“设备状态”和“设备产能”是另一伙的) |
二、技术债务诊断:像医生一样“望闻问切”
要清理技术债务,第一步不是“动手改”,而是搞清楚“欠了什么债”。就像医生治病,得先做CT(扫描代码)、问病史(和老员工聊天),再开药方。
2.1 技术债务的“四象限分类”
我们用Martin Fowler的技术债务四象限模型(有意/无意 × 短期/长期),给旧系统的债务分了类:
类型 | 例子 | 危害 |
---|---|---|
无意-长期 | 为了赶项目,把“订单排程”和“设备状态查询”写在一个函数里(1000行代码) | 改排程算法要停整个系统,维护成本每年涨30% |
有意-短期 | 硬编码AI模型的参数(比如“设备故障阈值=80℃”),先上线再优化 | 后来要调整阈值,得改代码、测一周 |
无意-短期 | 数据库表没加索引,查询慢但暂时能忍 | 数据量涨10倍后,查询时间从1秒变10秒 |
有意-长期 | 不用消息队列,直接调用接口传数据 | 设备故障时,请求堵死,系统崩溃 |
2.2 旧系统的“三大痛点”(附代码反例)
我们用SonarQube(代码质量扫描工具)和Architecture Blueprint(架构分析工具),揪出了旧系统的核心问题:
痛点1:单体架构“缠成一团”
旧系统是单体Java应用,所有功能(订单、设备、调度、AI)都在一个WAR包里。比如“生成排程”的函数:
// 旧代码:排程函数耦合了订单、设备、AI逻辑
public Schedule generateSchedule(Order order) {
// 1. 查询设备状态(设备模块)
List<Device> devices = deviceDao.findByType(order.getProductType());
// 2. 计算设备产能(AI模块:硬编码的产能公式)
for (Device d : devices) {
d.setCapacity(d.getSpeed() * 0.8); // 固定系数0.8,没有理由
}
// 3. 分配订单到设备(调度模块)
Schedule schedule = new Schedule();
for (OrderItem item : order.getItems()) {
Device bestDevice = findBestDevice(devices, item);
schedule.add(item, bestDevice);
}
return schedule;
}
问题:改“产能计算”的系数(比如从0.8变0.9),要改这个函数;改“找最优设备”的算法,也要改这个函数。牵一发动全身,测试要覆盖所有场景,耗时一周。
痛点2:AI模型“焊死在业务里”
旧系统的AI模型(比如设备故障预测)是硬编码在业务逻辑中的,没有独立的模型管理。比如:
# 旧代码:故障预测模型硬编码在设备状态查询里
def get_device_status(device_id):
# 1. 查设备数据
data = query_device_data(device_id)
# 2. 硬编码的预测逻辑(逻辑回归模型,参数固定)
probability = 1 / (1 + math.exp(-(0.5*data['temperature'] - 0.3*data['runtime'] - 20)))
# 3. 返回状态
return "故障风险高" if probability > 0.7 else "正常"
问题:想换个更准确的模型(比如随机森林),得重写整个get_device_status
函数,还要测试所有设备类型,迭代周期长达1周。
痛点3:数据“散成碎片”
旧系统的数据分布在3个数据库:
- 订单数据:MySQL(来自ERP);
- 设备数据:SQL Server(来自MES系统);
- 生产数据:Oracle(来自SCADA系统)。
调度时要跨3个库查数据,比如:
-- 旧代码:查设备状态要联3个库
SELECT d.id, d.type, p.status
FROM erp_db.order o
JOIN mes_db.device d ON o.product_type = d.type
JOIN scada_db.production p ON d.id = p.device_id
WHERE o.id = 'O123';
问题:联表查询慢(10秒+),而且某个库宕机,整个查询失败。
三、重构的核心思路:用“衣柜整理法”拆系统
3.1 故事类比:从“杂乱衣柜”到“分类衣橱”
假设你有个杂乱的衣柜:
- 衣服、裤子、袜子混在一起;
- 冬天的羽绒服和夏天的T恤堆在一层;
- 想找件衬衫要翻半小时。
你会怎么整理?三步法:
- 分类:把衣服分成“上衣、裤子、配饰”(对应DDD的“边界上下文”);
- 分区:把上衣放第一层,裤子放第二层(对应微服务的“模块拆分”);
- 标签:每件衣服挂标签(比如“纯棉”“保暖”,对应AI的“特征存储”)。
我们的系统重构,完全复制了这个逻辑!
3.2 重构的“三大方法论”
1. 用DDD划清“业务边界”(先搞懂“什么属于什么”)
DDD的核心是**“和业务人员一起画地图”**。我们和车间主任、调度员开了3次workshop,问了3个关键问题:
- “哪些事情是一起的?”(比如“订单交期”和“订单数量”是“订单”的一部分);
- “哪些事情要分开?”(比如“设备状态”和“订单排程”是两回事);
- “哪些事情需要实时?”(比如“设备故障”要立刻通知调度)。
最终画出领域模型图(简化版):
关键结论:
- 订单、设备、排程是核心聚合根(不能拆分的最小业务单元);
- AI决策是支撑服务(给排程提建议,不直接操作业务数据)。
2. 用微服务拆成“专业小组”(每个服务只做一件事)
根据DDD的边界,我们把旧单体系统拆成5个微服务:
微服务名称 | 职责 | 技术栈 |
---|---|---|
订单服务(Order Service) | 管理订单的创建、修改、查询 | Spring Boot + MySQL |
设备服务(Device Service) | 管理设备的状态、产能、位置 | Spring Boot + SQL Server |
调度服务(Schedule Service) | 生成排程、调整排程(核心业务) | Spring Boot + Redis(缓存排程结果) |
AI服务(AI Service) | 设备故障预测、交期准确率计算、最优设备推荐 | FastAPI + Python + MLflow |
事件总线(Event Bus) | 传递实时事件(比如设备故障、订单修改) | Kafka + Flink |
拆分原则:
- 小:每个服务代码量不超过1万行;
- 独:服务间通过API或事件通信,不共享数据库;
- 稳:先拆非核心服务(比如订单服务),再拆核心服务(调度服务)——用绞杀者模式(Strangler Pattern),慢慢替换旧系统。
3. 用“分层AI架构”解耦模型与业务
旧系统的AI模型是“焊死的”,重构后我们把AI模块分成4层(像“蛋糕分层”):
layerDiagram
layer 数据层 : 采集生产数据(SCADA/MES/ERP)
layer 特征层 : 处理成模型可用的特征(比如“设备连续运行时间”)
layer 模型层 : 训练/部署AI模型(故障预测、交期预测)
layer 决策层 : 给业务系统提建议(比如“推荐设备B执行订单A”)
数据层 --> 特征层 : 输入原始数据
特征层 --> 模型层 : 输入结构化特征
模型层 --> 决策层 : 输出预测结果
决策层 --> 调度服务 : 输出调度建议
关键改进:
- 特征层用Feast(特征存储):把“设备连续运行时间”“订单紧急程度”等特征存起来,模型直接调用,不用重复计算;
- 模型层用MLflow(模型管理):跟踪模型的训练参数、效果,支持“一键部署”“版本回滚”;
- 决策层用REST API:业务系统(比如调度服务)通过API调用AI结果,不用关心模型细节。
四、实战步骤:从“诊断”到“上线”的120天
4.1 步骤1:技术债务“ inventory ”(列清欠账单)
我们用SonarQube扫描旧代码,生成“债务清单”:
- 重复代码:23处(比如“设备状态查询”复制了5次);
- 复杂函数:11个(函数行数>500行);
- 未使用的代码:15%(比如旧的排程算法,没用但没删);
- 数据库慢查询:8个(联表查询时间>10秒)。
然后给每个债务打“优先级”标签:
- P1(紧急):调度函数的1000行代码(改不动);
- P2(重要):AI模型硬编码(迭代慢);
- P3(次要):未使用的代码(占空间)。
4.2 步骤2:用DDD做“业务切割”(画清楚边界)
我们和业务人员一起画了边界上下文图(简化版):
关键结论:
- 订单上下文和设备上下文是“上游”,给调度上下文提供数据;
- AI上下文是“辅助”,给调度上下文提建议;
- 调度上下文是“核心”,所有服务都围绕它转。
4.3 步骤3:微服务拆分(从“大泥球”到“小积木”)
我们用绞杀者模式逐步替换旧系统:
- 第一步:拆“订单服务”——把旧系统中的订单功能复制到新服务,用API网关(Spring Cloud Gateway)把流量导到新服务;
- 第二步:拆“设备服务”——同理,复制设备功能到新服务;
- 第三步:拆“调度服务”——这是核心,我们先写新的调度逻辑(用DDD的聚合根设计),再用“蓝绿部署”(Blue-Green Deployment)逐步切换流量;
- 第四步:拆“AI服务”——把旧系统中的AI逻辑移到新服务,用MLflow管理模型。
代码示例:新的调度服务(简化版)
// 新代码:调度服务的排程函数(只做调度,不耦合其他逻辑)
@Service
public class ScheduleService {
// 调用订单服务(Feign客户端)
@Autowired
private OrderFeignClient orderFeignClient;
// 调用设备服务(Feign客户端)
@Autowired
private DeviceFeignClient deviceFeignClient;
// 调用AI服务(RestTemplate)
@Autowired
private RestTemplate aiRestTemplate;
public Schedule generateSchedule(String orderId) {
// 1. 从订单服务查订单
Order order = orderFeignClient.getOrderById(orderId);
// 2. 从设备服务查可用设备
List<Device> devices = deviceFeignClient.getAvailableDevices(order.getProductType());
// 3. 从AI服务查最优设备推荐
List<RecommendedDevice> recommendations = aiRestTemplate.getForObject(
"http://ai-service/recommend?orderId={orderId}",
List.class,
orderId
);
// 4. 生成排程(核心逻辑,不耦合其他服务)
Schedule schedule = new Schedule();
for (OrderItem item : order.getItems()) {
Device bestDevice = findBestDeviceFromRecommendations(recommendations, item);
schedule.add(item, bestDevice);
}
return schedule;
}
}
改进点:
- 调度服务只做“生成排程”,不查订单、不查设备、不跑AI模型;
- 服务间用Feign(声明式HTTP客户端)或RestTemplate调用,耦合度极低;
- 改订单逻辑不用动调度服务,改AI模型也不用动调度服务。
4.4 步骤4:AI模块重构(从“焊死”到“可插拔”)
我们用MLflow和Feast重构了AI模块,实现“模型可插拔”:
1. 特征层:用Feast存储特征
比如“设备连续运行时间”这个特征,我们用Feast定义:
# feast_feature_def.py:定义特征
from feast import FeatureView, Field
from feast.infra.offline_stores.file_source import FileSource
from datetime import timedelta
# 原始数据来源(SCADA系统的CSV文件)
device_data_source = FileSource(
path="s3://my-feast-bucket/device_data.csv",
event_timestamp_column="event_time"
)
# 定义特征视图(设备连续运行时间)
device_continuous_runtime_fv = FeatureView(
name="device_continuous_runtime",
entities=["device_id"],
ttl=timedelta(days=7),
fields=[
Field(name="continuous_runtime_hours", dtype=float)
],
online=True,
source=device_data_source
)
好处:模型训练时直接调用device_continuous_runtime
特征,不用自己写SQL查数据。
2. 模型层:用MLflow管理模型
比如“设备故障预测模型”,我们用MLflow训练并注册:
# train_fault_model.py:用MLflow训练模型
import mlflow
import mlflow.sklearn
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from feast import FeatureStore
# 1. 从Feast获取特征
store = FeatureStore(repo_path="feast_repo")
features = ["device_continuous_runtime:continuous_runtime_hours"]
entity_df = pd.read_csv("entity_ids.csv") # 设备ID列表
training_data = store.get_historical_features(
entity_df=entity_df,
features=features
).to_df()
# 2. 训练模型
X = training_data[["continuous_runtime_hours"]]
y = training_data["fault_label"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
with mlflow.start_run():
model = RandomForestClassifier(n_estimators=100)
model.fit(X_train, y_train)
accuracy = model.score(X_test, y_test)
mlflow.log_param("n_estimators", 100)
mlflow.log_metric("accuracy", accuracy)
mlflow.sklearn.log_model(model, "fault_model")
好处:训练完的模型自动注册到MLflow仓库,部署时直接调用最新版本:
# ai_service.py:用MLflow加载模型
import mlflow.sklearn
from fastapi import FastAPI
app = FastAPI()
# 加载最新版本的故障预测模型
model = mlflow.sklearn.load_model("models:/fault_model/latest")
@app.get("/predict_fault")
def predict_fault(device_id: str):
# 从Feast获取设备的实时特征
store = FeatureStore(repo_path="feast_repo")
feature_vector = store.get_online_features(
features=["device_continuous_runtime:continuous_runtime_hours"],
entity_rows=[{"device_id": device_id}]
).to_dict()
# 预测故障概率
probability = model.predict_proba([[feature_vector["continuous_runtime_hours"][0]]])[0][1]
return {"device_id": device_id, "fault_probability": probability}
4.5 步骤5:实时调度改造(从“批处理”到“事件驱动”)
旧系统的调度是“批处理”(每天跑一次),无法应对实时事件(比如设备故障)。我们用Kafka和Flink实现“事件驱动的实时调度”:
1. 事件定义
我们定义了3种核心事件:
OrderCreatedEvent
(订单创建):触发新排程;DeviceFaultEvent
(设备故障):触发排程调整;OrderChangedEvent
(订单修改):触发排程重新计算。
2. 事件处理流程
3. 代码示例:Flink处理设备故障事件
// DeviceFaultEventProcessor.java:用Flink处理设备故障事件
public class DeviceFaultEventProcessor {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
// 1. 从Kafka读取DeviceFaultEvent
DataStream<DeviceFaultEvent> faultEvents = env.addSource(
KafkaSource.<DeviceFaultEvent>builder()
.setBootstrapServers("kafka:9092")
.setTopics("device-fault-topic")
.setGroupId("fault-event-group")
.setDeserializer(new KafkaRecordDeserializationSchema<DeviceFaultEvent>() {
@Override
public DeviceFaultEvent deserialize(ConsumerRecord<byte[], byte[]> record) throws Exception {
return new ObjectMapper().readValue(record.value(), DeviceFaultEvent.class);
}
})
.build()
);
// 2. 处理事件:调用调度服务调整排程
faultEvents.map(event -> {
// 调用调度服务的“调整排程”API
RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject(
"http://schedule-service/adjust",
new AdjustScheduleRequest(event.getDeviceId()),
Void.class
);
return event;
});
env.execute("Device Fault Event Processor");
}
}
效果:设备故障发生后,Flink在1秒内消费事件,调度服务在10秒内生成新排程,生产执行系统在1分钟内调整生产计划——比旧系统快了30倍!
4.6 步骤6:测试与迁移(从“怕出问题”到“放心上线”)
重构最担心的是“上线后出问题”,我们用了3种测试方法:
- 单元测试:每个微服务的函数都写单元测试(覆盖度>80%);
- 集成测试:用Postman测试服务间的API调用(比如订单服务调用设备服务是否正常);
- 混沌工程:用Chaos Mesh模拟“设备服务宕机”“Kafka消息丢失”等异常,测试系统的容错性(比如设备服务宕机时,调度服务会用缓存的设备状态继续工作)。
迁移时用蓝绿部署:
- 蓝环境:旧系统(运行中);
- 绿环境:新系统(部署完成);
- 用API网关把10%的流量导到绿环境,观察24小时;
- 没问题的话,逐步增加流量到100%,最后下线蓝环境。
五、效果:从“焦头烂额”到“游刃有余”
5.1 业务指标提升
指标 | 旧系统 | 新系统 | 提升率 |
---|---|---|---|
排程时间 | 2小时 | 10分钟 | 91.7% |
实时响应时间 | 30分钟 | 1分钟 | 96.7% |
AI模型迭代周期 | 1周 | 1天 | 85.7% |
维护成本 | 每月10人天 | 每月4人天 | 60% |
生产效率 | 每小时生产100件 | 每小时生产125件 | 25% |
5.2 真实业务场景案例
案例1:紧急订单处理
某天早上9点,客户突然加单5000个摄像头模组,交期当天18点。新系统的处理流程:
- 订单服务创建订单(1秒);
- Kafka发送
OrderCreatedEvent
(1秒); - 调度服务调用AI服务推荐最优设备(2秒);
- 调度服务生成排程(5分钟);
- 生产执行系统开始生产(10分钟内)。
最终17:30完成生产,提前30分钟交付,客户追加了10000件订单。
案例2:设备故障应对
某天下午2点,设备C突然故障(温度超过阈值)。新系统的处理流程:
- 设备服务发送
DeviceFaultEvent
(1秒); - Flink消费事件,调用调度服务调整排程(1秒);
- 调度服务从AI服务获取“替代设备推荐”(2秒);
- 调度服务生成新排程(3分钟);
- 生产执行系统切换到设备D生产(5分钟内)。
最终没有订单延迟,客户投诉率从每月5次降到0次。
六、挑战与应对:重构路上的“坑”
6.1 挑战1:分布式事务问题
微服务拆分后,“创建订单→生成排程→更新设备状态”变成了跨服务的事务,如何保证一致性?
应对:用Saga模式(事务补偿)。比如:
- 步骤1:订单服务创建订单(成功);
- 步骤2:调度服务生成排程(失败);
- 步骤3:订单服务回滚(删除已创建的订单)。
我们用Seata(分布式事务框架)实现Saga模式,保证跨服务的事务一致性。
6.2 挑战2:AI模型的“实时特征”问题
AI模型需要实时获取设备的“连续运行时间”,但Feast的在线特征存储延迟是500ms,不够快?
应对:用Redis做“实时特征缓存”。比如:
- 设备服务更新设备状态时,同时更新Redis中的“连续运行时间”;
- AI服务先查Redis,如果没有再查Feast,延迟降到10ms以内。
6.3 挑战3:团队的“学习曲线”问题
旧系统的开发团队习惯了单体架构,突然要学微服务、DDD、MLflow,压力很大?
应对:
- 内部培训:每周做1次技术分享(比如“DDD入门”“微服务实践”);
- 导师制:请外部专家做导师,解决团队的问题;
- 小步试错:先做小功能的微服务(比如订单服务),让团队慢慢适应。
七、未来趋势:从“智能调度”到“数字孪生+AI”
重构不是终点,而是新的起点。我们接下来的计划是:
- 数字孪生:搭建生产车间的数字孪生系统,实时模拟生产场景(比如“如果设备A故障,会影响多少订单?”),提前优化调度方案;
- LLM辅助决策:用大语言模型(比如GPT-4)解释调度方案(比如“为什么选择设备B?因为它的产能比设备A高20%,而且离原料库更近”),让车间主任更容易理解;
- AutoML自动优化:用AutoML工具(比如H2O)自动调优AI模型的参数,减少人工干预(比如“故障预测模型的准确率从85%提升到90%”)。
八、总结:技术债务的“本质”是什么?
通过这次重构,我对技术债务有了新的理解:
- 技术债务不是“坏代码”,而是**“为了快速满足业务需求而欠下的‘技术借款’”**——就像你为了买房子贷款,虽然要付利息,但能提前住上房子;
- 清理技术债务不是“否定过去”,而是**“把过去的‘临时选择’变成‘长期资产’”**——就像你把旧衣柜整理成分类衣橱,虽然花时间,但以后找衣服更方便;
- 架构重构不是“炫技”,而是**“用技术解决业务问题”**——如果重构后生产效率没提升、客户投诉没减少,那重构就是失败的。
九、思考题:动动小脑筋
- 你所在的项目有哪些“技术债务”?比如“硬编码的参数”“耦合的函数”,请列3个,并思考如何清理?
- 如果你的团队要做微服务拆分,你会先拆哪个模块?为什么?
- 如果你是3C工厂的架构师,如何用AI提升“订单交期准确率”?请给出1个具体的方案。
十、附录:常见问题与解答
Q1:微服务拆分的粒度怎么把握?
A:记住“两个原则”:
- 业务单一性:每个服务只做一件事(比如“订单服务”只管订单);
- 团队大小:每个服务由1-2个开发人员维护(太大的服务会导致沟通成本高)。
Q2:AI模型与业务系统的耦合怎么解决?
A:用“API化”和“特征存储”:
- AI模型通过API提供服务(比如“/predict_fault”),业务系统调用API,不关心模型细节;
- 特征用Feast等工具存储,模型和业务系统都从特征存储取数据,避免重复计算。
Q3:实时调度的延迟怎么优化?
A:用“事件驱动”和“缓存”:
- 用Kafka和Flink处理实时事件,减少批处理的延迟;
- 用Redis缓存常用数据(比如设备状态、排程结果),减少数据库查询时间。
十一、扩展阅读 & 参考资料
- 《领域驱动设计:软件核心复杂性应对之道》——Eric Evans(DDD的经典书籍);
- 《微服务设计》——Sam Newman(微服务的实践指南);
- 《Feast官方文档》——https://docs.feast.dev/(特征存储的权威指南);
- 《MLflow官方文档》——https://mlflow.org/docs/latest/index.html(模型管理的工具);
- 《混沌工程:系统韧性的实践》——Casey Rosenthal(混沌工程的入门书籍)。
架构师的话:
重构不是“推翻重来”,而是“站在过去的肩膀上,面向未来”。技术债务不是“敌人”,而是“提醒我们——业务在发展,技术也要跟着成长”。希望这篇复盘能给正在做架构重构的你一点启发,让我们一起把“旧系统”变成“能应对未来的系统”!
—— 某3C工厂架构师 老王
2023年12月于深圳
更多推荐
所有评论(0)