背景
系统架构风格(System Architecture Style)是描述某一特定应用领域中的系统组织方式的惯用模式。架构风格定义了一个词汇表和一组约束,词汇表中包含一些构件和连接件组合起来的。软件系统架构风格反映了领域中众多软件系统所共有的结构和语义特性并指导如何将各个模块和子系统有效地组织成一个完整的系统。软件架构风格的共有部分可以使得不同系统共享一个实现代码,系统能够按照常用的、规范化的方式组织,便于不同设计者很容易地理解系统架构。
题目
请以“软件系统架构风格”论题,依次从以下三个方面进行论述:
- 概要论述你所参与分析和开发的软件系统开发项目以及你所担任的主要工作。
- 分析软件系统开发中常用的软件架构风格有哪些?详细阐述每种风格的具体含义。
- 详细说明在你所参与的软件系统开发项目中,采用了哪种软件系统架构风格,具体实施效果如何。
论文
摘要
本文讨论某大型ERP系统项目的软件架构风格,试图从项目的实际角度出发,剖析软件架构风格在软件设计过程中发挥的实际作用和效果。该系统位于全球顶尖ERP系统之列,经过多年沉淀和技术迭代依然弥久历新,这不仅得益于其丰富的资源管理功能和先进的底层技术,密不可分的更是其低耦合、高扩展、高可修改性的软件架构风格发挥着巨大作用。在本文中首先讨论了隐式调用架构风格,管道过滤器架构风格和解释器架构风格等软件架构风格在项目中如何发挥着巨大作用,并结合实际情况阐述选择合理架构风格的过程和依据。
最后对现有系统的不足之处进行分析,并且探索可能的解决方案。在本项目的研发过程中,我担任了项目的架构师,与项目经理紧密配合完成对项目的具体架构工作,并指导开发人员高效的完成开发工作,另外还需要负责项目的技术选型和解决技术难点。
正文
ERP系统在软件信息系统家族中有着举足轻重的地位,我司于2022年承接了某国际大型ERP系统的部分模块工作,其中包括,支付模块,人工智能发票等工作。本人负责支付模块和人工智能发票模块的架构工作,另外肩负其余项目组的部分设计工作。其中支付模块包含了众多子系统,比如订单系统,发票系统,汇款系统等以及串联子系统的集成UI平台。人工智能发票模块是一大亮点,通过使用LLM 完成对遗留系统中大量杂乱发票拒绝理由的处理,从而分析出清晰的拒绝理由,并且汇总发票拒绝原因形成报表,乃至预测发票拒绝的趋势,最终降低供应商的发票拒绝次数,以增强用户体验感。
从对遗留系统的分析调研到对新模块的设计和组装以及对遗留系统的升级和对接,总共历时一年,投资300万。在团队所有人的共同努力下,新模块顺利上线并获得客户的一致好评,尤其是智能发票模块极大的减少了供应商发票被拒绝的次数。接下来我们通过对常用软件系统架构风格的分析和比对以及结合实际项目决策来剖析软件系统架构的巨大作用。
本质上讲,软件系统架构风格是对以往业务的高度抽象,类似于设计模式,我认为它也是一种经验层面的复用。假如项目开始之初,没有正确的对业务进行合理的抽象和建模,很难从纷繁的场景中剥离出业务的本质,这就极易导致后续的工作很难开展。比如系统需要高度的可修改行和用户自定义,而我们却选择了显示调用,一旦项目开展,在开发阶段就是受阻,维护阶段更是困难重重。选择适当的软件架构风格对于项目的成败至关重要。
目前主流的软件系统架构风格可以分为五类:1、数据流架构风格;2、调用返回架构风格;3、虚拟机架构风格;4、独立构件架构风格;5、数据中心架构风格。
其一,数据流分为,批处理架构风格和管道过滤器架构风格,二者均需要将数据看作整体在独立的管道或者处理构件中依次完成处理,前者着重于批量处理,后者着重于源源不断的数据在管道中逐个处理。
其二,调用返回分类比较多,比如子程序的显示调用或者独立构件、层次间、对象间的互相调用。但是无论如何这种架构风格的核心思想是,封装。将不同功能封装进不同构件或者更小的对象,进行属性和功能的隐藏以及解耦和复用。
其三,虚拟机架构风格分为解释器和规则系统,这种风格将组装功能的能力交给了客户,客户可以自定义规则集然后通过解释器或者规则系统编译后再实时运行。优点是灵活自定义,缺点是在大数据量面前性能不佳。
其四,独立构件风格的核心思想是解耦各个部件的直接调用,比如事件驱动。现在领域中常用的MQ 就是典型的应用场景,通过事件驱动解耦各个部件从而实现性能上的提升。
其五,数据中心风格可以分为多种。比如,仓库,黑板等,数据中心模式强调的是集中处理数据或者共享数据从而实现数据的复用或者分组分块处理。
接下来,笔者从实际的ERP项目具体模块的案例讨论,从其如何对如上软件建构风格进行取舍的方向出发一起探讨这些风格的落地和实际效果如何。
笔者所开发项目的支付模块本身包含多个子模块,而子模块之间又存在着不同程度的相互调用,比如发票模块需要获取订单信息,汇款模块需要获取发票信息,并且各个模块所需要的计算力也不尽相同,结合客户想要升级现有系统的夙愿实现对各个模块的独立部署和动态监控以及管理过程。基于客户现有体系,我们设计出支付模块V2.0,整个模块跟ERP系统中其他模块通过ESB进行连接,这是基于遗留系统的设计。但是整个支付模块是基于微服务架构的,将不同模块拆分为独立的服务进行独立开发可以极大的缩短开发周期和测试成本,另外将各个独立服务部署于客户的私有云上,可以实现服务的动态管理和扩缩容,对于后期的维护和扩展起到了至关重要的作用。为了串联整个支付模块,也独立开发了一套UI系统,UI系统调用不同微服务来获取相应数据,从而做到了对用户的友好操作。另外独立的UI系统使得前后端可以彻底分离开发,这也极大的增加了开发效率。
其中子模块包含发票的审批功能,从一开始的调研中发现客户可能会经常更改审批流程。笔者及团队成员经过慎重讨论后,决定采用解释器风格。选取了比较稳定的Activity作为活动流的中间件,用户可以通过拖拽的形式完成对流程的自定义,随后将定义的模板经过Activity转换后持久化到数据库。随后系统完成对Activity的集成工作从而实现审批流程的用户自定义。该子模块也是众多模块中用户最受欢迎的模块。通过牺牲一小部分性能换取了极大的灵活性。
智能发票模块着眼于供应商被经常拒绝发票的痛点,通过结合当下比较流行的AI 大模型,分为三大阶段完成开发,1、发票拒绝原因的智能分类;2、发票拒绝的周报和月报;3、发票拒绝的趋势以及预测。其中智能分类阶段出于对用户信息安全的考虑需要对原始数据进行过滤,其中包含用户个人信息,企业敏感信息,发票数据信息等敏感信息。但随着需求的不断更新不难发现这些敏感信息是会变化的,所以设计之初便提出了管道过滤器架构风格,将每种过滤器独立开发,然后经过一定顺序组装在一起构成敏感信息隐藏组件,当某些数据需要处理时,可以快速且灵活的自定义组件。经过独立的过滤器数据完成需要的敏感数据过滤和处理。反之,如果没有选择管道过滤器风格,开发过程中用户删除或者增加敏感信息,就会变得非常麻烦,且无法完成独立开发。
另外,由于该系统客户众多,数据量庞大,这些发票拒绝信息可能会在同一时间不定期的蜂拥至服务器,如果采用调用返回或者串行的处理方式可能有系统瘫痪的风险。于是采用隐式调用,主系统负责生产发票智能处理事件,Kafka作为高吞吐低延迟的事件处理平台负责对事件进行转发,独立的微服务负责发票拒绝的处理工作,从而实现了削峰填谷对发票拒绝信息的智能处理。对于系统的可修改行也带来了极大好处,因为随着系统深入使用,发现发票拒绝的数量在一开始非常巨大而随着智能发票系统的引入其拒绝也逐步降低。得益于前期的良好设计,客户可以动态调整计算量(微服务的数量甚至是内存大小)。
该系统交付上线后,获得客户和使用者(供应商和买方)的一致好评,稳定运行至今。其不同模块的高可扩展性,低耦合,高可修改性,高性能更是系统的亮点所在。这些良好性能均得益于项目设计阶段的正确定位以及合理架构风格的选择。不仅如此,合理的架构还会大大的提高开发效率。反之,可以想像,开发低效,难以扩展,性能不佳,这样的系统往往都是架构的问题。足以见,架构是一个信息系统的根基所在。但受限于遗留系统以及其他非主观性因素的限制,交付模块仍存在一些值得思考的问题,比如对于LLM 的使用不能仅限于单一生产商(GPT),应该可以灵活配置其他大语言模型生产商。另外,系统遗留模块也有可能以后需要智能+,比如智能发现供应商、智能订单等等,这一些都在促使一个通用的LLM落地平台的产生,诸多受限下,现有系统只是和LLM做了简单的集成。