<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一周緊急上線百萬高并發(fā)系統(tǒng)小記

          共 7462字,需瀏覽 15分鐘

           ·

          2020-12-06 02:11

          本文是魚皮在騰訊實(shí)習(xí)期間,從零開始一周緊急上線百萬高并發(fā)系統(tǒng)的相關(guān)經(jīng)驗(yàn)、思路及感悟,分享給大家。

          花 5 分鐘閱讀本文,你將收獲:
          1. 加深對實(shí)際工作環(huán)境、工作狀態(tài)的了解
          2. 學(xué)習(xí)高并發(fā)系統(tǒng)的設(shè)計(jì)思路、技術(shù)選型及理解
          3. 學(xué)習(xí)工作中對接多方的溝通技巧
          4. 學(xué)會(huì)與測試打配合的技巧
          5. 學(xué)習(xí)緊急事故的處理方式
          6. 事后如何進(jìn)行歸納總結(jié)
          7. 感受筆者爆肝工作的痛苦與掙扎

          前言

          從年前開始和導(dǎo)師二人接手了一個(gè)緊急項(xiàng)目,年前加班做完一期后項(xiàng)目效果顯著,于是年后開工立刻加急開發(fā)二期,目標(biāo)是一周上線。由于項(xiàng)目業(yè)務(wù)邏輯復(fù)雜、工期緊、人手缺、對接方多,難度很大,極具挑戰(zhàn)性,因此和導(dǎo)師二人開始了 007 的爆肝工作。
          遠(yuǎn)程辦公無疑為 007 無休工作制提供了有利條件,那段時(shí)間,我做夢都在敲代碼。

          項(xiàng)目介紹

          首先要介紹下負(fù)責(zé)的項(xiàng)目及系統(tǒng)。項(xiàng)目背景、業(yè)務(wù)等信息自然不能透露,這里剝離業(yè)務(wù),僅介紹關(guān)鍵系統(tǒng)模型,如下圖:
          如圖,我負(fù)責(zé)的是一個(gè)狀態(tài)流轉(zhuǎn)系統(tǒng)和查詢系統(tǒng),以及它們依賴的數(shù)據(jù)庫服務(wù)。
          狀態(tài)流轉(zhuǎn)系統(tǒng)的作用是按照邏輯修改數(shù)據(jù)庫中某條數(shù)據(jù)的狀態(tài)字段,并在修改成功后依據(jù)狀態(tài)向其他業(yè)務(wù)側(cè)發(fā)送通知。
          查詢系統(tǒng),顧名思義就是從數(shù)據(jù)庫中查詢數(shù)據(jù),包括最基礎(chǔ)的鑒權(quán)、查詢等功能。
          先分析一下系統(tǒng)中一些難點(diǎn):
          1. 查詢系統(tǒng)是一個(gè)高扇入服務(wù),被其他各業(yè)務(wù)側(cè)調(diào)用,會(huì)存在三個(gè)問題:
          高并發(fā):將各業(yè)務(wù)側(cè)請求量聚集,經(jīng)評估,會(huì)產(chǎn)生百萬量級的高并發(fā)請求。
          兼容性:如何設(shè)計(jì)一套 API,滿足各業(yè)務(wù)側(cè)需求的同時(shí)容易被理解。
          對接復(fù)雜:要同時(shí)與多個(gè)業(yè)務(wù)側(cè)的同學(xué)溝通來討論接口,想想就是一件很復(fù)雜的事情。
          2. 狀態(tài)流轉(zhuǎn)系統(tǒng)的業(yè)務(wù)邏輯相當(dāng)復(fù)雜。
          3. 狀態(tài)流轉(zhuǎn)系統(tǒng)和查詢系統(tǒng)、其他業(yè)務(wù)側(cè)之間存在交互(比如互相發(fā)送通知和調(diào)用),對時(shí)延、容錯(cuò)性、一致性的要求很高。
          分析出了難點(diǎn),在寫代碼之前,要先編寫可行的技術(shù)方案

          設(shè)計(jì)思路

          在實(shí)際工作中,編寫詳細(xì)的技術(shù)方案是非常有必要的。優(yōu)秀的工程師會(huì)在技術(shù)方案中考慮到各種場景、評估各種風(fēng)險(xiǎn)、工作量估時(shí)、記錄各種問題等,不僅幫助自己梳理思路、歸納總結(jié),同時(shí)也給其他人提供了參照以及說服力(比如你預(yù)期7天上線,沒有方案誰信你?)。
          根據(jù)二八定理,復(fù)雜的系統(tǒng)中,編寫技術(shù)方案、梳理設(shè)計(jì)思路的時(shí)間和實(shí)際敲代碼開發(fā)的時(shí)間比例為 8 : 2。
          設(shè)計(jì)遵循的原則是?“貼合業(yè)務(wù)”沒有最好的架構(gòu),只有最適合業(yè)務(wù)的架構(gòu)。切忌過度設(shè)計(jì)!
          此外,還要考慮項(xiàng)目的緊急程度和人力成本,先保證可用,再追求極致。
          一些簡單的設(shè)計(jì)這里就略過了,下面針對系統(tǒng)難點(diǎn)和業(yè)務(wù)需求,列舉幾個(gè)重點(diǎn)設(shè)計(jì)及技術(shù)選型

          1. 高并發(fā)

          提到高并發(fā),大家首先想到的是緩存和負(fù)載均衡,缺一不可。
          負(fù)載均衡說白了就是 “砸錢,加機(jī)器!”,但是為公司省機(jī)器、節(jié)約成本是每位后端工程師的信仰,這就要靠技術(shù)選型和架構(gòu)設(shè)計(jì)來實(shí)現(xiàn)了。目標(biāo)是盡可能利用每臺(tái)機(jī)器的資源,抗住最大的并發(fā)請求。

          選型如下:
          編程框架:選擇輕量級的 Restful 框架 Jersey,搭配輕量級依賴注入庫 Guice
          Web服務(wù)器:選擇高性能的輕量級 NIO 服務(wù)器 Grizzly
          緩存:騰訊自研海量分布式存儲(chǔ)系統(tǒng) CKV+(支持Redis協(xié)議,有數(shù)據(jù)監(jiān)控平臺(tái))
          數(shù)據(jù)庫分庫分表:選用公司自研的基礎(chǔ)設(shè)施,不細(xì)說了
          負(fù)載均衡:輕量級反向代理服務(wù)器 Nginx 和 L5 負(fù)載均衡,百萬并發(fā)需要增加十余臺(tái)機(jī)器
          CDN 及預(yù)熱:能夠支持高效的文件下載服務(wù)
          其中,緩存是抗住高并發(fā)流量的關(guān)鍵,須重點(diǎn)設(shè)計(jì)。

          緩存方案

          1. 數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì)
          用過緩存的同學(xué)都了解,關(guān)于緩存 Key 的設(shè)計(jì)是很重要的。根據(jù)業(yè)務(wù)來,保證緩存 key 之間不沖突、便于查找就好。此處我選擇請求參數(shù) + 接口唯一 id 來拼接 key。并且分頁查詢接口可復(fù)用全量查詢接口的緩存。
          2. 緩存降級
          找不到對應(yīng) key / redis 連接失敗時(shí)直接查庫。
          3. 緩存更新
          當(dāng)數(shù)據(jù)庫發(fā)生修改時(shí),需要對緩存進(jìn)行刪除。由于存在非必填的請求參數(shù),因此緩存 key 可能是一個(gè)模糊值。比如有 a、b 兩個(gè)請求參數(shù),key 可能為 “a”,也可能為 “ab”。
          針對請求字段固定(所有字段必填)的接口,更新緩存時(shí),直接拼接出唯一的 key 進(jìn)行刪除即可。
          而針對請求字段不固定(存在非必填字段)的接口,可使用 redis 的 scan 命令范圍掃描(不要用 keys 命令!)或者通過循環(huán)拼接出所有可能的 key。比如使用 scan 命令清除所有 key 前綴為 user1 的緩存。
          4. 緩存穿透
          無論查詢出的列表是否為空,都寫入緩存。但在業(yè)務(wù)會(huì)返回多種錯(cuò)誤碼時(shí),不建議采用這種方式,復(fù)雜度高,成本太大。

          2. 兼容性

          兼容性主要考察接口的設(shè)計(jì),為兼容多個(gè)業(yè)務(wù)側(cè),需要將請求參數(shù)以及響應(yīng)參數(shù)設(shè)置的盡可能靈活。在設(shè)計(jì)接口時(shí),切忌一定要和所有的業(yè)務(wù)側(cè)對齊,否則一個(gè)字段設(shè)計(jì)不當(dāng)可能導(dǎo)致滿盤皆輸!
          這里有三個(gè)技巧
          1. 提供可訪問鏈接的文檔,供調(diào)用方即時(shí)查閱(比如騰訊文檔)。
          2. 請求參數(shù)不能過多,且要易于理解,不能為了強(qiáng)制兼容而設(shè)置過于復(fù)雜的參數(shù),必要時(shí)可針對某一業(yè)務(wù)側(cè)定制接口。
          3. 響應(yīng)參數(shù)盡量多(多不是濫),要知道每次增加返回字段都要修改代碼,而適當(dāng)冗余的字段避免了此問題。

          3. 消息通知

          上面介紹難點(diǎn)時(shí)提到:狀態(tài)流轉(zhuǎn)系統(tǒng)與查詢系統(tǒng)、其他業(yè)務(wù)側(cè)存在互相發(fā)送通知的交互。當(dāng)狀態(tài)流轉(zhuǎn)時(shí),需要通知其他業(yè)務(wù),還要查詢系統(tǒng)立即更新緩存。對消息的實(shí)時(shí)性要求很高。
          這里最初有兩種方案
          1. 各系統(tǒng)提供回調(diào)接口,用于接收通知。能保證實(shí)時(shí)性,但是各系統(tǒng)間緊耦合,不利于擴(kuò)展。
          2. 使用消息隊(duì)列,實(shí)現(xiàn)應(yīng)用解耦及異步消息。
          最后還是采取了第二種方案,并選用騰訊自研的 TubeMQ(萬億級分布式消息中間件,已開源Apache孵化),原因如下:
          1. 狀態(tài)流轉(zhuǎn)系統(tǒng)的通知數(shù)據(jù)之后可能存在其他消費(fèi)方,使用消息隊(duì)列利于擴(kuò)展,對代碼侵入性也少。
          2. 消息隊(duì)列可持久化消息
          3. TubeMQ 支持消費(fèi)方負(fù)載均衡,性能高
          4. TubeMQ 容量大,可存放萬億數(shù)量級消息
          5. 支持公司自研組件,便于形成統(tǒng)一規(guī)范
          在技術(shù)選型和確定方案時(shí),不僅要關(guān)注當(dāng)前的業(yè)務(wù)需求,也要有一定的前沿視角。

          4. 風(fēng)險(xiǎn)評估

          切忌,在選用中間件 / 框架前,要盡可能多的進(jìn)行了解,評估其可能帶來的風(fēng)險(xiǎn)。一般公司內(nèi)都有自己的知識庫,可以利用好內(nèi)部資源或者找谷歌度娘。
          這里我評估了 TubeMQ 帶來的風(fēng)險(xiǎn),從消息可靠性、消息順序性、消息重復(fù)、監(jiān)控告警等多個(gè)角度進(jìn)行了分析,還是發(fā)現(xiàn)了一些可能的風(fēng)險(xiǎn)。比如當(dāng)消費(fèi)方消費(fèi)數(shù)據(jù)狀態(tài)改變的消息失敗時(shí),緩存未被及時(shí)更新,導(dǎo)致數(shù)據(jù)庫和緩存中的數(shù)據(jù)不一致。
          那么,如何規(guī)避風(fēng)險(xiǎn)呢?我從消息隊(duì)列生產(chǎn)方和消費(fèi)方的角度設(shè)計(jì)了消息可靠性和數(shù)據(jù)一致性的解決方案。

          解決方案

          生產(chǎn)方消息可靠性:
          1. Tube 可保證消息一定送達(dá),發(fā)送失敗時(shí)會(huì)自動(dòng)重發(fā)。
          2. 發(fā)送消息結(jié)束時(shí)會(huì)觸發(fā)回調(diào),回調(diào)里可判斷消息發(fā)送及確認(rèn)狀態(tài),可將發(fā)送失敗的消息放入隊(duì)列,下次發(fā)送優(yōu)先從隊(duì)列里取。
          消費(fèi)方消息可靠性和數(shù)據(jù)一致性:
          1.消費(fèi)失敗時(shí)進(jìn)行最多三次重試
          2.重試后仍消費(fèi)失敗,則記錄日志,確保消息不丟失
          3.通過定時(shí)任務(wù)讀取日志,嘗試再次消費(fèi)失敗消息,并進(jìn)行告警

          開發(fā)過程

          其實(shí)開發(fā)過程沒什么好說的,就是按照技術(shù)方案去敲代碼。
          這里也有幾個(gè)小竅門
          1. 同時(shí)開發(fā)多個(gè)項(xiàng)目時(shí),可以每個(gè)項(xiàng)目一個(gè)獨(dú)立 Git 分支,合并的時(shí)候分批合并,否則別人閱讀你提交的代碼時(shí)會(huì)非常累!
          2. 給每個(gè)請求做一些打點(diǎn)數(shù)據(jù)上報(bào),比如請求量、請求時(shí)間、失敗請求數(shù),便于監(jiān)控統(tǒng)計(jì)。
          3. 多記錄日志,詳細(xì)清晰的日志可以幫助我們快速定位故障

          問題解決

          很多問題在本地開發(fā)時(shí)是察覺不到的,在測試及線上環(huán)境才會(huì)被發(fā)現(xiàn)。問題解決的過程就像坐過山車,經(jīng)常的狀態(tài)是:測試 => 開發(fā) => 測試 => 上線 => 開發(fā) => 測試,循環(huán)往復(fù)。
          兩個(gè)溫馨小貼士:
          1. 遇到問題時(shí),千萬不要慌,可以先深呼吸幾口氣,因?yàn)閱栴}一定是可以解決的,解決不了那么你可能要被解決了!
          2. 解決問題后,千萬別激動(dòng),可以先深呼吸幾口氣,因?yàn)槟氵€會(huì)產(chǎn)生新的問題,而且往往新問題更嚴(yán)重!
          下面分享一些讓魚皮印象深刻的問題。

          1. 事務(wù)提交時(shí)報(bào)錯(cuò)?

          原因:事務(wù)中調(diào)用的函數(shù)里也有事務(wù),因此事務(wù)里套了事務(wù),破壞了隔離性。
          解決:修改代碼,保證事務(wù)隔離性。

          2. 依賴包存在,項(xiàng)目啟動(dòng)卻報(bào)錯(cuò)?

          原因:存在多版本 jar 包,導(dǎo)致 Java 代碼使用反射機(jī)制動(dòng)態(tài)生成類時(shí)不知道使用哪個(gè) jar 包里的類。
          解決:刪掉多余版本 jar 包。

          3. 緩存未即時(shí)更新

          原因:經(jīng)排查,是由于實(shí)際的緩存 key 數(shù)量可達(dá)千萬級,導(dǎo)致更新緩存時(shí)使用 scan 命令掃描的效率過低,長達(dá)20多秒!
          解決:修改更新緩存的方案,不再使用 scan 命令,而是在業(yè)務(wù)代碼中拼湊出所有可能的 keys,依次刪除。

          以為這個(gè)問題這樣就結(jié)束了?不要忘記上面的小貼士:
          “解決問題后,千萬別激動(dòng),可以先深呼吸幾口氣,因?yàn)槟氵€會(huì)產(chǎn)生新的問題,而且往往新問題更嚴(yán)重!”

          4. 緩存仍未即時(shí)更新?

          原因:某業(yè)務(wù)側(cè)要求數(shù)據(jù)強(qiáng)一致性,緩存和數(shù)據(jù)庫中的狀態(tài)必須完全一致!而緩存雖然是毫秒級更新,但無法做到實(shí)時(shí)一致。
          解決:為該業(yè)務(wù)側(cè)定制一個(gè)接口,該接口不查詢緩存,直接查數(shù)據(jù)庫,保證查到的數(shù)據(jù)一定是最新值。

          5. 請求卡死

          服務(wù)運(yùn)行一段時(shí)間后,發(fā)現(xiàn)所有的請求都被阻塞了!心臟受不了。
          原因:使用 jstack 打印線程信息后分析 thread_dump 文件,發(fā)現(xiàn)是由于緩存類庫 Jedis 未手動(dòng)釋放連接導(dǎo)致連接數(shù)耗盡,導(dǎo)致新的請求線程會(huì)不斷等待 Jedis 連接釋放,從而卡死。
          解決:補(bǔ)充釋放 Jedis 連接的代碼即可。

          6. 線上環(huán)境分析日志時(shí)突然告警,磁盤 IO 占用超過 99%!

          原因:誤用 cat 命令查看未分割的原始日志文件,由于日志文件太大(幾十 GB),導(dǎo)致磁盤 IO 直接刷爆!
          解決:使用 less、tail、head等命令代替 cat,并刪除已備份的大日志文件。

          7. 進(jìn)程閃退

          排查:通常 JVM 進(jìn)程閃退是有錯(cuò)誤日志的,但是并沒有找到,排查陷入絕境。沒辦法,只能祈禱問題不再復(fù)現(xiàn)。后來問題真的沒出現(xiàn)過了,謝謝!
          原因:后來,經(jīng)詢問,是有人手動(dòng) kill 掉了這個(gè)進(jìn)程。好的,***。

          8. 線上環(huán)境的消息通知發(fā)送成功了,怎么沒有預(yù)期的數(shù)據(jù)更新效果?

          定位思路:先看消息是否被消費(fèi),再看對消息的處理是否正確。
          排查:查看線上日志,發(fā)現(xiàn)消息并未被消費(fèi);但是查看監(jiān)控界面,發(fā)現(xiàn)消息被測試環(huán)境的機(jī)器消費(fèi)了!
          原因:由于測試環(huán)境和線上環(huán)境屬于同一個(gè)消費(fèi)組,當(dāng)消息到達(dá)時(shí),同一個(gè)消費(fèi)組只有一個(gè)消費(fèi)者能夠成功消費(fèi)該消息,被測試環(huán)境消費(fèi)掉了,導(dǎo)致線上環(huán)境數(shù)據(jù)沒更新。
          發(fā)現(xiàn)這個(gè)問題的時(shí)候,已經(jīng)是上線前一天的深夜。再申請一個(gè)消費(fèi)組已經(jīng)來不及了,情急之下,只能先下掉測試環(huán)境的服務(wù)。第二天申請好消費(fèi)組后,根據(jù)環(huán)境去區(qū)分使用哪個(gè)消費(fèi)組就可以了,這樣每個(gè)消費(fèi)組都會(huì)獨(dú)立消費(fèi)消息,成功避免了消息競爭。

          9. 報(bào)告!流量太大,撐不住啊!

          原因:機(jī)器不夠,需進(jìn)行緊急擴(kuò)容
          解決:緊急新申請了 10 臺(tái)機(jī)器,完成初始化配置,成功部署新機(jī)器后,成功增大了并發(fā)度。
          小技巧:多個(gè)機(jī)器做相同操作時(shí),有兩種快捷的做法。
          1. 利用 SSH 連接工具自帶的并行操作功能,自動(dòng)給所有機(jī)器鍵入命令( XShell 軟件支持)
          2. 配置好一臺(tái)機(jī)器后,可使用 rsync 命令同步配置至其他機(jī)器

          10. 上線前一天你跟我說接口設(shè)計(jì)有問題?

          原因:溝通出現(xiàn)嚴(yán)重問題!
          工作中,一些同事因?yàn)樽陨順I(yè)務(wù)繁忙,可能在核對接口設(shè)計(jì)方案的時(shí)候沒有注意。等他們忙完了,會(huì)反復(fù) @ 你、私聊你詢問。我們一定不要這樣!
          解決:緊急電話會(huì)議,拉群核對方案

          11. 線上出 bug 了!

          線上出 bug,是一件很大的事,必須緊急響應(yīng)。在夢里也得給我爬起來!
          原因:測試環(huán)境和線上環(huán)境未必完全一致,且測試環(huán)境未必能測出所有問題。因此驗(yàn)證時(shí)通常需要預(yù)發(fā)布環(huán)境,數(shù)據(jù)使用線上數(shù)據(jù),但卻是獨(dú)立的服務(wù)器,保證不影響線上。
          解決:緊急排查定位問題,三分鐘成功修復(fù)!
          修復(fù) bug 有一定的技巧,分享下個(gè)人的排錯(cuò)路徑:
          截圖 / 問題 => 請求 => bug 是否可復(fù)現(xiàn),和測試緊密配合 => 數(shù)據(jù) => 數(shù)據(jù)源(真實(shí)數(shù)據(jù)與接口數(shù)據(jù)是否一致) => 數(shù)據(jù)處理
          解釋一下:
          通常發(fā)現(xiàn)問題的是運(yùn)維、用戶或者測試,他們會(huì)拋出一個(gè)問題或者問題的相關(guān)的截圖,這時(shí),我們要快速想到這個(gè)問題對應(yīng)的功能(即對應(yīng)的請求/接口),然后讓問題描述者盡可能多的提供信息(比如請求參數(shù)、問題時(shí)間等)。
          如果問題時(shí)間較久,看日志及監(jiān)控不易排查,可以詢問是否可以造一個(gè)復(fù)現(xiàn)該問題的case,這樣只需觀察最新的日志即可,方便排錯(cuò)。
          定位到請求后,我們要分析請求及響應(yīng)的哪些數(shù)據(jù)是異常的,即定位關(guān)鍵數(shù)據(jù),然后定位數(shù)據(jù)來源(是從數(shù)據(jù)庫查的,還是從緩存查的),并觀察響應(yīng)數(shù)據(jù)與真實(shí)數(shù)據(jù)源是否一致。如果不一致,可能是業(yè)務(wù)邏輯中對數(shù)據(jù)的處理出現(xiàn)了問題,再進(jìn)一步去做分析。
          高效溝通建議:描述問題,盡量用數(shù)據(jù)說話,給出截圖的同時(shí),要提供完整的數(shù)據(jù)、請求等信息,有助他人分析。

          12. 線上出現(xiàn)部分錯(cuò)誤數(shù)據(jù)

          這是一個(gè)可以預(yù)見的問題。還好已經(jīng)在項(xiàng)目中配置了郵件告警,能夠報(bào)告錯(cuò)誤數(shù)據(jù)的信息,錯(cuò)誤數(shù)據(jù)量也不大。
          解決:修復(fù)導(dǎo)致錯(cuò)誤數(shù)據(jù)的 bug 后,編寫程序循環(huán)所有錯(cuò)誤信息并生成請求代碼,然后手動(dòng)執(zhí)行請求代碼,刷新線上不同步數(shù)據(jù)即可。
          建議:設(shè)計(jì)時(shí)還是要盡可能考慮到風(fēng)險(xiǎn),可以按照問題的嚴(yán)重程度做分級報(bào)警策略(短信 > 郵件 > 通訊軟件)。

          13. 線上機(jī)器 OOM!

          上線三天后發(fā)現(xiàn)的問題,部分線上機(jī)器竟然出現(xiàn)了OOM(堆內(nèi)存溢出)的情況,導(dǎo)致服務(wù)不可用。經(jīng)排查,是使用的第三方中間件的當(dāng)前版本存在 bug, 所以說在使用組件前要充分調(diào)研和風(fēng)險(xiǎn)評估,選擇正確的版本。

          血淚教訓(xùn)

          1. 有問題一定盡可能在測試環(huán)境去解決,否則線上出問題對心臟很不友好。
          2. 不要盲目樂觀,以為上線就沒問題,要多驗(yàn)證,保持警惕。
          3. 使用第三方依賴時(shí),一定要嚴(yán)格核對依賴版本號,確保穩(wěn)定版本。使用老版本或版本不一致可能導(dǎo)致嚴(yán)重 bug!

          上線后如果發(fā)現(xiàn)問題,會(huì)經(jīng)歷如下流程,我稱它為 hapy 流程
          比如當(dāng)發(fā)現(xiàn) DB 服務(wù)的 bug 后,你只需要改 DB 服務(wù)的一行代碼。然而還要做
          1. 修改DB服務(wù)的一行代碼
          2. 跑單元測試
          3. DB服務(wù)打成依賴包
          4. 修改“狀態(tài)流轉(zhuǎn)系統(tǒng)”、“查詢系統(tǒng)”對DB服務(wù)的依賴包(改動(dòng)版本號/更新本地緩存拉取最新包)
          5. 重新發(fā)布“狀態(tài)流轉(zhuǎn)系統(tǒng)”、“查詢系統(tǒng)”至測試環(huán)境
          6. 可能還要重新交給測試的同學(xué)進(jìn)行回歸測試
          7. 測試通過,再次提交“狀態(tài)流轉(zhuǎn)系統(tǒng)”、“查詢系統(tǒng)”的代碼,發(fā)起 CR(代碼審查)
          8. 找同事或 Leader 讀代碼,通過 CR
          9. 合并分支
          10. 發(fā)布 “狀態(tài)流轉(zhuǎn)系統(tǒng)”、“查詢系統(tǒng)” 至線上環(huán)境,每發(fā)一臺(tái)機(jī)器,都要進(jìn)行一次驗(yàn)證(滾動(dòng)部署)。
          11. 再次發(fā)現(xiàn)新的bug
          這是一件惡心到爆炸的事情,但是在第 2、6、8 步驟時(shí),是存在空余等待時(shí)間的。這時(shí)我們可以做做其他工作,記錄一下工作內(nèi)容、問題等。

          總結(jié)

          首先總結(jié)一下這個(gè)項(xiàng)目各階段的耗時(shí):
          理解需求:5%
          開發(fā):15%
          溝通確認(rèn)問題:30%
          測試及驗(yàn)證:30%
          上線及驗(yàn)證:20%
          其中,修復(fù) bug 貫穿后面的幾個(gè)流程,大概占了總時(shí)間的60%。


          項(xiàng)目過程存在的問題:
          1. 前期未參與需求評審,了解的信息較少。
          2. 上線前一天晚上,竟然還在臨時(shí)對齊接口?這是在溝通方案階段應(yīng)該確認(rèn)好的。
          3. 大約 80% 的時(shí)間花在溝通、查詢數(shù)據(jù)、提供數(shù)據(jù)及驗(yàn)證。
          4. 自己沒測試完,就開始串測,導(dǎo)致同一個(gè) bug 被多方發(fā)現(xiàn),反復(fù) @,導(dǎo)致改 bug 效率低下。
          5. 對自研中間件的不熟悉,導(dǎo)致花費(fèi)的時(shí)間成本較高。
          6. 全局觀還不夠,不能提前預(yù)見到一些可能的問題。
          7. 對中間件調(diào)研不夠,在最初未核對依賴版本號導(dǎo)致線上機(jī)器 OOM。

          自我感覺良好的地方:
          1. 和測試同學(xué)配合緊密,互相體諒,測試效率較高
          2. 為查詢系統(tǒng)編寫了詳細(xì)的接口文檔,上傳至公司知識庫供實(shí)時(shí)查閱
          3. 最快 3 分鐘緊急修復(fù)線上 bug
          4. 最快 30 分鐘從接受需求到上線
          5. 在發(fā)現(xiàn)中間件問題時(shí),即時(shí)和對接方溝通,設(shè)計(jì)出了對其無任何影響的低成本解決方案
          6. 積極幫助其他同學(xué)查詢數(shù)據(jù),排查問題
          7. 編寫腳本高效解決部分錯(cuò)誤數(shù)據(jù)

          成長與收獲:
          1. 抗壓熬夜能力 ↑
          2. 設(shè)計(jì)思維能力 ↑
          3. 溝通能力 ↑
          4. 解決問題能力 ↑
          5. 高級命令熟悉度 ↑
          6. 中間件熟悉度 ↑
          7. 集群管理能力 ↑
          8. 拒絕需求能力 ↑
          9. 吐槽能力 ↑
          10. 吹 ? 能力 ↑

          后續(xù)

          項(xiàng)目上線后,通過總結(jié)復(fù)盤,發(fā)現(xiàn)了項(xiàng)目中值得優(yōu)化的地方,也思考到了一些更健全的機(jī)制,將逐漸去實(shí)現(xiàn)。比如:

          1. 兩個(gè)系統(tǒng)中有部分相同的配置

          目前采用復(fù)制粘貼的方式去同步相同的配置,這種方式的優(yōu)點(diǎn)是比較簡單。但缺點(diǎn)也很明顯,如果一個(gè)系統(tǒng)的配置改了,而忘了修改另一個(gè)系統(tǒng)的配置,就會(huì)出現(xiàn)錯(cuò)誤。
          事實(shí)上,可以引入一個(gè)配置中心,集中管理多個(gè)系統(tǒng)的配置文件,并且支持手動(dòng)修改、多環(huán)境、灰度、配置版本回退等功能。
          可以采用阿里的 Nacos 或攜程的 Apollo,提供了界面來管理配置。


          2. 曾經(jīng)的進(jìn)程閃退問題,必須重視!

          無法保證進(jìn)程不閃退,但是可以對進(jìn)程實(shí)時(shí)監(jiān)控,并自動(dòng)對閃退進(jìn)程進(jìn)行重啟。
          實(shí)現(xiàn)方式有兩種:
          1. 使用工具,例如 supervisor 或 monit,可以對進(jìn)程進(jìn)行管理和閃退重啟
          2. 編寫 shell 腳本,再通過定時(shí)任務(wù),實(shí)現(xiàn)周期性觀察進(jìn)程狀態(tài)及重啟。推薦將定時(shí)任務(wù)接入分布式任務(wù)調(diào)度平臺(tái),尤其當(dāng)定時(shí)任務(wù)很多時(shí),進(jìn)行可視化的管理和方便的控制調(diào)度是必要的!

          3. 消息隊(duì)列可靠性保障

          1. 消息重傳機(jī)制:如方案所說,設(shè)計(jì)重傳隊(duì)列,再次發(fā)送時(shí)優(yōu)先取重傳隊(duì)列中的消息發(fā)送。但注意要避免隊(duì)列無限重傳,須給每個(gè)消息設(shè)置重傳次數(shù)閾值。
          2. 郵件告警:如果消息重傳次數(shù)超過閾值,直接發(fā)送郵件告警,不再將該消息入隊(duì)。

          工作真是簡單而不簡單,誰說后端只是 CRUD(增刪改查)?


          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产99精品 | 高清无码免费视频在线观看 | 九九成人| 亚洲第一导航 | 久草青青 |