我的软考历程
摘要
2023年9月,我所在的公司通过了研发纱线MES系统的立项,该系统为国内纱线工厂提供SAAS服务,旨在提高纱线工厂的数字化和智能化水平。我在该项目中担任系统架构设计师一职,负责该项目的架构设计工作。本文结合我在该项目中的实践,详细论述了分布式事务技术及其应用。在该项目中,我们采用了微服务架构,把系统根据领域分析划分成了一个个的微服务,每一个微服务都有自己独立的数据库,这样就不可避免会面临分布式事务的问题,为了解决该问题,我们采用了基于seata的2pc和tcc以及基于消息队列的和最终一致性的机制来保障分布式事务。最终在2024年7月,该项目正式上线并对外提供服务,目前已经有563家工厂接入了该系统,系统运行良好,得到了客户的一致赞扬。
项目背景
随着中国制造不断地产业升级以及工厂数字化和智能化的持续发展,我所在的某地纺织科技公司基于自研的物联网平台相继开发了染整一体化和织布一体化平台,这些平台上线后,得到了纱线工厂的追捧,也为公司带来了丰厚的经济回报。基于此,我司于2023年2月开始研发纱线MES系统,该系统预算730万,建设工期发10个月,该项目涵盖了纱线工厂从清花、梳棉、并条、精梳、粗纱、细纱到络筒的全流程工序,将为纱线工厂提供全面的生产管理解决方案。该项目采用物联网层次架构模型,整体分为感知层、网络层和应用层。其中网络层为公司已有的物联网平台,这次的重点建设内容为感知层和应用层,感知层使用Golang语言开发,作为联网网关部署在工厂侧,负责工厂数据的采集和云端指令的下发。应用层为纱线MES系统主体,采用Java语言开发,使用Spring Cloud微服务架构,数据库使用Mysql,缓存使用Redis,前端框架使用vue.js,日志、监控和链路追踪采用skywalking、prometheus、grafana和ELK,最终通过devops的方式部署在kubernetes集群中。系统上线后,将提供以下:基础管理、数据接入、工单排产、数字孪生、工资计算、智控中心和数据分析等等功能,通过以下功能,可以全面提升纱线工厂的数字化和智能化水平,使其运营水平和生产效率得到质的飞跃。
论述内容
该系统涉及模块众多,每一个业务都比较独立,所以我们架构组讨论决定采用微服务架构模型,把独立的业务作为一个个独立的微服务单独开发、测试和部署。在此情况下,每一个微服务都采用了独立的数据库,就不可避免产生了分布式事务的问题。比如,排产配置功能,在设置排产时,会调用工资、络筒、细纱等微服务的接口,并对各自的数据库进行表的修改,这种情况下,如果出现某一个服务的修改失败,就产生了分布式数据的不一致。为了解决这个问题,就需要引入分布式事务解决方案。目前主流的分布式事务解决方案有以下四种:1、两阶段提交;2、TCC机制;3、基于消息队列的分布式事务;4、基于本地表的事务。
1、两阶段提交。
这是一种经典的分布式事务解决方案,两阶段包括表决和执行两个阶段,在表决阶段都通过后才会提交事务,只要有一个节点有问题就回滚事务,都不提交。该方式可以保障事务的可靠性,缺点是性能较差,事务协调者需要等待所有节点的反馈。针对两阶段提交的特点,我们在需要严格保证事务型的业务上使用,通常要容忍一定的性能损耗。在纱线MES系统中,班组设置非常重要,纱线MES中的络筒、粗纱、细纱的数据统计都跟班组设置有关,一旦班组设置出现数据不一致问题,将导致纱线MES系统中的多个业务模块的数据出现不一致,让后续产生的工资计算、统计报表、数字孪生、大屏等等出现数据问题,为了解决这个问题,我们采用了两阶段提交方式,并引入了阿里开源的seata框架,通过该框架,确保了数据的一致性,避免发生数据问题,有力提升了系统的准确度。
2、TCC机制。
这是一种常见的分布式事务解决方式,TCC分别为Try,Confirm、cancel,在执行一项任务时,每一个节点都要提供Try、Confirm和cancel方法,Try方法负责锁定该任务需要的资源,比如你要排产,在try阶段就要把排产的工单给提前锁定,避免后续执行出现问题。在Confirm阶段,各个节点就需要执行任务了,在该阶段要保障任务正常执行,同时要满足幂等性,避免多次执行出现问题。如果在Try阶段,发现资源不够,或者任务没法执行,就执行cancel方法,把锁定的资源等释放掉。TCC机制优点是灵活,缺点是对系统代码侵入比较多,需要编写的代码比较多,不太好控制。
3、基于消息队列的分布式事务。
消息队列在大型系统中应用广泛,它有着削峰、解耦、异步、性能好的优点,同时通过它还可以实现分布式事务。具体做法如下:首先,需要设置消息发送方的发送级别,需要多个消息节点收到消息才返回成功,只要成功就确定消息已经进入了消息队列中,这就保证了消息在发送方的事务型。在消息的消费侧,需要取消消费者的自动提交机制,采用手动提交机制,只有消息被正常执行才提交消息。如此就保证了消费者侧的事务型。目前基于消息队列的分布式事务在大型项目中非常流行。在纱线MES系统中,工厂会触发停机事件,该事件到了云端后,云端需要处理停机业务,该业务涉及到工资微服务、络筒和细纱以及粗纱微服务,在这个过程中,如果有某个微服务处理失败,就会造成停机业务出现不同步的现象,为了解决这个问题,我们采用了基于消息队列的分布式事务方式。具体操作流程如下:发起方发送一个半消息,该消息存储在消息队列中,但是并没有并消费者消息,当发起方处理完成后,确认了事务再通知消息队列,让消费者消费。通过这种方式,既保证了事务,又没有系统之间的耦合。
4、基于本地表的分布式事务。
该方法需要提供一个本地表,把执行失败的任务记录到本地表中去,然后通过定时任务去执行失败的任务,如果执行三次还失败就报警给相关责任人,让责任人接入处理。我们在项目开发过程中,对于一些对时间比较敏感的业务就可以采用这种方式。比如在边端上报粗纱线核心数据时,由于模型匹配问题导致粗纱核心数据处理失败,这种情况下如果采用TCC或者AT模式将会影响云端处理的速度,基于此,就可以采用本地表的方式,把核心过程数据记录在表中,后面通过定时任务进行触发重新执行,让核心处理过程再次执行一遍,如果还是不行,就生成报警信息,通过短信、电话、飞书等方式通知响应开发人员介入处理。这种方式既保证了业务处理的快速又保证了事务的最终一致性,在现在系统开发中应用十分广泛。
以上四种方式在微服务架构中得到了广泛的应用,借助分布式事务,微服务才能保证数据的可靠性,避免出现系统性故障。
总结
通过采用分布式事务,我们保障了数据的可靠性,保障了项目的性能、可用性、安全性、可修改性等质量指标,确保了项目的按时上线。最终在2023年12月,该项目正式上线并对外提供服务,目前已经有563家工厂接入了我们的系统,系统运行良好,表现优异,得到了客户工厂和公司领导的一致好评。项目虽然获得了成功,但是也遇到过一些问题,在项目初期,由于产品对纱线业务的不熟悉,导致了多次功能的调整和返工,这让开发人员产生了抵触情绪。为了解决这个问题,我提出两个解决方案:1、派产品去工厂一线,熟悉纱线工厂操作流程,与工人交流,掌握纱线业务的难点和痛点,保障需求质量。2、开发人员也要参与需求的整理过程,有问题反馈给产品,同时在做设计时,采用灵活的设计模式,为需求的变更留下可操作的空间。通过这两个方法,最终解决了这个问题。得益于本次项目的实践,我不仅学到了分布式事务相关的知识,也锻炼了自己的架构和管理能力,我意识到只有不断地学习和实践才能让知识融汇于自己的技术体系之中,才能在未来的工作中游刃有余、勇担大任,为祖国的信息化建设贡献自己的力量。