当前位置:首页 > 智能制造 CIM/MES > 正文内容

MES系统架构设计实战:模块化设计从混乱到清晰的演进

MES系统架构设计实战:模块化设计从混乱到清晰的演进

实战指数:★★★★☆ | 收藏指数:★★★★★

一、问题背景:模块耦合严重的痛苦

2018年我接手了一个自研MES项目,前任团队写了大概15万行C#代码,但几乎所有模块都直接调用数据库,一个简单的改工单状态操作,牵扯到5个不同的类,改一个Bug影响三个模块简直是家常便饭。

那个系统上线后,光是一个"修改工艺路线"的需求,开发+测试+部署整整用了3周,而且上线后还引入了2个新Bug。这种耦合到骨髓的架构,逼得我们不得不启动重构。

二、技术原理:分层架构与领域驱动设计

成熟MES通常采用三层/四层架构:表现层(Web/APP/大屏)→ 业务服务层(领域模型+应用服务)→ 数据访问层(Repository模式)→ 基础设施层(消息队列/缓存/文件)。每层只对上下层负责,领域模型保持技术无关性。

DDD(Domain-Driven Design)核心概念:聚合根(Aggregate Root)是领域对象的统一入口,比如工单(WorkOrder)就是一个聚合根,所有对工单的操作都通过WorkOrderService进行,保证聚合内的一致性约束。

三、实战:从三层到微服务的演进过程

第一步:纵向拆分。按业务领域(工单、库存、SPC、设备)拆分为独立服务,每个服务独立数据库(Database per Service)。工单服务只关心工单相关逻辑,不再直接读写库存表。

第二步:依赖倒置。数据访问层定义为接口(IWorkOrderRepository),基础设施层实现具体逻辑,上层业务代码只依赖接口,不依赖实现。这一步花了2个月,但效果立竿见影——换数据库从改2周变成改2天。

第三步:事件驱动。用RabbitMQ做服务间解耦,工单状态变更发布事件,库存服务订阅事件后自动更新,彻底消灭跨服务的同步调用。

图1:MES架构从网状耦合(左)到清晰分层(右)的演进

图2:MES架构重构前后关键指标对比

四、完整代码:服务注册与接口调用示例

以下代码展示服务注册中心和依赖注入的配置,以及工单服务的标准调用流程。使用反射自动扫描并注册服务实现类,减少手工配置。

MES架构示例:服务注册中心

from abc import ABC, abstractmethod from typing import Dict, Type, Any import inspect # 1. 定义仓储接口(依赖倒置) class IWorkOrderRepository(ABC): @abstractmethod def get_by_id(self, wo_id: str) -> Dict[str, Any]: pass @abstractmethod def update_status(self, wo_id: str, status: str) -> bool: pass @abstractmethod def list_by_state(self, state: str) -> list: pass class ISpcRepository(ABC): @abstractmethod def save_control_chart(self, data: Dict) -> bool: pass # 2. 服务容器(简单DI容器) class ServiceContainer: _services: Dict[Type, Type] = {} _instances: Dict[Type, Any] = {} @classmethod def register(cls, interface: Type, impl: Type): cls._services[interface] = impl @classmethod def resolve(cls, interface: Type) -> Any: if interface not in cls._instances: impl = cls._services.get(interface) if not impl: raise ValueError(f"Service {interface} not registered") cls._instances[interface] = impl() return cls._instances[interface] @classmethod def auto_register(cls, base_package): # 反射扫描:自动将接口的实现类注册到容器 for name, obj in inspect.getmembers(__import__(base_package)): if inspect.isclass(obj) and hasattr(obj, '__bases__'): for base in obj.__bases__: if base != ABC and issubclass(base, ABC): cls.register(base, obj) # 3. 应用服务(用例编排层) class WorkOrderService: def __init__(self): self.repo = ServiceContainer.resolve(IWorkOrderRepository) def change_route(self, wo_id: str, new_route: str) -> Dict: wo = self.repo.get_by_id(wo_id) if not wo: raise ValueError(f"WO {wo_id} not found") if wo['status'] not in ['released', 'pending']: raise ValueError(f"Cannot change route at status {wo['status']}") success = self.repo.update_status(wo_id, 'route_changed') return {'success': success, 'wo_id': wo_id, 'new_route': new_route}

为什么这样写:IWorkOrderRepository接口定义数据访问契约,使业务层与具体数据库解耦;ServiceContainer通过简单DI容器实现依赖注入,支持接口替换(如测试时注入MockRepo);auto_register用反射自动扫描,符合开闭原则,新增服务无需修改注册代码。

五、效果对比

六、实施建议

第一,不要一开始就想做微服务。先在单体应用内做好模块化拆分(Namespace/Assembly分离),验证领域边界后再考虑服务化。第二,API版本管理要提前规划。v1/api/workorders和v2/api/workorders的路由分离,避免升级时影响旧客户端。第三,引入Swagger/OpenAPI做接口文档自动化,防止接口文档过时引发的扯皮。

七、进阶方向

Kubernetes+Docker容器化部署,支持各服务独立扩缩容;Istio服务网格实现熔断、限流、链路追踪;GraphQL统一API网关,解决REST API过度获取/不足获取问题;低代码平台集成,让工艺工程师通过配置而非代码来调整业务流程。

📝 互动话题

你们FAB的设备综合效率OEE目前大概在什么水平?最大的损失来源是哪一块?

在实施OEE改善项目时,有什么坑是特别容易踩的?欢迎评论区分享!

觉得这篇文章有收获?欢迎收藏、点赞支持! 您的支持是我持续输出的最大动力! 本文首发于:blog.csdn.net/yeflashzhihui

标签: MES

相关文章

SPC统计过程控制:FAB质量管理的定海神针

SPC统计过程控制:FAB质量管理的定海神针

SPC统计过程控制:FAB质量管理的定海神针 Statistical Process Control — 用数据说话,让异常无处遁形 一、问题背景:FAB里每天产生上百万个数据点,靠什么来管理质量?...

刻蚀工艺深度解析:干法刻蚀vs湿法刻蚀怎么选

刻蚀工艺深度解析:干法刻蚀vs湿法刻蚀怎么选

刻蚀工艺深度解析:干法刻蚀vs湿法刻蚀怎么选 大家好,我是老张。前面讲完了光刻,今天聊聊刻蚀(Etching)。如果说光刻是「画图」,那刻蚀就是「刻字」——把光刻转移到光刻胶上的图形,精确地转移到下面...

半导体产业全景:从沙子到芯片的完整产业链

半导体产业全景:从沙子到芯片的完整产业链

半导体产业全景:从沙子到芯片的完整产业链 大家好,我是老张,在半导体行业摸爬滚打了十五年。从Fab厂的一线工艺工程师,到现在的产业分析师,我有幸见证了这个行业最波澜壮阔的十年。今天,我想用最接地气的方...

晶圆制造全流程:硅片是怎么从沙子变出来的

晶圆制造全流程:硅片是怎么从沙子变出来的

晶圆制造全流程:硅片是怎么从沙子变出来的 大家好,我是老张。上篇讲了半导体产业全景,很多朋友私信说「想深入了解晶圆制造」。今天我就把这部分展开,从一捧沙子到一片光洁如镜的硅晶圆,每一步的参数、原理、设...

MES制造执行系统:半导体FAB的信息中枢到底管什么

MES制造执行系统:半导体FAB的信息中枢到底管什么

MES制造执行系统:半导体FAB的信息中枢到底管什么 Manufacturing Execution System — 当FAB遇上数字化转型,信息流如何驱动价值流? 一、问题背景:FAB一天产生几个...

半导体测试全流程:从晶圆测试(CP)到成品测试(FT)一网打尽

半导体测试全流程:从晶圆测试(CP)到成品测试(FT)一网打尽

半导体测试全流程:从晶圆测试(CP)到成品测试(FT)一网打尽 Chip Probing → Wafer Sort → Package Test → Burn-in — 一颗芯片要经历多少道"...