浅析从基础层和应⽤层设计前端架构如何做
  本篇⽂章不会更多侧重于具体技术实现,⽽是尝试从更⾼⾓度出发,分析为什么要这么做,这些设计能解决什么问题,成本和收益如何。
⼀、综合考量
1、核⼼思想
  解决问题:前端架构的设计,应是⽤于解决已存在或者未来可能发⽣的技术问题,增加项⽬的可管理性、稳定性、可扩展性。
  ⼈效⽐:对于需要额外开发⼯作量的事务,我们在决定是否去做的时候,应该考虑到两个要素:第⼀个是花费的⼈⼒成本,第⼆个是未来可能节约的时间和⾦钱、避免的项⽬风险与资损、提⾼对业务的⽀撑能⼒以带来在业务上可衡量的更⾼的价值、以及其他价值。
  定性和定量:架构⾥设计的内容,⼀定要有是可衡量的意义的,最好是可以定量的——即可以衡量带来的收益或减少的成本,⾄少是可以定性的——即虽然⽆法⽤数字阐述收益,但我们可以明确这个是有意义的,例如增加安全性降低风险。
  数据敏感:专门写这⼀条强调数据作为依据的重要性。当我们需要说服其他部门/上级管理者,以推动我们设计的内容时,只有数据——特别是跟钱有关的数据,才是最有说服⼒的证明。
  由于篇幅所限,本⽂很难直接给出定量的值,因此建议架构设计者,先确保项⽬中设计使⽤2.7⾥的埋点系统,根据埋点系统获取的数据,对项⽬效果进⾏定量分析,并以此写成PPT和其他部门/上级管理者进⾏协调。
2、切⼊⾓度:分为基础层和应⽤层。
  基础层偏基础设施建设,与业务相关性较低。
  应⽤层更贴近⽤户,⽤于解决某⼀个问题。
  部分两个都沾边的,根据经验划分到其中⼀个。
3、由于已经谈到架构层级,因此很多内容,并不仅仅只属于前端领域,有很多内容是复合领域(前端、后端、运维、测试),因此需要负责架构的⼈,技术栈⾜够全⾯,对未来发展有⾜够的前瞻性。
  ⽂章的内容结构为:【项⽬】—>【解决的问题和带来的好处】—>【项⽬的实际意义】
⼆、基础层设计
1、⾃建Gitlab
  这个是基础的基础了。本不应该提的,不过考虑到有的公司(⼈数并不少)并没有使⽤Gitlab,因此专门提⼀下,并且使⽤这个的难度⾮常低。
  强烈建议使⽤ Gitlab 进⾏版本管理,⾃建Gitlab难度并不⼤,⽅便管理,包括代码管理、权限管理、提交⽇志查询,以及联动⼀些第三⽅插件。
  意义:公司代码是公司的重要资产,使⽤⾃建Gitlab可以有效保护公司资产。
2、版本管理
  版本管理的⼏个关键点:
发布后分⽀锁死,不可再更改:指当例如0.0.1版本成功发布后,不可再更改0.0.1分⽀上的代码,否则可能会导致版本管理混乱。
全⾃动流程发布;指应避免开发者提交后,⼿动编译打包等操作,换句话说,开发⼈员发布后,将⾃动发布到预发布/⽣产环境。开发⼈员不和相关环境直接接触。实现这个需要参考下⾯的2.3。
多版本并存;指当例如发布0.0.2版本后,0.0.1版本的代码应仍保存在线上(例如CDN),这样当出现线上bug时,⽅便快速回滚到上⼀个版本。
  意义:提⾼项⽬的可控性。
3、⾃动编译发布 Jenkins + docker
  这个⼯具⽤于在代码发布后,执⾏⼀系列流程,例如⾃动编译打包合并,然后再从Gitlab发布到CDN或者静态资源服务器。使⽤这个⼯具,可以让⼀般研发⼈员不关⼼代码传到Gitlab后会发⽣什么事情,只需要专⼼于开发就可以了。
  意义:让研发⼈员专⼼于研发,和环境、运维等事情脱钩。
4、统⼀脚⼿架
  适⽤场景:有⽐较多独⽴中⼩项⽬。好处:
可以减少开发⼈员配置脚⼿架带来的时间损耗(特殊功能可以fork脚⼿架后再⾃⾏定制);
统⼀项⽬结构,⽅便管理,也降低项⽬交接时带来的需要熟悉项⽬的时间;
⽅便统⼀技术栈,可以预先引⼊固定的组件库;
  意义:提⾼开发⼈员在多个项⽬之间的快速切换能⼒,提⾼项⽬可维护性,统⼀公司技术栈,避免因为环境不同导致奇怪的问题。
5、埋点系统
  强烈推荐前端做⾃⼰的埋点系统。这个不同于后端的⽇志系统。前端埋点系统的好处:
记录每个页⾯的访问量(⽇周⽉年的UV、PV);
记录每个功能的使⽤量;
捕捉报错情况;
图表化显⽰,⽅便给其他部门展⽰;
  埋点系统是前端⾼度介⼊业务,把握业务发展情况的⼀把利剑,通过这个系统,我们可以⽐后端更深刻的把握⽤户的习惯,以及给产品经理、运营等⼈员提供准确的数据依据。当有了数据后,前端⼈员就可以针对性的优化功能、布局、页⾯交互逻辑、⽤户使⽤流程。
  埋点系统应和业务解耦,开发⼈员使⽤时注册,然后在项⽬中引⼊。然后在埋点系统⾥查看相关数据(例如以⼩时、⽇、周、⽉、年为周期查看)
前端大文件上传解决方案  意义:数据是money,数据是公司的⽣命线,数据是最好的武器。
6、监控和报警系统
  监控和报警系统应基于埋点系统⽽建⽴,在如以下场景时:
当访问量有⽐较⼤的变化(⽐如⽇PV/UV只有之前20%以下)时,⾃动触发报警,发送邮件到相关⼈员邮箱;
⽐如报错量⼤幅度上升(⽐如200%或更⾼),则触发报警;
当⼀段时间内没有任何访问量(不符合之前的情况),则触发报警;
每过⼀段时间,⾃动汇总访问者/报错触发者的相关信息(例如系统、浏览器版本等);
  建设这个系统的好处在于,提前发现⼀些不容易发现的bug(需要埋点做的⽐较扎实)。有⼀些线上bug,因为⽤户环境特殊,导致⽆法被开发⼈员和测试⼈员发现。但其中⼀部分bug⼜因为不涉及资⾦,
并不会导致资损(因此也不会被后端的监控系统所发现),这样的bug⾮常容易影响项⽬⾥某个链路的正常使⽤。
  意义:提⾼项⽬的稳定性,提⾼对业务的把控能⼒。降低bug数,降低资损的可能性,提前发现某些功能的bug(在⼯单到来之前)。
7、安全管理
  安全管理的很难从架构设计上完全避免,但还是有⼀定解决⽅案的,常见安全问题如下:
XSS注⼊:对⽤户输⼊的内容,需要转码(⼤部分时候要server端来处理,偶尔也需要前端处理),禁⽌使⽤eval函数;
https:这个显然是必须的,好处⾮常多;
CSRF:要求server端加⼊CSRF的处理⽅法(⾄少在关键页⾯加⼊);
  意义:减少安全漏洞,避免⽤户受到损失,避免遭遇恶意攻击,增加系统的稳定性和安全性。
8、Eslint
  Eslint的好处很多,强烈推荐使⽤:
降低低级bug(例如拼写问题)出现的概率;
增加代码的可维护性,可阅读性;
硬性统⼀代码风格,团队协作起来时更轻松;
  总的来说,eslint推荐直接配置到脚⼿架之中,对我们提⾼代码的可维护性的帮助会很⼤。可以考虑在上传到gitlab时,硬性要求eslint校验,通过的才允许上传。
  意义:提⾼代码的可维护性,降低团队协作的成本。
9、灰度发布
  灰度发布是⼤型项⽬在发布时的常见⽅法,指在发布版本时,初始情况下,只允许⼩⽐例(⽐如1~5%⽐例的⽤户使⽤),若出现问题
时,可以快速回滚使⽤⽼版本,适⽤于主链路和访问量极⼤的页⾯。好处有以下⼏点:
⽣产环境⽐开发环境复杂,灰度发布时可以在⽣产环境⼩范围尝试观察新版本是否可以正常运⾏,即使
出问题,也可以控制损失。
对于⼤版本更新,可以先灰度⼀部分,观察埋点效果和⽤户反馈(即所谓的抢先试⽤版)。假如效果并不好,那么回滚到⽼版本也可以及时⽌损;
当我们需要验证某些想法或问题的时候,可以先灰度⼀部分,快速验证效果如何,然后查漏补缺或者针对性优化;
  意义:降低风险,提⾼发布灵活度。
10、Mock 平台
  Mock也是常见前端系统之⼀,⽤于解决在后端接⼝未好时,⽣成返回的数据。有很多 mock 平台,这个就不多说了。
  意义:在前后端并⾏开发时,降低沟通交流成本,⽅便开发完毕后直接对接。
11、定期备份
  备份是常被忽略的⼀件事情,但当我们遇见毁灭性场景时,缺少备份带来的损失是⾮常⼤的,常见场景:
服务器损坏,导致存在该服务器上的内容全部完蛋;
触发某致命bug或者错误操作(例如rm -f),导致⽂件和数据全部消失;
数据库出现错误操作或出现问题,导致⽤户数据、公司资产遭受严重损失;
  总的来说,没⼈想遇见这样的场景,但我们必须考虑这种极端情况的发⽣,因此需要从架构层⾯解决这个问题。常见⽅法是定期备份、多机备份、容灾系统建设等。
  意义:避免在遭遇极端场景时,给公司带来不可估量的损失。
三、应⽤层设计
1、以应⽤为单位划分前端项⽬
  在项⽬⽐较⼤的时候,将所有页⾯的前端⽂件放⼊到同⼀个代码仓库⾥,根据使⽤经验来看存在很多问题:
会极⼤的增加代码的维护难度;
项⽬会变得很丑陋;
不⽅便权限管理,容易造成页⾯误更改或代码泄密;
任何⼈都有权利改任何他能看到的页⾯(在合并代码的时候,管理⼈员并不能确定他本次修改的页⾯是否是需求⾥他应该改的页⾯);
发布成本⾼,即使改⼀个页⾯,也需要发布所有资源;
  因此,我们应该避免这种现象的发⽣,个⼈推荐以应⽤为单位进⾏开发、发布。所谓应⽤即指⼀个业务涉及到的前后端代码,好处很多:
⽅便进⾏管理,当某个业务有需求变更时,可以只给研发⼈员该业务前端应⽤的developer权限;
在需要发布某业务时,只需要发布该业务的所属应⽤即可;
  意义:规范项⽬,增加代码的安全性,降低项⽬维护成本。
2、基础组件库的建设
  这个蛮基础的,对于组件库的建设,不建议研发⼈员较少时去做这件事情,专职前端开发⼈数少于10⼈时,建议使⽤⽐较靠谱的第三⽅UI库,例如Antd,这样性价⽐更⾼。设计基础组件库的前提,是要求统⼀技术栈,这样才能最⼤化基础组件库的效益。组件库建议以使⽤以下参考标准:
使⽤ts;
可扩展性强;
适⽤程度⾼;
⽂档清楚详细;
版本隔离,⼩版本优化加功能,⼤改需要⼤版本更新;
和UI协调统⼀,要求UI交互参与进来;
  总的来说,建设起来后,利⼤于弊,但是需要专⼈维护,因此还是有⼀定成本的。
  意义:统⼀不同/相同产品线之间的风格,给⽤户更好的体验,减少单次开发中写UI组件时浪费的时间和⼈⼒,提⾼开发效率。
3、内容平台建设
  为了提⾼公司内部的沟通效率,总结经验,以及保密原因。应建设⼀个内部论坛+博客站点。其具备的好处如下:
可以记录公司的历史;
研发同学之间分享经验;
总结转载⼀些外界⽐较精品的⽂章,提⾼⼤家的眼界;
增加公司内部同学的交流,有利于公司的团队和⽂化建设;
对某些技术问题可以进⾏讨论,减少因没有达成共识带来的沟通损耗;
  众所周知,⼤型互联⽹公司通常都有这样⼀个内部论坛和博客站点。其降低了公司的沟通和交流成本,也增加了公司的技术积累。
  意义:博客增强技术积累,论坛增强公司内部沟通能⼒。
4、登录系统设计(单点登录)
  当公司内部业务线⽐较复杂但相互之间的耦合度⽐较⾼时,我们应该考虑设计添加单点登录系统。具体来说,⽤户在⼀处登录,即可以在任何页⾯访问,登出时,也同样在任何页⾯都失去登录状态。SSO的好处很多:
增强⽤户体验;
打通了不同业务系统之间的⽤户数据;
⽅便统⼀管理⽤户;
有利于引流;
降低开发系统的成本(不需要每个业务都开发⼀次登录系统和⽤户状态控制);
  总的来说,⼤中型web应⽤,SSO可以带来很多好处,缺点却很少。
  意义:⽤户体验增强,打通不同业务之间的间隔,降低开发成本和⽤户管理成本。
5、CDN
  前端资源的加载速度是衡量⽤户体验的重要指标之⼀。⽽现实中,因为种种因素,⽤户在加载页⾯资源时,会受到很多限制。因此上CDN是⾮常有意义的,好处如下:
⽤户来⾃不同地区,加⼊CDN可以使⽤户访问资源时,访问离⾃⼰⽐较近的CDN服务器,降低访问延迟;
降低服务器带宽使⽤成本;
⽀持视频、静态资源、⼤⽂件、⼩⽂件、直播等多种业务场景;
消除跨运营商造成的⽹络速度较慢的问题;
降低DDOS攻击造成的对⽹站的影响;
  CDN是⼀种⽐较成熟的技术,各⼤云平_台都有提供CDN服务,价格也不贵,因此CDN的性价⽐很⾼。
  意义:增加⽤户访问速度,降低⽹络延迟,带宽优化,减少服务器负载,增强对攻击的抵抗能⼒。
6、负载均衡
  ⽬前来看,负载均衡通常使⽤Nginx⽐较多,以前也有使⽤Apache。当遇见⼤型项⽬的时候,负载均衡和分布式⼏乎是必须的。负载均衡有以下好处:
降低单台server的压⼒,提⾼业务承载能⼒;
⽅便应对峰值流量,扩容⽅便(如举办某些活动时);
增强业务的可⽤性、扩展性、稳定性;
  负载均衡已经是蛮常见的技术了,好处不⽤多说,很容易理解。
  意义:增强业务的可⽤性、扩展性、稳定性,可以⽀持更多⽤户的访问。
7、多端共⽤⼀套接⼝
  ⽬前常见场景是⼀个业务,同时有PC页⾯和H5页⾯,由于业务是⼀样的,因此应避免同⼀个业务有多套接⼝分别适⽤于PC和H5端。因此解决⽅案如下:
后端提供的接⼝,应该同时包含PC和H5的数据(即单独对⼀个存在冗余数据);
接⼝应当稳定,即当业务变更时,应尽量采取追加数据的形式;
只有在单独⼀端需要特殊业务流程时,设计单端独有接⼝;
  多端共⽤接⼝,是减少开发⼯作量,并且提⾼业务可维护性的重要解决⽅案。
  意义:降低开发⼯作量,增强可维护性。
8、总结
  由于各个公司具体情况不同,项⽬也具有特殊性,因此以上设计不可强⾏套⼊,应根据⾃⼰公司规模、项⽬进展、⼈员数量等,先添加⽐较重要的功能和设计。并需要考虑到长期项⽬的可维护性和发展需要,对部分基础设施进⾏提前研发设计。