相对于系统软件而言,企业软件往往是面向应用场景、业务逻辑。虽然很多工程师、架构师会面带严峻表情的告诉你,软件项目所要保障的高可用性、鲁棒性、可扩展性、高并发性、低延迟性、安全性、可测试性、灵活性,是如何如何的重要,仿佛一套只有几个部门三五十人用的软件系统,其架构也得是多么科学、严谨、隆重的经历一系列的设计、论证、测试,姿势拉好、仪式感满满。
但现实中,多少企业的软件系统是由代码屎山堆成,多少IT运维人员是每天沉浸在救火中,多少开发工程师被业务部门的需求逼迫的996也依然人仰马翻,多少业务人员则是被“提新需求如油盐不进、讨旧债务似老鼠拉龟”不见效果的系统折磨出焦虑症。
今天面向业务逻辑、应用场景的软件系统,其底层或者说基础技术层(例如网络连接、多线程、内存管理等等)早就被封装成成熟的组件了,最难、最硬核部分的技术工作,可能九成以上被某些开源项目或者商业组件解决了,企业软件系统的开发工程师,需要编写代码解决的主要问题,都是业务应用问题 - UI编程、表单处理、数据存取、增删改查、消息队列、任务调度、领域建模、接口集成、服务封装、信息同步、批处理... 有多少技术含量?如果你问一个三十年前的C++程序员,手工搓网络代码、手工写线程管理、手工打造应用框架、然后手工建对象模型开发应用逻辑... 今天的这种企业应用开发,对他而言可能就是裱糊匠的工作...
那么为什么这些系统的开发、扩展、维护还是这么痛苦?其最根本原因,如果只选一个的话,那就是:紧耦合。代码屎山就是因为代码写成一坨,环环相扣,牵一发动全身,历史代码谁都不敢乱改乱动,在“意大利面条”般的条件判断语句和无穷无尽的打补丁中堆成。“敏捷”大部分情况下是一种口号或者自嗨,从来没有让业务部门承认过信服过...
企业应用软件架构,扯更多的“性”没用。极端一点的说,如果只选择一个企业软件架构设计原则彻底奉行,那只有是:坚持“分而治之”的原则,建立高内聚、低耦合的技术架构。
甚至可以说,一个企业软件系统的架构师,其终生职业所做的事情,不过是设计低耦合技术架构 - 不断的梳理问题、解耦千丝万缕的关系,对问题分而治之,各个击破,必要时则又对集中统一与解耦分离作出一定的折衷取舍,仅此而已。
分治算法与思想(Divide-and-conquer)
分治算法,对于每一个计算机科学系毕业的学生,都是入门级的“数据结构与算法”必修课里的基本内容。“高内聚低耦合”的技术架构,可以算是分而治之的算法精神的一个体现。事实上,在软件世界分治算法无处不在,以下是大家熟悉的例子。
大数据领域:MapReduce与ETL
MapReduce 是一种编程模型和处理大规模数据集的计算框架。它在分布式计算环境中实现了“分而治之”的思想,将大规模数据处理任务分解为可并行处理的小任务。
Map 阶段:在 MapReduce 中,数据首先被分割成若干个小块,然后通过一系列的 Map 函数进行处理。每个 Map 函数独立处理一小部分数据,并生成中间键值对(key-value pairs)。
- Shuffle 阶段:中间键值对被重新分配和排序,以便相同的键值对能够被送往同一个 Reduce 函数。
- Reduce 阶段:最后,由一系列的 Reduce 函数对相同键的数据进行合并和计算,生成最终的输出结果。
- MapReduce 的优势在于它能够高效地处理大规模数据,并通过分阶段的操作实现了任务的拆分与聚合。
ETL 是一种用于将数据从一个地方提取、进行转换,然后加载到另一个地方的数据处理过程。ETL 过程同样遵循“分治算法”的思想,将复杂的数据处理任务拆分成几个独立的步骤。
Extract 阶段:数据从源系统中提取出来,可能包括关系型数据库、日志文件、API 等。
- Transform 阶段:提取的数据进行清理、转换、过滤等操作,以满足目标系统的需求。这个阶段可以包括数据清洗、格式转换、计算等处理。
- Load 阶段:最后,处理过的数据被加载到目标系统中,可以是数据仓库、数据湖或其他存储系统。
- ETL 的分而治之体现在每个阶段的独立性,每个步骤都专注于特定的任务,通过将复杂的数据处理流程拆解为简单的步骤,提高了可维护性和扩展性。
云计算领域:微服务、容器、容器编排
微服务(Microservices)。微服务架构是一种软件设计方法,将一个大型应用程序拆分成一组小型、相对独立的服务。每个服务都负责一个特定的业务功能,可以独立开发、部署和扩展。微服务体现了“分而治之”的思想,通过将整个系统分解为小而自治的服务,降低了系统的复杂性,使得每个服务可以独立演化和扩展:
- 分解:微服务将大型应用拆分成小的、独立的服务单元,每个服务专注于一个特定的业务功能。
- 自治:每个微服务都是自治的,具有自己的数据存储、开发团队和部署流程。
- 独立演化:微服务之间的松耦合使得它们可以独立演化,而不影响整体系统的运行。
Docker 容器技术: 是一种轻量级的容器技术,通过将应用程序和其依赖项封装到容器中,实现了跨平台、一致性和可移植性。Docker 的设计理念与“分而治之”相符,通过容器化应用,将大型系统分解为小而可管理的单元:
- 封装:Docker 封装了应用程序和其依赖项,形成一个独立、可重复部署的容器。
- 隔离:每个容器是相互隔离的,一个容器的变化不会影响其他容器,实现了微服务间的高度隔离。
- 可移植性:Docker 容器可以在不同的环境中运行,实现了应用程序的可移植性和一致性。
Kubernetes 技术: 是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。它体现了“分而治之”的思想,通过将应用程序部署为多个容器,并提供自动化的管理工具,实现了系统的高效、弹性的运维:
- 部署:Kubernetes 将微服务以容器的形式部署在集群中,每个微服务可以独立部署。
- 扩展:通过动态调整容器数量,Kubernetes 实现了微服务的弹性扩展,可以根据负载自动调整服务的副本数。
- 自愈:Kubernetes 提供了自动修复和替代故障容器的机制,保证系统的稳定性和可用性。
通过微服务、Docker 容器技术和 Kubernetes 技术的结合使用,系统的复杂性得以降低,每个组件都可以独立演化和部署,实现了系统的分而治之。这样的设计思想有助于构建更灵活、可维护和可扩展的分布式系统。
人工智能领域:神经网络、大语言模型、多智能体
神经网络: 神经网络是一种由多个神经元组成的模型,它们分层组织,通过学习从输入到输出的映射关系来完成任务。在神经网络中,分治算法的思想体现在网络的分层结构和层级特征提取上:
- 分层结构:神经网络通过多层的结构,将复杂的问题分解为多个阶段的特征提取和抽象。每一层负责处理输入数据的不同层次的特征,使得神经网络能够逐层学习和理解数据的表示。
- 特征提取:每一层神经元都专注于学习特定的特征,通过逐层的处理,逐渐提取出数据的抽象表示,实现了对问题的分而治之。
Mixture of Experts 模式: Mixture of Experts 是一种神经网络结构,其中包含多个专家(experts),每个专家负责处理特定类型的输入或任务。这种结构体现了“分而治之”的思想,通过将整个问题拆解为多个专家负责的子问题,每个专家独立学习和处理局部信息。传说中OpenAI的大语言模型实质上以MOE构成,而在开源大语言模型领域表现突出的Mistral则发布了Mixtral 8x7B,在多项指标超越GPT 3.5和Llamma2 70B
- 专家组合:在 Mixture of Experts 中,一个 gating network 负责确定每个输入由哪个专家处理。这样,每个专家只需关注自己负责的子问题,降低了系统的复杂性。
- 独立学习:每个专家通过独立学习局部的任务,而 gating network 则协调这些专家的贡献,实现了问题的分治和整体优化。
大语言模型的 Multi-Agent 多智能体:大语言模型中的 Multi-Agent 多智能体结构是一种通过协同工作的多个智能体(agents)来解决复杂问题的方法。每个智能体负责学习和处理特定方面的知识,整体上体现了分治算法的思想。每个智能体都可以独立地思考、决策和行动,同时与其他智能体进行交互。多智能体系统可以用于解决许多复杂的问题,例如协作、博弈、规划、控制、优化等等:
- 任务分配:每个智能体专注于学习和处理一部分知识,通过任务分配,每个智能体负责处理特定的语境或任务。
- 协同学习:智能体之间通过协同学习,将各自的专业领域的知识整合起来,形成对问题的全局理解。
神经网络、Mixture of Experts 模式和 Multi-Agent 多智能体都体现了分治算法的思想,通过分解问题、分层学习、任务分配和协同工作,实现了对复杂问题的高效处理。这种分而治之的设计理念使得模型更具有可扩展性、可维护性,并有助于提高系统的整体性能。
系统工程领域:插件、App商店、小程序平台
软件的插件机制、应用商店和小程序技术在架构设计理念和运作模式上具有以下共性,都体现了“分而治之”的思想:
- 都是基于功能模块的分解与解耦。插件将特定功能剥离为单独模块,小程序将应用划分为独立子应用,App商店将软件产品化为一个个应用。实质上,小程序可以被视为某个“超级App”的插件,而App则可以被视为是某个手机操作系统的插件
- 都是高内聚与松耦合的结合。插件、小程序或App内部功能高度内聚一致;而它们之间通过简单且稳定的接口进行数据交互或消息通信,实现松耦合。
- 都可通过配置或编排自由组合。用户可以灵活启用插件,下载安装不同App,组合使用小程序,来满足多样化的定制需求。
- 开发者都无需了解或修改“母体软件”内部实现,只需依照规范、接口,实现自己的内容“单元”。开发者之间毫无关联关系
- 都构成了生态系统。插件模式、应用商店和小程序生态都通过这种“分而治之”的机制形成了非常充满活力的软件或服务生态。系统内高水平的协作创新与共生共荣得以实现。
- 这三种技术作为典型的体现机制,都验证了基于“分而治之”的低耦合组件化设计,是构建灵活、易扩展、协同创新的软件系统的有效模型。这为企业软件架构提供了可资借鉴的设计模式。
架构模式:管道-过滤器架构、SOA
管道-过滤器架构和面向服务架构(SOA)都体现了“分而治之”的思想,主要体现在:
管道-过滤器架构将一个处理流程分解为一个一个的过滤器组件,每一个过滤器实现某一个步骤的处理功能。这些过滤器之间松耦合,通过管道(如流)串联起来,实现流水线式的并行处理,大大提高了效率。过滤器和服务内部是高内聚的模块,具有单一职责;而它们之间通过管道或标准化接口进行松耦合,降低了依赖,提高了灵活性。通过配置和编排框架,可以复用和灵活调度这些可组合的服务或过滤器构建流水线,以满足不同的业务处理需求。实现了可重用性和业务流程的敏捷配置。
SOA是一种软件架构风格,它将应用程序中的功能模块封装成服务,每个服务实现一组内聚统一的业务能力,服务之间通过定义良好的接口契约进行通信与交互。这种方法可以实现应用程序的快速开发和部署,同时也可以方便用户获取应用程序。SOA体现了分治算法的精神,将一个大问题分解成若干个小问题,然后逐个解决这些小问题,最后将结果合并起来得到大问题的解。
轻应用的“商店模式”应成为下一代企业软件基础架构
在上述众多体现“分治”精神的软件架构模式下,对于企业来说,“商店模式”最为值得借鉴,这是数字化时代任何企业在数字化转型过程中最为有用的企业技术架构。
企业IT思维从扮演“集成商”角色转变为扮演“平台运营商”角色。过去企业IT的开发人员最主要做的事情是充当裱糊匠,调用、粘合第三方系统,没完没了的“集成” 。是时候提高“平台”意识,由IT基于企业诉求搭建框架、技术平台,制定标准,让开发商、技术供应商遵循这些标准来提供“插件”、“乐高”。即使是IT自己,内部的很多开发团队实际上也是这类“插件”的提供者。
“插件”应聚焦业务应用,而不是底层技术,业务插件实际上是一种“轻应用”。轻应用型的“插件”机制是高层技术载体,让开发者无需了解插件的“母体”软件系统或者说“宿主”,即可开发、调试业务内容。且开发者之间无关联关系,互相不影响,可以(1)并行开发互无干扰,(2)无上限的扩展开发小组/团队的数量。让每个业务部门的数字化业务内容得以平行进行。
“插件”的上下架、审核、审计、搜索发现、升级更新、分发出版,均应在企业内统一管理。这个管理的技术载体,就是“应用商店” - 也可以称之为“插件商店”、“乐高商店”。这类的“应用”,不是手机上的App,更有可能是基于HTML5或在其基础上扩展的DSL(Domain Specific Language)开发的业务逻辑代码模块。
走向开放与连接。传统企业IT思维是,强烈假设一个软件系统的内容必然由IT开发或集成,由内而外的输出。但在数字化时代,这个假设未必再成立,数字企业需要在安全可控的基础上更加开放,其中包括如何允许业务部门引入第三方合作伙伴或业务内容供应商的源代码运行在己方的系统(例如App)中,或者说,如何让第三方而不仅是IT自己提供插件,从而形成自己的数字化合作生态,起到借力打力的效果。从某种角度看,数字生态与连接是数字化企业无法绕开的。拥有一个插件“商店”并开放,就拥有一个数字生态。
企业化小程序技术平台 - 符合国情的新一代企业软件载体
有想法有能力的企业IT,采用“商店模式”自主研发一个内部的“插件商店”、软件模块的“零部件仓库”,说难不难,但要让其有生命力、长期可持续发展,则是一件相当挑战的事情。
例如,在移动互联网发展中后期,不少技术团队也探索出用HTML5实现业务逻辑导向的、变更相对频繁的模块并支持热更新,降低对手机上原生App的变更所产生的成本,提高开发测试和发版的敏捷度。
但是这种做法有几个不足之处:
- 首先是“土法炼钢” - 相当于自己发明了一次“轻应用”(基于HTML5的代码模块)
- 其次,这种“作坊式”DIY的“轻应用”,因为一开始就不是从一种工业标准或被广泛接受的规范的角度考虑,而是基于某个企业自己的应用场景和一些工程实践的积累,“迭代”而来,因此往往缺乏周详完备的考虑,对通用性考虑不足,可能经过相当长时间的积累后趋于稳定,但也可能沉淀了不少的早期历史包袱和技术债(例如因团队早期工程经验或业务焦点所导致的局限性而形成)
- 第三是这样的内部自研封闭技术,很难做到对外开放 - 例如如果企业希望打开一个轻应用“商店”,争取外部合作伙伴、开发者向商店开发新内容或者迁移存量内容,面临相当困难,因为要求外部开发者重新学习了解一个非标准的技术,开发、迁移成本高,也没有其他商业化回报
- 第四是自我维护这么一套不直接与业务内容相关的“中间件”成本不低,在业务导向的传统行业的企业中,这类成本投入也不见得能被业务部门、财务预算的控制部门所理解。长期来说变成一种食之无味弃之可惜的“鸡肋”的机会颇高
- 第五是无法衍生出专业的开发工具、测试工具,因为这种研发投入对于一般的企业来说是不划算的,不是它们的本业
说到底,自我发明“插件”机制、自我定义“轻应用”规范,最大的问题是:缺乏工业标准。没有标准就没有开放性,也就没有技术生态、内容生态可言。技术供应商、系统集成商等乙方需要根据不同的甲方客户的技术要求,把相同的技术内容作重复开发。因为给每一家客户都是做人力密集型的“外包”,实施成本高并且因客户而异,所以乙方也不得不把成本转嫁于甲方。简单的说,甲方乙方的对接成本都非常高。
那么,对于传统企业IT而言,是否足够大的企业就有资格去制定某个行业内的“轻应用”标准,从而约束业内软件供应商、开发商、集成商去共同遵循,达到整个行业的降本增效?答案恐怕也是否定的,因为被某个行业共同接受的标准,不仅制定周期长、涉及众多同业机构的协商和扯皮,更往往同样没有生命力,终究要被互联网标准、市场约定俗成的“既成事实”标准所替代。
鉴于这样的观点和认知,市场上出现了以凡泰极客FinClip引领的“小程序容器”技术,它专为企业软件系统建设而生,背后的设计逻辑是:
- 最大程度兼容互联网上最主流的、拥有最多开发者、沉淀最多存量内容的小程序规范,直接采用小程序作为下一代企业软件中“轻应用”的技术载体。这相当于在ToB赛道重新发明了一次小程序(但除遵循相似规范或标准外,与互联网上的小程序平台并无关系)。从而让传统企业的IT能够更容易的获得开发人才、吸引合作伙伴提供内容
- 逐步向W3C MiniApps(国际互联网技术标准制定组织W3C的MiniApps 工作组牵头的小程序技术标准)靠拢,让传统企业节省“重新发明车轮”的麻烦与成本,以工业标准去打造自己的企业软件系统
- 整体上为任何行业的甲乙方合作、对接,提供最根本的降本增效方案。甲方无需徒劳的去定义行业标准,乙方也无需被迫接受、适配相对封闭的行业标准,大家都采用最普遍、最广为人知的技术即可
- 以小程序作为现成标准,提供产品化的开发工具如IDE(FinClip Studio)、调试工具(如FinClip App、FinClip Browser)、低代码生成工具等等
PWA(Progressive Web App)、.Net以及众多JavaScript Meta Framework(诸如Next.js、Nuxt.js、SvelteKit、Astro、Vite、Remix... 以及涉及Hydration、SSR等诸多技巧与概念),在移动互联网高度繁荣、人机交互体验领先全球的中国市场,从来都没有取得过成功或者成为主流。相比之下,小程序技术是最符合国情的轻应用技术。凡泰极客把这种技术重新发明为企业应用软件的基础平台,有非常合理的市场基础。
极致的高内聚、低耦合
小程序技术可以说是把高内聚低耦合的架构设计思想发挥到极致。
从业务功能解耦的角度看,任何业务场景、应用逻辑,都可以独立在某个小程序中实现,而小程序之间互无关系、互不影响。
从开发团队解耦的角度看,任何开发小组、开发团队仅负责自己的小程序,彼此无依赖关系。运行在小程序容器中的代码,彼此之间有安全隔离、资源隔离,所以小程序代码库及知识产权均独立维护。
从规模效应(Economy of Scale)的角度,任何拥有小程序容器技术的企业,均可以像某些互联网巨头一样,引入、运行无上限的小程序内容 - 注意这是“数字化转型”的关键,当企业可以低成本甚至接近零成本的引入极其丰富的小程序化业务内容时,即可让其客户、员工、合作伙伴“不离线”的在平台上获得一切的数字服务,所谓数字化就达到“从量变到质变”。
从敏捷触达市场(Time to market)的角度看,任何小程序化的业务场景、应用逻辑,均可以“小程序粒度”发布或回收。以银行为例,通过这样的技术,在其App中,每天可以由各业务线、各区域分支行灰度发布和上下架小程序内容百千次,谁都不用等候谁,功能上架没有在IT枢纽排期一说。内容发布变成一个以IT、法务、合规、风控等部门联合管控的运营事务。
从数字内容生命周期的角度看,小程序化的业务数字内容,其开发、测试、灰度发布、审核、审计、上架、下架等全生命周期的管理,完全由“业主”部门自主负责,和它所运行的软件系统“宿主”环境(例如某个App)无关。
从生态化的角度看,拥有小程序技术平台的企业,技术上也拥有了自己的“小程序商店”,具备了自主打造合作生态、发展合作伙伴的可能性。数字化转型的焦点,从建设基础技术平台,转移为运营数字化生态。生态建设的成功,不再受技术掣肘,全在于企业的线上开放合作的营销推广能力。
企业应用软件系统的小程序化,可以说是“分治算法”精神下一种极致的低耦合技术架构,企业软件的“可测试性”、“可扩展性”、“灵活性”、“鲁棒性”等等,会随之而来。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。