面試官:工作中處理過(guò)什么復(fù)雜的前端需求,如何解決的?
聊一聊當(dāng)下發(fā)生的事情吧。疫情期間大家都在享受延長(zhǎng)假期的福利,吐槽在家辦公的不爽,而我們則從過(guò)年開(kāi)始就一直在戰(zhàn)斗,到現(xiàn)在還沒(méi)有好好休息過(guò)。
先說(shuō)背景,我目前在騰訊IMWeb團(tuán)隊(duì),負(fù)責(zé)在線教育騰訊課堂的前端研發(fā)。
都說(shuō)疫情期間在線教育是風(fēng)口,我想說(shuō),打的贏扛得住也許是機(jī)遇,打不贏完全是炮灰。
1.先說(shuō)流量
從春節(jié)假期到現(xiàn)在,我們?cè)庥隽饲八从械牧髁糠逯?,雖然具體數(shù)字不方便透露,但是可以預(yù)想得到,那么多所學(xué)校在期間強(qiáng)制網(wǎng)絡(luò)上課,學(xué)生加老師的數(shù)量是多么龐大。
如果說(shuō)雙十一是所有具有消費(fèi)能力和沖動(dòng)的人群沖擊,那么這一次則是所有學(xué)生和老師的強(qiáng)制訪問(wèn),訪問(wèn)者沒(méi)有選擇權(quán),這是最可怕的一點(diǎn)。比雙十一更可怕的是,我們沒(méi)有時(shí)間準(zhǔn)備,雙十一也許可以提前幾個(gè)月甚至半年開(kāi)始謀劃,這次的流量則完全是毫無(wú)預(yù)兆的突發(fā)性事件,要求我們?cè)诙虝r(shí)間內(nèi)必須做出快速的決策響應(yīng)。
截止現(xiàn)在,流量高峰已經(jīng)沖擊三波了,每一次都是幾倍的增長(zhǎng),流量逐漸平穩(wěn),也讓我能夠偷閑刷一刷知乎。。
1.1 前端考驗(yàn)一——主域
對(duì)于前端而言,最大的影響莫過(guò)于主域,一旦我們的主域扛不住,html都打不開(kāi)了,整個(gè)全玩完。
在我們團(tuán)隊(duì),主域的Nginx主要是由前端負(fù)責(zé)管理,在騰訊的運(yùn)維體系下,STGW在下一層統(tǒng)統(tǒng)是交由業(yè)務(wù)來(lái)維護(hù),運(yùn)維同學(xué)完全不了解業(yè)務(wù)是如何發(fā)布和控制的。從某種程度來(lái)說(shuō),我們才是真正的DevOps,夸張一點(diǎn)說(shuō),運(yùn)維同學(xué)與我們打交道也許僅限于機(jī)器申領(lǐng)與容量。
除了承載核心HTML入口,主域還承接了CDN的降級(jí)策略,防止某處運(yùn)營(yíng)商等問(wèn)題直接導(dǎo)致CDN無(wú)響應(yīng),之前的教訓(xùn)讓我們做了這層容災(zāi)。所以主域的穩(wěn)定性至關(guān)重要。
所幸這里僅僅是靜態(tài)渲染,抗住高并發(fā)不是太難的事情,不過(guò)Nginx對(duì)于前端的能力提出了更高的要求,對(duì)于Nginx的改動(dòng),有著嚴(yán)格的流程把控,務(wù)必做好充分的驗(yàn)證。
1.2 前端考驗(yàn)二——音視頻直播
音視頻鏈路對(duì)于課堂而言是重中之重,老師和學(xué)生的核心目的就是通過(guò)直播來(lái)上課,一旦音視頻掛了,騰訊課堂所有其他功能形同雞肋,這是前端第二項(xiàng)影響巨大的考驗(yàn)。
圖片
課堂前端團(tuán)隊(duì)針對(duì)于音視頻領(lǐng)域做了非常多的優(yōu)化,在疫情期間,音視頻作為核心模塊被重點(diǎn)關(guān)注,快速上線了快直播,簡(jiǎn)化WebRTC信令,分?jǐn)偢蟮牧髁浚琀LS降級(jí)WebRTC,混流開(kāi)關(guān)等等。
由于我不主要負(fù)責(zé)音視頻開(kāi)發(fā),音視頻所做的工作遠(yuǎn)遠(yuǎn)大于這里提到的,我們組負(fù)責(zé)音視頻的小姐姐已經(jīng)不知道通宵了多少回,十分辛苦~
1.3 前端考驗(yàn)三——SAS數(shù)據(jù)管理配置平臺(tái)
圖片
這個(gè)平臺(tái)承接了所有的運(yùn)營(yíng)、類(lèi)目、產(chǎn)品配置,對(duì)接CKV與CDB平臺(tái)做數(shù)據(jù)存儲(chǔ),對(duì)接云COS做文件存儲(chǔ),通過(guò)JSON Schema配置出數(shù)據(jù)服務(wù),同步ZK節(jié)點(diǎn)供后臺(tái)查詢(xún)。
圖片
目前成百上千張表都在這個(gè)平臺(tái)上,一旦掛了,后果不可預(yù)料。這個(gè)平臺(tái)整體運(yùn)用了GraphQL技術(shù)作為訪問(wèn)查詢(xún),屬于前端團(tuán)隊(duì)的第二大考驗(yàn)。
得益于SAS平臺(tái)最初設(shè)計(jì)的簡(jiǎn)潔性,監(jiān)控非常的充足,擴(kuò)容也較為容易,非常輕松地挺過(guò)流量高峰。
1.4 前端考驗(yàn)四——IMPush
IMPush是前端團(tuán)隊(duì)自研的消息通道,承接了所有socket消息轉(zhuǎn)發(fā)。這個(gè)系統(tǒng)承接了聊天區(qū)所有的消息服務(wù),與后臺(tái)保持全雙工長(zhǎng)連接通道,利用Redis進(jìn)行數(shù)據(jù)緩存,整體agent與center都會(huì)受到比較大的壓力挑戰(zhàn)。
圖片
這個(gè)服務(wù)如果掛了,所有的聊天區(qū)、彈幕都將面臨癱瘓,影響也是非常大的。
同樣的手段,借助于現(xiàn)有的負(fù)載均衡L5體系和資源,需要抗住巨大的并發(fā)量。
1.5 前端考驗(yàn)五——監(jiān)控、日志與灰度
我習(xí)慣將監(jiān)控、日志和灰度稱(chēng)為前端三板斧,是衡量一個(gè)前端團(tuán)隊(duì)是否專(zhuān)業(yè)的重要指標(biāo)。很多前端并不注重這點(diǎn),最多只有一個(gè)腳本報(bào)錯(cuò)的監(jiān)控,最基本的測(cè)速返回碼等監(jiān)控都沒(méi)有。
單論腳本報(bào)錯(cuò)監(jiān)控,我們其實(shí)已經(jīng)準(zhǔn)備三套方案,BadJS+Sentry+FullLink,在超高的訪問(wèn)量下,可以預(yù)計(jì)所有的平臺(tái)基本上都會(huì)掛,而腳本監(jiān)控對(duì)于前端來(lái)說(shuō)是非常重要的,三套系統(tǒng)的降級(jí)方案保證了我們?cè)谕饩W(wǎng)出問(wèn)題的時(shí)候第一時(shí)間定位到問(wèn)題所在,快速響應(yīng)bug。
日志上報(bào)是前端最容易忽略的,當(dāng)用戶量多了你就會(huì)發(fā)現(xiàn),很多問(wèn)題是沒(méi)有腳本報(bào)錯(cuò)的,如果只依賴(lài)于報(bào)錯(cuò)監(jiān)控,很多外網(wǎng)問(wèn)題兩眼一抹黑,無(wú)從下手了。作為專(zhuān)業(yè)的前端,我們需要全鏈路的日志定位。
圖片
前端團(tuán)隊(duì)在這里借用開(kāi)源的ELK方案,與后臺(tái)全鏈路系統(tǒng)打通,在基礎(chǔ)上通過(guò)DC通道上報(bào)落地,Agent代理不同監(jiān)控系統(tǒng),做成了上報(bào)中臺(tái)方案,在Kibana系統(tǒng)上統(tǒng)一查詢(xún)和定制報(bào)表。
圖片
灰度方案其實(shí)相對(duì)是比較難做的,最簡(jiǎn)單的是按照機(jī)器灰度,但這種方案在實(shí)際環(huán)境中基本上是不可用的,對(duì)于一個(gè)需求來(lái)說(shuō),如果同時(shí)修改了老頁(yè)面和新頁(yè)面,會(huì)導(dǎo)致用戶前后訪問(wèn)不一,甚至出現(xiàn)404情況。更好的方式是按照登錄態(tài)灰度,這時(shí)候我們需要統(tǒng)一接入層,Nginx、TSW都是可以的選擇,在白名單內(nèi)用戶進(jìn)行灰度。
圖片
但針對(duì)CDN,我們無(wú)法架設(shè)統(tǒng)一的Node服務(wù)來(lái)接入,這時(shí)需要考慮離線方案,制作離線包以及PWA管理平臺(tái),利用離線版本進(jìn)行登錄態(tài)灰度,可與Node服務(wù)保持一致。
有了這三點(diǎn)的保障,我們才可以做到心中有底,數(shù)據(jù)支撐指導(dǎo)我們的行動(dòng),來(lái)抗住高并發(fā)流量。
1.6 前端考驗(yàn)六——后臺(tái)保護(hù)
在這場(chǎng)戰(zhàn)役面前,前端不能自己獨(dú)善其身,不僅僅要做好自己的分內(nèi)事,更要幫助后臺(tái)團(tuán)隊(duì)共渡難關(guān)。
首先,在核心場(chǎng)景下,按需屏蔽不重要的接口,幫助后臺(tái)減輕壓力,可根據(jù)后臺(tái)的負(fù)載情況動(dòng)態(tài)調(diào)整。
圖片
其次,前端自己要保持柔性,除了核心CGI外,其他接口無(wú)論是超時(shí)還是返錯(cuò),都不要影響頁(yè)面核心功能的正常運(yùn)行,這對(duì)前端的代碼提出了很高的要求,所幸平時(shí)團(tuán)隊(duì)CR習(xí)慣養(yǎng)成良好,對(duì)接口的異常處理也做的比較完善,只是模擬接口測(cè)試驗(yàn)證花費(fèi)了一些時(shí)間。
2. 再說(shuō)需求
你以為上面就是全部了?Too Naive!上面的幾點(diǎn)只是擠出時(shí)間去做一些調(diào)整,重頭戲還在于極度緊張的業(yè)務(wù)需求。
騰訊課堂之前的toB部分針對(duì)的是開(kāi)課機(jī)構(gòu)、個(gè)人老師,現(xiàn)在是學(xué)校教務(wù)、學(xué)校老師、學(xué)校領(lǐng)導(dǎo)、教育局領(lǐng)導(dǎo),老板們直接重點(diǎn)關(guān)注,可想而知產(chǎn)品的壓力有多大。
我們?cè)趦商靸?nèi)就推出了騰訊課堂極速版(https://ke.qq.com/s),支持老師10s開(kāi)課,隨時(shí)隨地開(kāi)課,目前已經(jīng)迭代到了第4版。
眾所周知,對(duì)于一個(gè)系統(tǒng)而言,由簡(jiǎn)入繁易,由繁入簡(jiǎn)難。騰訊課堂有著一套復(fù)雜的B側(cè)管理體系,極速版要將這一切推翻,讓老師極速開(kāi)課,學(xué)生極速上課,這是多么困難的一件事情。課堂在這么短時(shí)間內(nèi)拿下極速版的版本發(fā)布,體現(xiàn)了極強(qiáng)的開(kāi)發(fā)戰(zhàn)斗力。
圖片
在此期間,開(kāi)發(fā)承接的工作量大約在平時(shí)的五倍左右,不僅僅需要通宵達(dá)旦,更需要快速響應(yīng),課堂前端每日均發(fā)布版本達(dá)到10次以上,如何在高頻次的發(fā)布中不影響質(zhì)量也是巨大的考驗(yàn)。
要保持高強(qiáng)度的戰(zhàn)斗力,對(duì)于團(tuán)隊(duì)的基礎(chǔ)效率工具建設(shè)提出了很高的要求。
2.1 快速開(kāi)發(fā)需求——Nohost方案
圖片
Nohost方案對(duì)于測(cè)試環(huán)境多需求并行開(kāi)發(fā)做了很好的支持,不僅支持前端分發(fā),還利用docker打通了后臺(tái)環(huán)境。
開(kāi)發(fā)很便捷使用分支部署,產(chǎn)品可以在家切不同的需求環(huán)境體驗(yàn),測(cè)試也可在家訪問(wèn)不同環(huán)境進(jìn)行測(cè)試。
圖片
2.2 快速開(kāi)發(fā)需求——Tolstoy方案
圖片
Tolstoy打通了后臺(tái)的PB、CGI,讓后臺(tái)定義的協(xié)議能夠自動(dòng)生成文檔、Mock、聲明文件、測(cè)試用例等等,尤其是TS的自動(dòng)生成,為開(kāi)發(fā)提供了很大的遍歷,讓我們的TS項(xiàng)目開(kāi)發(fā)的更快更好。
2.3 穩(wěn)定上線需求——Thanos方案
圖片
Thanos方案是我核心主導(dǎo)的,它解決的是發(fā)布鏈路的問(wèn)題,對(duì)于大公司而言,發(fā)布除了CI/CD之外,還有一些其他的額外流程保障,形成發(fā)布閉環(huán)。
圖片
如果沒(méi)有一個(gè)系統(tǒng)承載流程,這些雜亂無(wú)章的步驟可能成為發(fā)布事故的罪魁禍?zhǔn)住?/p>
圖片
另一方面,分支模型也是關(guān)鍵因素,采取分支發(fā)布的策略帶來(lái)的好處很多,但缺點(diǎn)也有,其中很重要的是分支準(zhǔn)入問(wèn)題,以及發(fā)布覆蓋問(wèn)題,這兩個(gè)普遍性問(wèn)題在Thanos方案得到保障。
圖片
2.4 個(gè)人技術(shù)能力
在高需求量,deadline又非常緊的情況下,對(duì)每個(gè)人的技術(shù)能力要求很高。騰訊課堂的前端復(fù)雜度還有很重要的一點(diǎn)體現(xiàn)在端上,老師端、學(xué)生端、機(jī)構(gòu)端、APP端、PC端、小程序端、微信公眾號(hào)、QQ公眾號(hào)、題庫(kù)、直播間等等等等……,這些端和項(xiàng)目可謂是眼花繚亂,數(shù)不過(guò)來(lái)。
很多項(xiàng)目歷史悠久,包含了眾多技術(shù)棧,從古老的FIS、QQ客戶端內(nèi)嵌、jQuery,到React、TypeScript、RN、音視頻等等,切換一個(gè)項(xiàng)目,如同換了家公司,需要重新適應(yīng)技術(shù)棧。
在人力不足的情況下,每個(gè)人都要去應(yīng)對(duì)自己不熟悉的領(lǐng)域,可能你還沒(méi)搞清楚什么是HLS就被拉去做音視頻,或者完全沒(méi)接觸過(guò)fis的情況下去熟悉整個(gè)項(xiàng)目的構(gòu)建打包流程,這對(duì)于個(gè)人快速上手能力和編程速度質(zhì)量都提出很高的要求。
圖片
另一方面,文檔在這一刻發(fā)揮出應(yīng)有的價(jià)值,一般團(tuán)隊(duì)不怎么注重文檔建設(shè),一來(lái)寫(xiě)起來(lái)廢時(shí)間,二來(lái)對(duì)于晉升和成長(zhǎng)沒(méi)什么幫助,看起來(lái)完全是利他性質(zhì),但實(shí)際上是互利。這時(shí)團(tuán)隊(duì)的價(jià)值觀和管理者就非常重要了,文檔的程度可以從側(cè)面反映出團(tuán)隊(duì)的管理水平。
3. 總結(jié)
最后,回歸正題,前端的復(fù)雜度也許很多,比如之前我參與的CPU負(fù)載過(guò)高問(wèn)題排查,用盡手段定位一個(gè)月之后發(fā)現(xiàn)是一條正則語(yǔ)句引發(fā)的,這種性質(zhì)的復(fù)雜屬于特定場(chǎng)景下的復(fù)雜度。而我今天提到的“復(fù)雜度”則比較普適,所有團(tuán)隊(duì)都存在面臨這種場(chǎng)景的可能性,而對(duì)于每個(gè)團(tuán)隊(duì)而言,我認(rèn)為沒(méi)有一個(gè)團(tuán)隊(duì)會(huì)覺(jué)得應(yīng)對(duì)起來(lái)很簡(jiǎn)單。更多需要的是公司資源調(diào)度+團(tuán)隊(duì)技術(shù)積累+個(gè)人能力的配合。
成長(zhǎng)最高效的方式,不是一個(gè)人單槍匹馬孤軍奮斗,而是和大家并肩作戰(zhàn)享受狂歡。
真正復(fù)雜的需求,個(gè)人的力量是有限的,如何協(xié)調(diào)整個(gè)團(tuán)隊(duì)的力量更為艱難。當(dāng)團(tuán)隊(duì)在技術(shù)視野、技術(shù)方向上有前瞻性,沉淀性,個(gè)人不僅僅是埋頭寫(xiě)業(yè)務(wù)時(shí),是團(tuán)隊(duì)在推著個(gè)人成長(zhǎng),在高手云集的團(tuán)隊(duì)中保持核心競(jìng)爭(zhēng)力,才是個(gè)人成長(zhǎng)最合適的方向。