一个直播项目的年度总结(设计-开发-重构)

1,527 阅读39分钟

温故而知新,学习是如此的,一年下来看了几本书,回忆一下却是记不得了许多。记忆是短暂的,哪怕高中的知识当时记得再怎么清楚,现在也是忘却了。留下一些文字,笔记也是对那份岁月最好的痕迹了。青葱岁月,如白驹过隙,一年工作下来有留下了什么呢?谨以此文,纪念我在云学堂的工作一周年。

最后感谢我的老婆,替我承担了很多琐事,使得我在假期中有这份闲暇去写下这寥寥数笔。

前言

学习是痛苦的,工作也是,有时候往往不仅仅是痛苦,也有委屈,也有焦急。过程是漫长,紧凑,激烈的,回想这一年,有时候跟同事废寝忘食的讨论,下午很晚才吃晚饭,有时候跟同事讨论回放流程,有时候跟同事讨论数据结构。有时候跟同事通宵加班发布。当然还有同事去纠结一个细节的实现。当然还有产品还有其他同事。回想起来一定是充实的一年,开心的一年,压力很大的一年。文笔总有些稚嫩和干瘪,写不出那并肩作战的气氛,热火朝天的感觉。这一年谢谢各位同事一起走过风风雨雨。没那么夸张却是真情流露。

在这一年里有一些人难以忘记,有些事也难以忘怀,从头开始搭建项目,走上正轨,疾步前行,大厦将倾,拨乱反正,负重前行。每个阶段,每件事都是那么深刻,因为事情复杂,技术才复杂,正因为如此才能有不一样的产品体验。

文字表述总有些苍白,下面我希望用这一笔写下这一年的深刻而有趣的回忆,对青春的致敬,对工作的总结。

技术分享是枯燥的,学习也是枯燥的,我就以这一年直播项目里真实的开发经历,项目管理的实践为例,希望大家包括我自己能够有一些收获。一家之言,难登大雅之堂,用那份初心,来写一写我心中的年度技术总结报告。

目录

  • 第一章 直播工具

    • 我们做了一个什么样的直播工具
    • 解决什么核心的问题
  • 第二章 敏捷开发

    • 什么是敏捷开发
    • 什么我心中的敏捷开发
  • 第三章 架构师

    • 架构师导论

      表达力

      协同力

    • 架构师职责

      功能需求

      质量属性

      技术负债

    • 架构师执行过程

      设计

      开发

      重构

  • 第四章 敏捷开发与架构师的最佳实践

  • 致谢

第一章 直播工具

我们做了一个什么样的直播工具

在企业直播培训场景下面,我们使用了electron,web基于声网的音视频能力,融云的信令能力,微演示的PPT解析与展示能力,再基于业务的场景上面添加了习题,签到,画笔,OMO(线上线下)教学模式,除此之外对于还有连麦,嘉宾讲课这样更深度的师生互动场景,具有这些能力和场景构达到了企业培训的目的,以及线上培训场景的支持。

image.png

解决什么核心的问题

我记得我很早的时候问过同事我们这个直播工具和钉钉相比,有什么优势?钉钉的体量,体验,技术水平肯定是高于我们的。当时常青的回答是,钉钉对于并发,客户服务,场景衔接上面这些方面是不如我们的。

经过这一年,我有了自己的一些想法,这些想法也一直在变化,技术的原创性和稳定性其实我们是远远不行的,这是我作为技术人最敏锐的感知。说白了我们所有核心的能力都是借助于第三方实现的,在技术角度考虑我们是一个需求的粘贴怪。当然在了解团队人员的背景之后,我开始是佩服的,确实核心团队之前从零到有构建过这样的一个系统,我觉得是牛逼的,这是第一次转变。

第二次转变来自于业务的复杂度技术的复杂度进入到一个成熟期,很多设计,方案,实现在整体的判断上面是出现问题的,我们明显感到,下半年迫不得己的技术重构以及多次打断的重构以及一些深水区问题,已经感到了迷茫。需求的压力与技术瓶颈是明显的爆发期。

第三次转变还是来自商业和客户的转变,之前我也是做的ToB的场景,销售强,技术就不那么重要吗?我们是不是应该把整体的重心放在稳定性和功能多样性上面,这才是价值的本质。

场景是固然存在的,企业肯定是从线下转入线上的,不管疫情有没有加快这个趋势。社会的发展是必然是效率的体现。以前一骑红尘妃子笑,无人知是荔枝来,现在啥时候都能吃到荔枝。交通效率,农业效率提升就是社会的进步的体现。企业效率的提升必然是在沟通效率,执行效率上面的提升,不去拥抱变化的企业必然是走向消亡的。恒大,华为,小米为啥去造车,虽然行为看上去很幼稚很low,但至少拥抱了变化。固有的方式,固有的渠道,固有的产品,都是会被这个时代抛弃。唯有不变的就是变化本身。

第二章 敏捷开发

什么是敏捷开发

刚来团队时候我是懵逼的,不管怎么样反正都是上班嘛,跟着做吧,这是我的第一感受。建立sprint,拆分stroy,定ower,每日晨会,交付测试,迭代上线,迭代总结会,把这些流程跑会了,我以为的敏捷开发是这样的。随着团队的扩大,项目业务的复杂,我们失控了,质量项目周期我们都把控不住了,持续的需要通过加班去偿还业务压力。我们的解决方案加入更多的流程,加入更多的管理人员,砍掉更多的需求。表面是这样的,这是敏捷吗?所有敏捷是什么?

加班就是敏捷开发吗?不是。流程清晰是敏捷吗?不是。砍需求是敏捷吗?不是。

敏捷开发是一种思想,需要一套敏捷流程,以最短的时间,完成客户最重要的需求。

什么我心中的敏捷开发

当事情流于文字和规范,就会变成一种玄学,是不是学了PMP,我们就一定会项目管理了吗?学当然有用,我们是否一定要关注各种启动,交付的过程,关注各种时间,成本的管理?答案是否定的。读万卷书行万里路,纸上得来终觉浅,绝知此事要躬行。技术代码需要实践,管理也是如此。

每个人都喜欢被动接受,主动提问的很少!敏捷的核心是时间有限,用户的场景为先。

首先当任务安排过来的时候,我们想目录放左边,放右边,做呗,动画,弹窗做呗!从工作安排的角度是没有问题的,但行为认知上面就有很大问题。UI的改动带来的价值是什么?在有限的时间和人员的基础上面,我们关注的重点是什么?我们把按钮做什么样子,把弹窗做成什么样子?重要吗?在这么紧张的资源前提下面?

第二动态安排,计划变化,延期,我们往往想的是流程,通知,延期,没人问为什么要上?为什么要延期?为什么今天要?没人问为什么就最大的问题?

第三技术负债管理失控。

总结一下,现在就是没有价值判断,没有好奇追问,没有问题管理。

我心中的敏捷是什么样的?我认同敏捷是一种思想,是一种快速迭代的方式,是关注最核心价值,需要固有的流程保证我们敏捷的管理,跟需要的是敏捷的思想,以及与对应的工作流。

第一步不管是时间节点还是重要需求首先应该制定第一原则时间还是需求,这个大需求一定要上就配合这个需求安排时间,这个时间一定要上线就安排这么多工作量,这么多资源,哪些做,哪些不做。做的再评级。

第二步拥抱变化发布与平台需求明显对当前迭代有影响,就应该拥抱这种变化,而不是一直延期,迟迟不做决断。

第三信任团队,认同团队,认同敏捷,开发测试产品最小意见一致即可执行。

第四管理技术负债。

第五开心工作,开心生活,敏捷的最终状态肯定是8个小时内,最高效的决策与最高效的开发方式。

第三章 架构师

架构师导论

我相信很少会有人认真读到这里,原因是什么呢?文字是枯燥的,学习是痛苦的。那工作能这样草草了事吗?如果把阅读所有人工作总结变成一份大家必须去完成的工作,相信这样的工作效果是不尽如人意的。

我之前可能会说,跟我没有关系,我文档都写好了,别人不看,肯定是别人的责任。其实是错了,其实是我的问题,我表达的不够有趣,或者我的文字不能给别人带来收获,显然这是失败的案例。

如果我是这个阅读项目的架构师,我应该怎么去做呢?架构师的核心能力是什么呢?架构师应该是什么样子的?

架构师需要对功能需求,质量属性,技术负债负责。架构师应该思考问题,理解需求,设计架构,评估结果,编写文档、核心代码与算法实现,这些对吗,对也不全对。架构师最关键的能力,我个人觉得是表达力和协同力,其他都是架构师的具体工作内容。

表达力

表达力可以体现到表达准确度以及表达方式这两个方面。

表达准确度

比如大家都在过年,除夕当天各地的习俗不同,有些地方年夜饭是中午,有些地方年夜饭是晚上,但是就年夜饭这一个词就存在着表达准确度的问题,明明是年夜饭为什么夜里的饭是中午吃,是不是很奇怪。很多人会有疑问这是很大的问题吗?在团队协作的时候就是很大的问题。

表达工具:文字总是苍白无力的,正如我现在这样使用这样的方式,我自己看了都会犯困。合适的表达工具不仅仅是提升兴趣,说明情况,更是设计层面最不可或缺的部分。例如我之前开发的OMO中,PPT投屏的方案,在技术选型时使用苍白的文字,参会者看了也就看了,没有一目了然的感觉。如果换成表图的形式再对比一下效果。

表达工具

举例

截图方案

使用截图的方式,使用定时器定时截取视频容器里面的画面转成图片,通过ipc传输到另一个窗口渲染(icp的封装不在这次分享之内)技术是可行的。

问题是:传输的次数太过频繁,会造成客户端卡死的情况。传输数据很大,图片转成base64之后数据量很大,这样数据进行不适合进行本地通信。扩展性差,当前是一个视频是可以完成传输的,如果是多个视频的场景,无疑性能是有极大的问题。

远程流媒体服务

不管是自建流媒体服务或者使用第三方的流媒体服务,都可以实现本地视频流或者多个视频流上传,然后在另个窗口订阅这些视频流,性能上面试绝对没有问题的,实现也很简单。

问题是:体验不好,会有延迟性,明明是本地的视频,非要上传,再下载,受带宽影响就会出现延迟性。经济费用:自建服务器和第三方服务都会带来经济成本。

webrtc视频传输

高性能,低延迟,无费用,这其实才是我们真正想要的。

上面这段文字表达没啥毛病,可是参与技术评审的人,怎么根据这些文字做选择呢?合适的表达工具是架构师基本的技能之一,如果我换一种方式呢?

常见图表工具
图表

选择哪个omo投屏方案

方案/特点截图第三方服务(声网)webrtc
性能
延迟
费用

看了这表格之后我相信产品,测试,后端,项目经理都是清晰的。架构师不仅仅是写出这个表格内容(技术预演和判断),更重要的是使用表格这样的形式让所有的参与者明白。

时序图

涉及多方调用的场景,可以采用时序图表明关系与流程,下面就是一个回放数据流程的设计,可以看到调用是清晰的,关系是明确的,但是有个很明显的问题就是没有使用图标,解释性不强,如果光看这个图其实也是有点懵逼的,最好添加图标说明,这样协同的同学看图即可明白。

sequenceDiagram
客户端->>客户端: 异步请求队列控制
客户端->>服务端: 发送操作数据
服务端-->>客户端: 响应成功
服务端->>MQ: 数据发送给MQ(异步,解耦,并发)
MQ-->>服务端: 订阅消息
服务端-)阿里云: 操作数据追加写入oss
类图

类图是在面向对象的表达力上面是有很强体现的,对象的方法,属性,以及对象之间继承关系。是定义代码场景下面一种最常见的表达方式,在前端面向对象的设计中可以使用。

关系图

例如我们现在的部门系统内,有产品、测试、前端、后端、app、ui、项目经理、平台人员这些角色,这些角色之间的关系是怎么样的,有时候为什么出现混乱情况,是不是关系没有梳理清楚。

其他图表

其他还有很多例如协作卡片、概念图、流程图、模块图等等,为啥不说了呢?没学好,也没用好,这是我学习的一个方向,这也是同事那天问我的问题,我自己就应该好好总结。例如直播微课如果用图,应该怎么表示呢?是不是真的有人去思考这个问题?

一个合适的图表重要吗?

选择一个图表去更好的阐述你的观点,你的设计,你的理念,重要吗?很重要,工欲善其事必先利其器,如果每个人都是按照自己的方式去工作,那肯定不是最高效的,如果不是存在高效率的场景,那人员就是没有意义的,部门就是没有意义的,产品就是没有意义的。应该逆水行舟不进则退,不能学习新的技能与能力,终将被淘汰。哈哈开玩笑的夸张了,但是做任何事还是应该精益求精,对自己有要求,有成长。

有时候思考一个问题和梳理图表是很有意义的一件事情,为什么大家经常讲产品自己都没有想清楚?这个就是现实的问题,主流程是开始直播,结束直播,子流程呢?子流程里面有开始签到,结束签到,开始推流,结束推流,如果有个完整详细的设计图,我相信大家每次看到这个图,肯定会想到,我这个子流程里面对主流程的影响,主流程变化也会对子流程会有什么影响。每一次的迭代开始,首先应该都是去设计和梳理关系。为什么没有?因为没有思考,没有传递,没有驱动。也许那一张主图在大家心中,但更应该在文档的第一页。

认知基础

比如上一个稳定版本的这个说法?在工具产品内部的认知范围内就是上一个发布版本的代码,即master分支,但是APP团队的分支管理里面,代码测试完成就已经合并进入了mater分支等待发布,而不是我们这边的发布当天合并进入master的。大家都基于这个mater去做私有化发布就有问题。因为这个APP的包已经带入新的特性,而工具产品这边的代码还是旧的版本,这怎么能对应上呢?这个就是架构师的失误,为什么公司的基础认知都能不一致?

通用名词

不要创立新的名词,其实在我们的业务中有很多顺序任务执行,例如有序的信令,有序的聊天顺序,渲染顺序。当和其他端安卓,IOS如果用统一的名词使用例如队列这样名词,这样大家是统一认知的。可是如果跟非开发人员说队列这个名词就是有些不通用了。

不要扩散概念

当你以为的你以为不是你以为的时候是很痛苦的。例如灰度发布,在我的认知范围内就是流量的分离,提升上线体验,做一些产品的AB测试。可是甬道,beta alpha 这样的名词附加在上,对于新人来说或者对于刚接触的人来是有心智负担的。

表达方式有效度

其实表达方式有很多种,例如会议,文档,培训等等。在一个体系里面最好的方式,我觉得应该是两种,一种是事无巨细所有人全知道,一种具体细节全不知道。

传达度

灰度实施是必然的,很多灰度的讨论很多小伙伴都没有参加,新有的名词,新有的场景,大家都不能够很好的理解,其实很多理论概念没有落实到一线,这个表达其实就是无效的。集群的场景,这样耦合度极高的方案我认为也是失败的。说实话前端关心吗?需要前端关心吗?流量分配到哪里跟前端有什么关系?这个就是没有充分讨论,大家没有好奇之心,意见没有向上的通道。表达如何实施,却无法令人理解!

规范统一

部署tag方案,也是奇怪,发布人员需要关心tag,tag的版本?表达不规范。前后端的hotfix理解不一致,app端节奏与当前团队不一致。表达不统一,各自为政。

这些所有细节都了解对于一个公司是需要多大的成本?其实最优的模型,应该是开发不需要关注任何运维的细节这两部分应该是解耦的(学习运维知识除外)。为什么是现在这样的局面,每个人需要关注环境,关注集群,关注tag,关注jekins里面的项目?

选择好的表达方式

表达方式有问题,要么最low的方式应该有完整的新人培训去了解这个知识,要么讨论全员参加,要么用工具去磨平。

其实最好的表达方式应该是没有表达,会心一笑才是最高境界,可是现实生活和工作中当面聊都能聊差了,更好的应该是公司从上而下,从左往右所有部门的表达要到位,统一,规范。

协同力

一个好的架构设计出来了,接着上面的案例,公司内部的灰度方案。怎么去落实方案,监督方案,一个架构师很好的设计了流程图,调用逻辑,接口定义,怎么去驱动协同人力丝毫不差的完成。

永远不用松懈直到最后一刻。讨论有文档,设计有概要和详细,开发有工期规划,验收要标准,整个链路,所有端都要清晰明了,直到上线成功。

驱动他人是很难的,例如我参与的IM加固的事情。首先得理念的团队宣导和认同,大家认同为什么要加固?为什么要有序?到方案的宣讲,再到具体的实施验证。就算一个人的水平很高,技术点很全面,所有的事情还是要团队去执行,怎么能保证每一端的代码实践是你的设计方案呢?针对结果验证其实只是验证的一方面,所有流程全渗透,你就要去协同所有人,达到你想要的目标。

架构师职责

定义问题,定义场景,解决问题,适配场景,解决的过程中出现了新的问题,新的场景,再继续循环。这是一个良性上升的过程,每个时间往后看都不是最优解,但是也是BB机到大哥大到键盘型智能手机再到触摸屏智能手机的过程。螺旋上升是一个产品,一个国家,一个社会总体发展的趋势。如果不是必然面临淘汰和瓦解,产生新的产品,新的社会制度。

功能需求

人人都是产品经理这句话也算是深入人心的,产品经理工作职责之一就是输出需求。是不是输出需求的就是产品经理呢?每个人都有痛点有痒点,不是因为一个点就产生了一个需求。

评估价值

一个点怎么变成一个需求,这个过程是需要评估的?考虑客户价值,区分时间段,考虑数据支撑。一个炫酷的动画效果,感官肯定是愉悦的,作为一个工具产品的初期他没有功能重要,中期没有稳定性重要,总结而言有一点价值,但是完成不重要,所以他不能成为一个好的需求,是个分散资源的需求。

需求可以来自于销售,客户成功,需求本身有价值,可能是一个需求点也可能是一个痒点。但是我们应该依赖数据,使用率,使用场景,客户是上帝我认同,这是大B场景下面不可回避的一部分,更好的引导客户其实也很重要,除非万不得已,没有数据支撑,没有价值认同,但是有客户收入,但是我认为这是最后才能触发的条款,而不是一来就使用的权利。

一个好的架构师应该评估价值,一个UI放这边,放那边重要吗?在这个稳定性还没有达到的时间段是没有意义的,随着稳定性的变化,产品需求都会发生变化,为什么要花时间人员在UI上面?如果这个产品很稳定了,没有什么线上问题了,这样的前提下,标准UI,提升交互。我认为那是一个好的时机。可是产品直播需要保证,问题需要解决,为什么因为细枝末节而沉醉于细枝末节。因为反驳而沉醉于反驳,这是一个好的设计评审时需要的角色,但是最后大家一定要有共识。每个人都有不同价值观,开始时应该拉通的是团队价值,而不是妄动开发。

场景很重要

正如iphone使用屏幕代替键盘之后,使用滑动解锁来防止误操作,导致屏幕打开进行一些错误输入等等。这是一个很重要的场景下的一个方案。

接受不完美

虽然滑动解锁解决了很多误操作,但是依然会有不小心的概率出现,我自己就出现手机在口袋里,误操作了,或者是多次输出密码,导致我不能正常使用。完美是都是大家的目标,但是不完美确实长期存在的。电车取代油车看似现在是个趋势,但是电车的快充问题,低温环境问题,都是不完美的存在,甚至不完美到大家很痛苦。但是依然阻挡不了电车的上市销售。我相信电车的产品不会说,没有充电桩咋办呢,充电很慢咋办呢,低温下使用感不好咋办呢?不上线吧?那不是扯犊子吗?如果不上线永远不知道更大的问题在哪里,如果就因为一个小小的瑕疵就不上线?开发的时代也在变化,我们去评估bug,去正常的看待bug,不是说有bug不能上,而是这个需求本身的价值是不是很炫酷。这才是我们关心的重点,关注bug,容忍bug,大家共同决策,这是向好的生态。当然bug不是不处理,在下面很重要的章节去说明这一点。

质量属性

一个项目是否能正在运行与持续发展其实是来自他的质量属性。很明显的一个例子就是我们问题反馈群里面一直在反馈问题,显而易见我们的质量不行。质量属性细致划分为可用性,性能,可扩展性,安全性等等。

高可用

高可用绝对是我们最常见的名词,这一目标不仅仅是前端,后端,运维都是要努力实现和推进的一件事。有时候我们可以看到群里说,直播不能用了,老师不切PPT了,老师说话听不到了,签到学生没有结束,回放看不了。这些明显就是我们现在代码,服务,第三方,中间件存在某些问题。

代码问题:例如现在的结束签到,有些学员收不到。这就是一个不可用的场景,我们常见的信令方案都是对其进行保障,使用推拉两种方式保证消息的到达。定时向直播间推送最新状态,学员定时在直播间拉取最新状态。

并发问题:常常服务端和前端的轮询方案会对服务器产生很大的压力。服务端标准的熔断限流会保证服务端的稳定性,但是在这一基础上面会出现用户使用的不稳定性,一些用户的请求没有被正常处理。并发处理的方式,当前我们处理的方式是把压力转交给了阿里云,将数据写入阿里云,这样并发的压力就不在我们服务端本身了。其实在各种语言里面都是有多线程的方案,去处理各个高并发场景的解决方案,数据流转和通信各有不同,nodejs使用message传递,golang里面使用channle。有些语言并发的使用的资源小,可以极大的降低服务器成本。还有一些中间件的方式,类似这样常用的mq最大的一个特点就是削峰。总结一下:并发处理方式有下面几种:使用轮询的方式可以加入随机数的模型,这样可能在一定概率上面减少并发压力;转交能力给其他服务商例如阿里云本身这样专业服务商;更换语言;更换实现方案使用中间件。

第三方问题:今年的最大感悟是对于第三方的依赖,首先第三方成熟的技术完善的sdk,专业的团队,这是不得不承认的。但是第三方给我们也造成了很多困扰,例如不稳定的融云,存在信令丢失的问题,我们这边就需要对他的基础服务进行强化;不确定的声网,音视频问题的传输,渲染问题非常的头痛;PPT的解析问题,解析不对,使用不对等等。这些第三方问题,最大的解决方案要么约束使用,比如告警说明,PPT不能使用复杂的字体;要么告警提示,当前某某功能异常;要么提示使用场景这个场景可能遇到的问题建议,cpu过高时关闭其他程序,减少分享屏幕,PPT使用常规的字体。解不了的问题就是解决不了,但是要给出诚恳的建议和指导。连载入航天这么机密的事情,也不是用尿不湿解决生理问题,而不是花很多时间和精力涉及很复杂的工程去建一个厕所,至少在那个场景下,载人航天是有突破意义的,而不是让一个尿不湿去阻挠前进的路。

可扩展

预见有限时间内的扩展,项目初期不可能说设计和支持一个10万人并发在线的系统,但是得考虑。技术的预见性和产品的预见性是我们今年犯的最大的一个失误和判断。多端直播的问题确实带了很大的难题,之前的方案全是客户端中心化的实现基础。短平快的完成任务造成了很多技术负债。众多sdk的熟悉程度,升级方案,实现方案,确实一步一步的探索,这如果是一个初创团队,可以理解一部分,如果是个经验团队我相信这不是一个好的表现。如果以后来的角度来看待这个问题,web直播或者和app的交互方式再前期众多不确定性的前提下,我会选择纯web直播以及纯内嵌h5,体验可能是下降点客户感知度与长期的项目迭代规划优化这条路的话,我相信纯web的效果是最佳的技术方案。

这也是我表达扩展性的核心思想,扩展性是基于快速的试错和升级基础的,上来没想清楚就上的话,带来了巨大的扩展性的风险。现在由于桌面客户端和app存在,升级机制的现在,可扩展性的实现基本很难了,变化来临的时候不能拥抱变化,这是我们现在最大的问题之一。api想升级,功能想升级,app突然发布,很痛苦。

性能

其实有时候有些关系其实是一个多元关系,相互影响的。例如我做的回放数据的方案,在小数据量的前提下面依据状态去回溯结果是最快的表现,减少了计算的压力的,减少了卡顿的体验;在大数据前提下,这样的方案就是灾难性的后果。资源很大,请求很慢,处理复杂,这个我是承认的。但是如果我在压缩性能 和压缩方案上面开始就使用了比较好的方式,那么虽然我的数据方案是有问题的,但在压缩性能的保障下面,也许很难触发我的数据量过大的风险。不可能每个点都是最优的,但是每个带来的相互提升其实是很好的结果。这是我后面开发设计的需要注意的,多点的提升而不是集中在一点。

安全性

安全性其实是很重要的场景,正如我之前的数据库被攻击,然后要挟我要我给0.002比特币,我也意识到安全的重要性。这是我个人项目的场景。除此之外企业场景下面数据加密机密也是常见的述求,除了客户数据安全性的要求外,还有竞争对手的数据接口爬取的风险。加密等级,防爬策略,都是相互的,看哪一方投入较多了,是个长期斗争的过程。不管安全性的实现具体方案如何,我相信无侵入式的方案才是最佳的实践,无论采取哪一种加密算法,对于项目本身不应该关注这些,开发时无影响,上线后起作用,配合自定义工具进行调试和定位问题,这是我个人的见解和感悟。数据库安全的话也是要注意的,用户密码不能太简单。数据库数据本身的备份与恢复。在一个完整项目里面都是要注意的,之前就是太轻视了,开源项目也要注意数据安全。

技术负债

技术负债是在快速迭代过程中遗留的技术瑕疵。例如直播过程中有很多画笔数据,在切换PPT,客户端重启之后需要做恢复。之前的方案是把画笔数据存储在本地,这个显然是有问题的,如果切换设备,或者以后想要支持多场景切换直播,将会面临数据无法迁移恢复的问题。除此之外,在迭代过程中到deadline时间点时依然无法解决的bug,或者一些很难复现的bug,对于上线是存在一定风险的。技术负债是需要管理和处理的。

方案型

如果是设计方案问题这是最头痛的问题,一个项目的基础方案决定了后期的可维护性,可扩展性,正如我之前的设计是以客户端中心化的设计原则,所有数据,信令逻辑都是维护在客户端本身,但是本身客户端崩溃问题,以及多端通用性上面有着极大的设计缺陷。如果没有关注这一点是存在极大的问题的,这类问题应该立即有限处理,否则链路会越来越多,越来越长,对于项目本身是存在致命风险的。

BUG型

在敏捷开发的前提下面,带着bug上线我觉得是正常的,如果关心的核心价值和项目迭代速度本身,存在一些bug,我本人也是认为ok的。不管怎么说,又快又好应该是一个不可实现的状态,我们永远是趋同这个状态过程。个人还是认同将bug分级,优先级高的就应该并入下一次迭代需求之中或者下一次的hotfix之中。敏捷永远是8小时的敏捷,如果不认同这一点,那敏捷是没有任何意义可言的。我们就是要清晰认识到资源本身的稀缺性,我们每天都要做决策,按照优先级去迭代,这样才是良性的循环。我对此深信不疑,我也相信我的相信,这才是团队,才是敏捷,所有的决策,应该基于信任,判断,长期主义。

第三方

第三方的bug以及能力的问题是我们今年最大的瓶颈。接受不完美依然是我们的主题,这是我的普遍价值。但是今年出现了多次应该第三方在某些场景下面的bug问题或者能力问题导致了,我们需求未上线。我觉得其实存在价值失衡的地方,如果h5在某些场景下面会出现音视频问题,我个人是觉得是可以接受的,或者其他类似合流录制这样的能力出现问题。上线是存在问题风险的,但我不认为这是不上线的理由。所有的判断没有客户价值依据,没有数据支撑,没有集中讨论,我觉得还是走错了方向。价值来自于客户反馈,数据支撑,什么都没有的情况,判断是毫无意义的,这是我们很多软件错误的方向,不管是产品决策,领导决策其实都是毫无依据的。我总感觉大家有下意识的不上线就没有问题的侥幸心理。为什么不能把带给客户价值为第一考虑项?

架构师执行过程

设计

任何事情的发展,或者想要做好,我觉得充分的讨论和详细的设计是必不可少的。设计时间和开发时间比重是十分重要的,缩短设计时间不一定会减少整个迭代的周期,有时候反而拉长整个项目的周期。

设计永远不是创造一个从来没有的东西,大部分设计应该都是基于现有的技术或者方案进行调整和优化。正如我们应该借鉴vscode来做客户端设计,我们应该借助知名的UI库做我们自己库设计。所有的设计不应该从无到有,而是一个从有到优的过程。很多业务上的设计偏弱的原因,个人感受还是数据结构和算法这方面存在欠缺的地方,如果这些地方有补强的话,我相信业务能做更好一点的设计。

设计原则

设计原则有常见的六大原则。我这里简述一些常见使用方式和应用场景。

单一职责

单一职责见名知意,每个模块,每个函数职责应该是单一的,一个方法只做一件事,这样代码的阅读性和可维护性是很高的,最害怕的是一个方法中做了N件事。如果方法内存在多种判断这执行不同的分支,可以使用策略模式进一步拆分。前端分离的场景其实也可以认为是一种单一职责的场景体现。

开闭原则

开闭原则,对扩展开发,对修复关闭,这是项目演进过程中最应该注意的原则,不要动屎山,除非你要整个模块的重构,要么你就开一条新路绕过这座山。在维护得不怎么样的项目中这是最重要的原则。

最少知识原则

这也是我今年最大的痛苦之一,公司需要支持双集群跟前端有什么关系?公司要支持灰度跟前端有什么关系?公司要打tag跟前端有什么关系?每一个参与的人都是全部了解前因后果,这个是多么痛苦的事情,这个方案设计就存在着巨大的问题。如果是我设计双集群的方案,前端一定是不受影响的,我为何要关心是腾讯集群,阿里集群,最low做法可以是在阿里或者腾讯的ng里面再加一层代理或者其他一万种的方案,跟前端项目有什么关系?公司灰度发布要打tag,要有tag规范,为什么?为什么前端开发要关心这个?前端管理人员只要保证代码经过测试审核进入master分支,至于发布到哪里?怎么发布跟前端有什么关系?如果说之前的2.0方案是就是有问题的,只能用这样的方式做,我觉得这也是不合理的,这是公司最基础的技术建设,为什么要用很差这样的方式?公司的根基使用差的基石,然后再往上搭建,应该是最危险的事情没有之一了。

设计模式

单例模式

这是其实是在项目中是比较容易使用,也是代码健壮性的中不可或缺的一部分。假设我在项目中要使用一个全局的数据收集系统,其实从健壮性的角度而言,这个数据采集有且只能有一个,不能重复实例化多次。这是自己平时没有注意,其实在全局性的声明功能和能力的时候都应该注意且使用这样的单例模式以保障,不会出现重复调用实例化。

装饰器模式

装饰器模式确实也是我们常用的一种方式,在angular中是最常见的使用方式,主要使用在行为扩展方面。如果可以简单定义一个场景的话,类似定义一个dog的class,定义一个bark犬吠的方法,不仅仅希望它叫,还希望它在叫的时候咬人。这样的场景可能是装饰器的一种现实表述。但更真实的场景可以是组件的通用能力上面附加功能可以使用装饰器的形式。或者面向切片的思想,例如行为日志这样的设计也是可以使用装饰器的。

观察者模式与订阅发布

这是两个都是一个系统里面解耦处理的一种场景方式。当依赖发生变化时候,自己就会触发行为。如果以结构来分辨模式,发布订阅模式相比观察者模式多了一个中间件订阅器,所以发布订阅模式是不同于观察者模式的;如果以意图来分辨模式,他们都是实现了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知,并自动更新,那么他们就是同一种模式,发布订阅模式是在观察者模式的基础上做的优化升级。当前项目中有多处使用,在各个模块中作为数据通信的一种方式在使用。

image.png

设计评审会

如何开一个好的评审会?有以下几点需要注意:

会前准备

第一开会前的充分准备,不能开无准备的会议,这是很多场景的痛苦,就为了开会而开会。

利益相关

第二需要多种身份,每一个利益相关方都需要参与,会议中主持人的身份很重要,需要控制节奏,已经最好保证会议结论与执行。

积极调动

第三会议者可以是有反驳者,有支持者,一定要有参与和讨论,当其他人员心思或者状态不对时,主持人要唤起大家的参与的兴趣与积极度。

把控节奏

第四有限讨论,在方案陈述时一定要保证陈述人员的完整陈述,主持人一定要控制好,每个阶段方案宣讲,自由讨论,后续补充,执行计划,最后提高会议效率。

开发

开发就是设计的执行

一定要保证,开发是与设计一致的,如果不是那就是天大的问题了,大家前面的准备很可能功亏一篑。

重构的同行

开发的过程也是重构的过程,开发过程可以重构,重构也是开发的一部分。

重构

原则

重构的原则就是在不改变软件外观的前提下,使得代码更有维护性和扩展性。正如我们现在做的服务端中心化的重构其实应该很少的改变数据结构与含义,尽量保证回放数据,信令与之前保持一致。重构和性能优化基本是一致的都是最好不要改变外在表现的前提下,一个提升代码可维护性,理解性,可修改性。一个是提升速度。重构原则上是不能让用户和其他程序员有感知的。(这一点我们做的不好)

痛苦的回忆

不管我上一家公司还在现在的公司,都会出现1.0版本和2.0版本。两个版本完全不同,前端不同,后端库表全部不同,业务也发生了变化,我至今也有疑惑?是应该这样做吗?就算以前的架构再怎么差,不也是前后端安装模块去切割成微服务然后再按照模块依次升级吗?业务上不同客户当真没有意见?1.0与2.0天差地别的开发怎么去磨平?我是很奇怪做出这个决定的?angular不如react就这样把一个几年的项目从0开始重构?这是不是有点奇怪?

第四章 敏捷开发与架构师的最佳实践

敏捷开发应该是关注价值,允许技术负债与线上bug的,架构师应该是引领整个团队向前进的一个角色,在敏捷的过程讨论价值本身大于开发,每个小伙伴基于信任,激情,讨论,接收他人观点,自驱成长。每一天都应该是更好的自己,更好的项目价值。

致谢

首先感谢我老婆的支持,在春节这样有些繁忙的日子里帮我完成了这些枯燥的文字阅读与校验。再者感谢所有同事,这一年是大家的付出和经历,我只是侥幸有时间,写下这样的总结和感悟。最后感谢两本书籍,一本书是架构师修炼之道,一本书是重构。最后祝大家新年快乐,虎年大吉。