前言
随着时代的发展,网络通信已经成为人们日常生活中不可或缺的一部分。在5G时代背景下,传统的网络通信已经不能满足工业侧及企业强应用通信的需求,出于安全性、稳定性的要求,专有网络通信逐步成为通信市场的一支重要力量。作为通信运营商,我们更是应该在专网通信领域展现出自身的通信优势。
除了通信技术的发展之外,对应于CT通信技术的发展需求,作为IT侧的Web前端开发也需要顺应时代发展构建出符合业务及产业模式的架构模型,为ICT融合提供技术方案支持。本文旨在通过专网通信领域的业务实践,从系统性、结构性、健壮性等几个不同的维度来阐述前端架构设计过程中的考量与分析。
系统性
系统设计作为整个软件工程项目的顶层设计,是根据系统分析的结果,运用系统科学的思想和方法,设计出能最大限度满足所要求的目标的新系统的过程。在整个软件架构中,系统性作为整体项目的先导及前驱,需要能够贯穿整个项目时段,本章将通过设计理念、设计方法、设计模型、设计原则四个方面来阐述在系统性方面的思考。
设计理念
设计理念作为整个系统架构的指导方针,是整个系统架构的核心理念及设计哲学。在专网通信领域中,结合业务需要及软件工程中的设计方法,整体的设计理念是:
简约、有效、解构、可控、扩展
简约:以最简单的方式实现,最大限度的保证当前粒度的复杂度最低。方便开发与验证,提供简单的设计模式,有利于系统内的所有人员达成一致,为有效且高效的组织提供可能。
有效:以合适的划分粒度分拆问题,不进行过度设计,以避免引入不必要的复杂度到系统中;也不进行过少设计,避免冗余。在精益中提升软件质量,以最高性价比的方式解决问题,避免任何形式的冗杂。
解构:以明晰的边界确定粒度与粒度之间的权责,本颗粒度下内部共融;本颗粒度外,需要暴露的对外共享,不需要不暴露的隔离封闭。
可控:以可靠的观测方法输入,以同一结果输出,可观测;问题出现,定位清晰,可追寻;临时更改,及时应变,可容错。
扩展:提供渐进的解决方案,提供完整生态,兼容并包,根据需求定制,可扩展、可插拔。
设计方法
设计方法作为一组按照架构领域的开发顺序而排列的一套方法理论,是对复杂业务需求的梳理后做的全面方法总结。在前端开发过程中,结合对应常见不同的架构分类,对不同层次各个子集做对应的方法论总结。
业务架构
业务架构定义了符合业务产出的对应的能力或者功能矩阵,明确业务流程。对应于前端工程而言,则是要落地到业务时序、角色分配、权限认证等。
数据架构
数据架构描述了组织的物理及逻辑数据资产,以及数据资源的结构。在前端工程中,则是对应最初的数据结构的设计,从方法论上可以参考不同的数据集合进行数据库模式的设计与接入。
应用架构
应用架构提供了一个蓝图,涉及各个应用程序部署,它们之间的相互作用,以及它们的联系,该组织的核心业务流程等。对于前端领域而言,则是对于不同应用之间的聚合统一以及隔离呈现,包括但不限于跨端呈现以及上下游逻辑串联。
技术架构
技术架构描述了需要支持的业务,数据和应用服务部署的逻辑软件和硬件的能力;这包括IT基础设施、中间件、网络等。对于前端而言,则是包含各种框架体系以及对应的生态延展,筛选更加符合业务的场景落地技术方案。
设计模型
软件设计采用不同的视角来设计抽象软件的系统,对需求进行分析而产生概念模型。常见的设计模型包含:面向对象模型(OOP)、面向领域模型(DDD)、六边形模型(Hexagonal Architecture)、洋葱模型(Onion Architecture)等。软件设计最重要的过程就是抽象,对业务及领域进行建模,通过抽象化的手段将共性及元信息抽离,通过不同的组合模式构建属于自己业务及系统的模型。抽离设计模型是一个高度凝练和萃取的过程,需要考虑多方因素。抽象设计模型既要做顶层设计,又要做底层设计,视野要从上而下,拆解要从下而上。
设计原则
软件设计过程中要符合软件开发的特征,通常来说需要符合以下几大原则:
单一职责原则
单一职责原则是指每一个颗粒度都只专注于一件事情,从而可以降低单颗粒度的复杂度,简化逻辑,职责简单,提高可读性及系统可维护性。在修改及变化过程中,可以减低对其他颗粒度的功能影响。
开放封闭原则
开放封闭原则是指面向扩展开放,面向修改关闭,这意味着在需求变化时,对代码变化所做的修改应该以扩展为主,而不是修改之前的代码,这就要求在设计颗粒度过程中保留扩展项,以应对变化。软件需求总是变化的,因而在不对原有系统做修改的情况下,可以基于不同的设计模型构建不同的系统扩展。
里氏替换原则
里氏替换原则是指具象粒度可以替换抽象粒度,也就是抽象粒度的元信息是完全抽离的具象内容,其也是开闭原则的重要验证方式之一,满足里氏替换原则表明其开闭性是可以保证的,在不同的设计模型中,可以运用不同的方法来实现抽象粒度与具象粒度之间的链接关系。
接口隔离原则
接口隔离原则是指颗粒度对外应该提供尽可能详细的接口,而不是提供宏观的接口,对外暴露的行为应该越少越具体也好,这样才能保证外部对内部的影响及侵害做到最小,尽量细化接口。通过分散定义多个接口,可以预防外来变更的扩散,提高系统的灵活性和可维护性,在隔离与外界的界限过程中,也能做到边界的明晰与确立。
依赖倒置原则
依赖倒置原则是指实现应该尽量依赖抽象,不依赖具体实现。具体依赖抽象,上层依赖下层,可以减少颗粒度之间的耦合性,提高系统的稳定性,减少并行开发引发的风险,提高代码的可读性和可维护性
迪米特原则
迪米特原则又叫最少知识原则,一个软件架构实体应当尽可能少的与其他实体发生相互作用。颗粒度与颗粒度之间的关系越密切,耦合度也就越来越大,只有尽量降低颗粒度与颗粒度之间的耦合才符合软件设计的模式。一个颗粒度对另一个颗粒度中引用或者使用越少越好,这样可以避免发生变化时,相互之间产生关联反应,如果必须进行相关的关联操作,可以通过第三者进行相互的联系,后续变化只需对第三者进行相关的操作即可,方便维护。
组合/聚合复用原则
组合/聚合复用原则是指应尽可能多的进行复用,而不是复制,通过单一职责的颗粒度构建,在其他业务中可以尽可能多的复用相关的颗粒度组合,从而在发生变化时,只需要在内部修改对应的颗粒度内容,对外做到接口隔离而不影响外界的使用。
结构性
软件系统作为一个有机的整体,其内部是由若干个不同的部分构成的,结构性则主要是从软件组织结构的角度来衡量,它包含或关联了一些不同层次的信息。从最早的单体架构,到面向服务的SOA架构,再到后来的微服务架构,不同的软件架构演变,都体现了结构性的重要性。对于前端工程而言,常见的分层设计是软件系统结构化的一种有效实现方式,本章将从网关层、应用层、基础层三个划分层次来阐述专网项目中的架构设计的结构性特征。
网关层
在传统软件开发过程中,不同的业务类型所对外界暴露的方法不尽相同。在网络通信中,我们常常使用网关来作为内网与外网的通信传输连接。在软件开发过程中,我们也可以借鉴这样的思路来对我们的软件系统做对应的设计和处理。
对于专网领域的前端而言,对于各种应用的收敛和聚集就成为一个对外暴露的重要层级。网关层的出现,打破了框架及业务栈的束缚:对内部应用,可以提供服务注册机制用于各种应用的聚集和收集;对外部用户,可以提供统一的服务地址,从而隔离开用户与内部应用变化带来的割裂感。
应用层
应用层作为各种业务的不同呈现形态,是真实落地到各种业务形态的子形态。对外部而言。各个应用之间的关联及处理可以通过网关层做对应的服务分发和拉起;对内部而言,则可以选择对应的框架形态来更好的处理所需要的业务,从而实现了高内聚、低耦合的软件系统关联与隔离。
对专网业务形态而言,需要提供专业的业务处理服务,也即通用化的中台产品服务;同时也需要提供对应的可视化产品服务,更好的展现业务数据信息,从而将CT侧的业务内容进行IT化的展现。应用层可以基于不同的业务需求,扩展不同的形态,跨端、互动等新的业务形态也可以插件化的形式注入,从而对扩展开放,共建生态圈。
基础层
基础层为所有业务提供公共的基础技术服务,避免单个业务应用各自为战,形成各自的独立技术烟囱;同时,也为业务的技术沉淀积累提供面向更多业务形态的技术支持,做到了技术能力的抽象通解。
对于专网业务形态而言,其基础层主要提供了面向整个产研链路的基础服务支持,方便产品、设计、前端、后端、测试、运维同学的全链路通路连接,一站式解决整体的前端上下游沟通屏障,打造高效、简单的产研一体化解决方案。在产品侧,提供了wiki文档化的支持;在设计侧,提供了图床、设计物料、设计组件库的支撑;在前端侧,提供了脚手架、监控等开发模板工具;在后端侧,提供了静态转发、BFF转化、接口联调配置等技术设置;在测试侧,提供了通用的测试套件,方便测试用例的设计及验证;在运维侧,提供了高效的CICD流水线处理,提供故事版等功能性处理方案。
健壮性
健壮性是指软件系统在一定参数的摄动下,维持正常的特性。根据不同的系统级别的要求,通常要求软件架构系统在设计的过程中考虑不同的健壮性要求。本章将通过高可用、高性能、高安全、高扩展来阐述系统的健壮性。
高可用
高可用主要目的是为了保障业务的连续性,即在用户眼里,业务永远是正常对外提供服务的。要保证架构的高可用,就要保证架构中的所有颗粒度及其对外暴露的服务都能尽可能做到高可用。对于前端而言,通常需要在服务拉起的过程中保证高可用,那么可以采用冗余及自动故障转移等方法来处理。
对于专网业务而言,在基础层提供了云化相关的基础操作,利用云化的一些高可用多副本做到服务可达,同时在运维发布过程中基于不同的业务需求做到发布的策略分化,从而更好的为业务及用户数据收集等产品需求做到技术理论支撑,闭环整个链路。
高性能
高性能是指对于资源的最高利用,可以最大限度的发挥软硬件的优势。要保证架构的高性能,通常需要在不同业务形态中利用不同的性能瓶颈做对应的优化与改造。对于前端而言,由于更加贴近用户侧,其通常高性能包含网络、渲染、用户体验等几个方面。
在专网业务中,由于网络层的特殊传输特点,其对于网络的优化通常都是基于云原生相关的网络侧优化,而对于渲染侧的压力,则可以基于不同的业务形态选择诸如客户端渲染(CSR)、服务端渲染(SSR)、原生渲染(NSR)、边缘渲染(ESR)等不同的渲染模式或者混合渲染模式。
高安全
高安全是指对于系统的攻击保证有效的防护及对于潜在危险的及时清除。要保证架构的高安全,除了要应对常见的攻击手段之外,还需要对系统本身做到监控可控。对于前端而言,由于面向用户更近,对于用户的操作最可能攻击到本身系统的安全,因而做好诸如XSS、CSRF等前端安全防护是十分重要的,同时也要对风险做到评估和监控。
在专网业务中,在基础层对于不同应用层的应用做到了前端的监控,对于性能、错误等做到数据的收集与处理,对于密钥及密码的设定做到高级别防护,网络通信采用加密传输等手段防护,同时对于中间访问做到不同层级的拦截和鉴权验证。
高扩展
高扩展是指在不改变系统整体核心架构下,为了支持不断增长的需求而保证系统的快速响应。要保证架构的高扩展,通常需要对内核形态做到充分考量,明确可更改及不可更改的边界。对于前端而言,通常需要考虑不同的产品需求变化对可抽离的部分尽可能抽离,对于不同的编程范式,采用符合业务方法的编程方案,比如:在使用面向对象编程过程中,尽可能使用设计模式等来处理业务需求和正确编码等。
对于专网业务而言,高扩展通过使用前端网关的服务发现及注册机制来拉起对应的微应用,做到前端的微服务化,对于单个应用中可以再进一步拆分,可以使用诸如类单页形式、类iframe形式、类web组件形式、类容器化形式等的微前端方案来处理,从而实现整体的高扩展和兼容处理。
总结
相较于后端发展的历程,前端的发展过程则经历了以下几个时代变化:在上古时代,浏览器诞生,伴随着第一点浏览器大战,前端注重在静态页面的搭建;到了石器时代,ajax技术的出现,前端工作涉及到了一部分的数据交互工作,同时也进行着第二代浏览器大战;而在农业时代,面对不同浏览器所提供的的各自api的兼容性需求,前端第一次出现了基于库的开发的模式,突现出了一批诸如jQuery、YUI、ExtJS等类库;紧接着,随着工业时代的到来,前端也承接了更多的数据交互工作,从之前的服务端渲染页面,转换到了浏览器客户端来渲染页面的时代,也在这个时代出现了前端框架的理念;到了更近一些的信息时代,随着不同终端的出现,前端出现了各种跨端体验一致性的需求,从而带来了不同渲染模式的方案;在当前的云边端时代,目前基于不同的业务形态和业务方向,前端呈现出更加多样化和复杂化的形态,借助其他软件领域的发展,前端形态更加多元和泛化。
对于层出不穷的业务形态与需求,前端从单纯的页面切图也渐渐演变到了整体软件架构的治理。在软件工程领域,所有的业务形态都可以通过不同的抽象组合架构拼接完成,但合理优雅的架构方式不仅要考虑全局的调度与共生,也需要兼顾局部的优化与权衡。道以明向,法以立本,术以立策,势以立人,器以成事。