小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

一周爆肝上線百萬高并發(fā)系統(tǒng)!你給我解釋解釋什么叫牛逼?

 但丁叔叔 2020-03-15

作者:木子魚皮 鏈接:https://www./discuss/368998 

本文是個人(騰訊廣告全棧畢業(yè)生)從零開始一周緊急上線百萬高并發(fā)系統(tǒng)的相關(guān)經(jīng)驗、思路及感悟,在此記錄分享。

后續(xù)持續(xù)更新,歡迎先??后看!

花5-10分鐘閱讀本文,你將收獲:

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

前言

從年前開始和導(dǎo)師二人接手了一個加緊項目,年前加班做完一期后效果顯著,于是開工后加急開發(fā)二期,目標(biāo)是7天上線(后來延長至9天)。由于項目難度大、工期緊、人手缺、對接方多,極具挑戰(zhàn)性,因此和導(dǎo)師二人開始了007的爆肝工作。

PS:007本意指一周七天隨時靈活oncall。此處的007特指朝9晚0點后、無午休以及夜里做夢的時間都在工作的爆肝工作制。遠(yuǎn)程辦公為007提供了有利條件。

項目介紹

首先要介紹下負(fù)責(zé)的項目及系統(tǒng)。項目背景、業(yè)務(wù)等信息自然不能透露,這里剝離業(yè)務(wù),介紹一下抽象出的關(guān)鍵系統(tǒng)模型,如下圖:

如圖,我負(fù)責(zé)的是一個狀態(tài)流轉(zhuǎn)系統(tǒng)和查詢系統(tǒng),以及它們依賴的DB服務(wù)。

狀態(tài)流轉(zhuǎn)系統(tǒng)的作用主要是按照邏輯修改DB中的狀態(tài)值,并在修改成功時依據(jù)狀態(tài)向其他業(yè)務(wù)側(cè)發(fā)送通知。

查詢系統(tǒng),顧名思義就是查詢我們負(fù)責(zé)的DB的值,包括最基礎(chǔ)的鑒權(quán)、查詢等功能。

先分析一下系統(tǒng)中一些難點:

1.明顯,查詢系統(tǒng)是一個高扇入服務(wù),被各其他業(yè)務(wù)側(cè)調(diào)用,必然會存在三個問題:·高并發(fā):各業(yè)務(wù)側(cè)流量聚集,經(jīng)評估,會產(chǎn)生百萬量級的高并發(fā)流量·兼容性:如何設(shè)計一套API,兼容各業(yè)務(wù)側(cè)的同時易被理解·對接復(fù)雜:要同時與4個業(yè)務(wù)側(cè)的同學(xué)溝通,想想就是一件很復(fù)雜的事情2.狀態(tài)流轉(zhuǎn)系統(tǒng)邏輯相當(dāng)復(fù)雜(最后光邏輯就300多行代碼)3.狀態(tài)流轉(zhuǎn)系統(tǒng)與查詢系統(tǒng)、其他業(yè)務(wù)側(cè)存在交互(比如互相發(fā)送通知),對時延、一致性要求很高

分析出難點后,下面開始編寫技術(shù)方案。

設(shè)計思路

在實際工作中,編寫好的、詳細(xì)的技術(shù)方案是非常有必要的。優(yōu)秀的工程師會在技術(shù)方案中考慮到各種場景、評估各種風(fēng)險、工作量估時、記錄各種問題等,不僅幫助自己梳理思路、歸納總結(jié),同時也給其他人提供了參照以及說服力(比如你預(yù)期7天上線,沒有方案誰信你?)。

根據(jù)二八定理,復(fù)雜的系統(tǒng)中,可能編寫技術(shù)方案、梳理設(shè)計思路的時間和實際敲代碼開發(fā)的時間比例為8 : 2。

設(shè)計遵循的原則是”貼合業(yè)務(wù)“,沒有最好的架構(gòu),只有最適合業(yè)務(wù)的架構(gòu)。切忌過度設(shè)計!

此外,還要考慮項目的緊急程度和人力成本,先保證可用,再追求極致。

一些簡單的設(shè)計這里就略過了,下面針對系統(tǒng)難點和業(yè)務(wù)需求,列舉幾個重點設(shè)計及技術(shù)選型:

1. 高并發(fā)

提到高并發(fā),大家首先想到的是緩存和負(fù)載均衡,缺一不可。

負(fù)載均衡說白了就是“砸錢,加機(jī)器!”,但是為公司省機(jī)器、省成本應(yīng)該是每位后端工程師的基本理念,就要靠技術(shù)選型和架構(gòu)設(shè)計來實現(xiàn)了,目標(biāo)是保證每臺機(jī)器能抗住最大的并發(fā)流量。

選型如下:

1.編程框架:選擇輕量級的Restful框架Jersey,搭配輕量級依賴注入Guice(不用Spring,可以私信我問原因)2.Web服務(wù)器:選擇性能最高的輕量級NIO服務(wù)器Grizzly(各服務(wù)器性能對比[1])3.緩存:CKV+ 騰訊自研海量分布式存儲系統(tǒng)(支持Redis協(xié)議,有數(shù)據(jù)監(jiān)控平臺,已開源)4.DB分庫分表:公司自研基礎(chǔ)設(shè)施,不多說5.負(fù)載均衡:輕量級反向代理服務(wù)器 Nginx,百萬并發(fā)需要增加十余臺機(jī)器6.CDN及預(yù)熱:保證高效的下載服務(wù)

其中,緩存是抗住高并發(fā)流量的關(guān)鍵,須重點設(shè)計。

緩存方案

1. 數(shù)據(jù)結(jié)構(gòu)設(shè)計

用過緩存的同學(xué)都了解,關(guān)于緩存Key的設(shè)計是很重要的,根據(jù)業(yè)務(wù)來,保證隔離和易查找(便于緩存更新)就好,這里我選擇請求參數(shù)+接口唯一id來拼接key。并且分頁接口可復(fù)用全量list接口。

2. 緩存降級

找不到對應(yīng)key/redis連接失敗時直接查庫。

3. 緩存更新

當(dāng)DB修改時,對緩存進(jìn)行刪除。由于存在非必填的請求參數(shù),因此key可能是一個模糊值(比如有a、b兩個請求參數(shù),key可能為“a”,也可能為“ab”)。

針對請求字段固定(均必填)的接口,更新緩存時,直接拼接出唯一的key進(jìn)行刪除即可。

而針對請求字段不固定(存在非必填字段)的接口,可使用redis的scan命令范圍掃描(千萬別用keys命令[2]!用了等著被優(yōu)化吧)

要更新的接口、對應(yīng)key及匹配規(guī)則可能如下表:

接口key匹配規(guī)則
Int1[a:xx;]b:xxx;%s;scan正則1:a:xxx;*
scan正則2:

b:xxx;



Int2a:xx;%s;拼唯一鍵

4. 緩存穿透

無論查詢出的列表是否為空,都寫入緩存。但在業(yè)務(wù)會返回多種錯誤碼時,不建議采用這種方式,復(fù)雜度高,成本太大。

2. 兼容性

兼容性主要考察接口的設(shè)計,為兼容多個業(yè)務(wù)側(cè),需要將請求參數(shù)以及響應(yīng)參數(shù)設(shè)置的盡可能靈活。在設(shè)計接口時,切忌一定要和所有的業(yè)務(wù)側(cè)對齊,否則可能導(dǎo)致滿盤皆輸!

這里有三個技巧:

1.提供可訪問鏈接的文檔,供調(diào)用方即時查閱(一般公司都有知識庫)。2.請求參數(shù)不能過多,且要易于理解,不能為了強制兼容而設(shè)置過于復(fù)雜的參數(shù),必要時可針對某一業(yè)務(wù)側(cè)定制接口。3.響應(yīng)參數(shù)盡量多(多不是濫),要知道每次增加返回字段都要修改代碼,而適當(dāng)冗余的字段避免了此問題。

3. 消息通知

上面難點中提到:狀態(tài)流轉(zhuǎn)系統(tǒng)與查詢系統(tǒng)、其他業(yè)務(wù)側(cè)存在互相發(fā)送通知的交互,在查詢系統(tǒng)收到通知后,要對緩存進(jìn)行即時更新,因此對消息的實時性要求很高

這里最初有兩種方案:

1.各系統(tǒng)提供回調(diào)接口,用于接收通知。能保證實時性,但是各系統(tǒng)間緊耦合,不利于擴(kuò)展。2.使用消息隊列,實現(xiàn)應(yīng)用解耦及異步消息。

最后還是果斷采取了第二種方案,并選用公司自研 TubeMQ 萬億級分布式消息中間件[3](已開源Apache孵化),原因如下:

1.狀態(tài)流轉(zhuǎn)系統(tǒng)的通知數(shù)據(jù)之后可能存在其他消費方,使用消息隊列利于擴(kuò)展,對代碼侵入性也少2.消息隊隊列可持久化消息3.TubeMQ支持消費方負(fù)載均衡,性能高4.TubeMQ容量大,可存放萬億數(shù)量級消息5.支持公司自研組件,便于形成統(tǒng)一規(guī)范(類似現(xiàn)在的全業(yè)務(wù)上云)

在技術(shù)選型和確定方案時,不僅要關(guān)注當(dāng)前的業(yè)務(wù)需求,也要有一定的前沿視角。

***險評估

切忌,在使用中間件/框架前,要盡可能多的進(jìn)行了解可能帶來的風(fēng)險,一般公司內(nèi)都有KM(知識庫),可利用好內(nèi)部資源或者google!

這里我主要評估了TubeMQ帶來的風(fēng)險,做一些分享,非技術(shù)的同學(xué)建議直接跳過!

TubeMQ風(fēng)險

1. 消息可靠性

Tube性能高,但是不保證消息的絕對可靠!

Tube系統(tǒng)主要在兩個地方可能會有數(shù)據(jù)丟失:

1.第一是Tube采取了Consumer信任模型,即數(shù)據(jù)一旦被Consumer拉取到本地,就默認(rèn)會消費成功,如果Consumer在實際消費的過程中出現(xiàn)錯誤,則Tube并不負(fù)責(zé)恢復(fù)。2.由于操作系統(tǒng)pagecache的利用,服務(wù)器斷電或宕機(jī)而可能帶來的數(shù)據(jù)丟失。

經(jīng)評估,本業(yè)務(wù)需同時保障發(fā)送方及消費方的消息可靠性。

2. 消息順序性

Tube沿用了Kafka的分區(qū)設(shè)計思想,而分區(qū)的數(shù)據(jù)消費之間是沒有先后順序關(guān)系的,而且Tube支持消息的異步方式發(fā)送;在這種方式下,網(wǎng)絡(luò)并不能保證先發(fā)送的消息就一定會先到達(dá)服務(wù)端,所以Tube一般不提供順序性的保證。

經(jīng)評估,本業(yè)務(wù)消息消費方允許消息非順序。

3. 消息重復(fù)

Tube集群中,Consumer的消費位置信息由Broker端進(jìn)行管理,所以在某些異常情況下,Broker可能無準(zhǔn)確獲得Consumer的實際消費情況而導(dǎo)致數(shù)據(jù)重復(fù);另外就是出于性能考慮, Consumer的消費位置信息在每次變化時,并不會實時更新到持久化存儲中,而是暫存于內(nèi)存,周期性更新,如果此時broker宕機(jī)即會導(dǎo)致少量的數(shù)據(jù)重復(fù)。

經(jīng)評估,本業(yè)務(wù)消息消費方是相對冪等操作,可允許消息重復(fù)。

4. 監(jiān)控告警

1.公司內(nèi)部提供監(jiān)控平臺,但數(shù)據(jù)有五分鐘延遲,非實時監(jiān)控2.提供了對消費方單分區(qū)滯后的告警,可在公司內(nèi)部平臺直接修改消費配置

那么,如何規(guī)避風(fēng)險呢?設(shè)計了針對消息可靠性和數(shù)據(jù)一致性的解決方案。

消息可靠性方案

1. 生產(chǎn)方消息可靠性

1.Tube可保證消息一定送達(dá),發(fā)送失敗時會自動重發(fā)。2.發(fā)送消息結(jié)束時會觸發(fā)回調(diào),回調(diào)里可判斷ACK狀態(tài),將發(fā)送失敗的消息放入隊列,下次發(fā)送優(yōu)先從隊列里取。

2. 消費方消息可靠性

1.消費失敗時記錄日志,確保消息不丟失

數(shù)據(jù)一致性方案

1. 設(shè)計消息補償接口

消息消費失敗時,會記錄日志,人工排查日志,調(diào)用補償接口再次消費消息。(其實也可以存db消息表,寫任務(wù)去輪詢消費,成本太高)

開發(fā)過程

其實開發(fā)過程沒什么好說的,就是按照技術(shù)方案去敲代碼。

這里也有幾個要點:

1.同時開發(fā)多個項目時,每個項目一個獨立Git分支,合并的時候分批合并,否則別人CR你代碼的時候可能你就要打噴嚏了!2.給每個請求做一些打點數(shù)據(jù)上報,比如請求量、請求時間,便于監(jiān)控統(tǒng)計(這里我將數(shù)據(jù)上報至公司自研網(wǎng)關(guān)的系統(tǒng),可視化監(jiān)控)3.多打日志,打詳細(xì)清晰的日志,便于故障定位

高并發(fā)系統(tǒng)一定要做好完備的日志及監(jiān)控措施!

問題解決

問題主要在測試及線上被發(fā)現(xiàn),問題解決的過程就像坐過山車,經(jīng)常的狀態(tài)是:測試 => 開發(fā) => 測試 => 上線 => 開發(fā) => 測試,循環(huán)往復(fù)。。。

兩個溫馨小貼士:

1.遇到問題時,千萬不要慌,可以先深呼吸幾口氣,因為問題一定是可以解決的,解決不了那么你可能要被解決了!2.解決問題后,千萬別激動,可以先深呼吸幾口氣,因為你還會產(chǎn)生新的問題,而且往往新問題更嚴(yán)重!

這里分享一些印象深刻的問題。

1. 事務(wù)提交時報錯?

原因:事務(wù)依賴的服務(wù)里也有事務(wù),因此事務(wù)里套了事務(wù),破壞了隔離性。

解決:修改代碼,保證事務(wù)隔離性。

2. 依賴包存在,項目啟動卻報錯?

原因:存在多版本jar包,導(dǎo)致Java代碼使用反射機(jī)制動態(tài)生成類是不知道使用哪個版本的依賴的類。

解決:刪掉多余版本jar包。

3. 緩存未即時更新

原因:經(jīng)排查,是由于實際的key數(shù)量可達(dá)千萬級,導(dǎo)致更新緩存前對要刪除的keys的scan掃描效率過低,長達(dá)20多秒!

解決:修改更新緩存方案,不再使用scan掃描,而是拼湊出所有可能的keys,直接delete。

以為這個問題這樣就結(jié)束了?不要忘記上面的小貼士:

“解決問題后,千萬別激動,可以先深呼吸幾口氣,因為你還會產(chǎn)生新的問題,而且往往新問題更嚴(yán)重!”

↓↓↓

4. 緩存仍未即時更新?

原因:某業(yè)務(wù)側(cè)要求數(shù)據(jù)強一致性,而緩存雖然是毫秒級更新,但無法做到真正的實時一致。

解決:為其定制一個接口,該接口不查詢緩存,直接查DB,保證查到的數(shù)據(jù)一定是最新值。

5. 請求卡死

服務(wù)運行一段時間后,發(fā)現(xiàn)所有的請求都被阻塞了!心臟受不了。

原因:jstack打印線程信息后分析thread_dump文件,發(fā)現(xiàn)是由于jedis未手動釋放連接使資源耗盡,導(dǎo)致新的請求中會不斷等待jedis連接資源釋放,從而卡死。

解決:補充釋放資源代碼即可。

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

原因:誤用cat命令查看未分割的原始日志文件(31G?。。。瑢?dǎo)致磁盤IO直接刷爆!

解決:使用less、tail、head等命令替換cat,并移除已備份的大日志文件

7. 進(jìn)程閃退

排查:通常jvm進(jìn)程閃退是有錯誤日志的,但是并沒有找到,排查陷入絕境。沒辦法,只能祈禱問題不再復(fù)現(xiàn)。后來問題真的沒出現(xiàn)過了,謝謝謝謝!

原因:最后,經(jīng)詢問,是有人手動kill掉了這個進(jìn)程。。。好的,開啟問候模式

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

定位思路:先看消息是否被消費,再看對消息的處理是否正確

排查:查看線上日志,發(fā)現(xiàn)消息并未被消費;但是查看監(jiān)控界面,發(fā)現(xiàn)消息被測試環(huán)境的機(jī)器消費了!?。?/p>

原因:由于測試環(huán)境和線上環(huán)境屬于同一個消費組,當(dāng)消息到達(dá)時,同一個消費組只有一個消費者能夠成功消費該消息,被測試環(huán)境消費掉了,導(dǎo)致線上環(huán)境數(shù)據(jù)沒更新。

發(fā)現(xiàn)這個問題的時候,已經(jīng)是上線前一天的深夜。。。再申請一個消費組已經(jīng)來不及了,情急之下,只能先下掉測試環(huán)境的服務(wù)。第二天申請好消費組后,根據(jù)環(huán)境去區(qū)分使用哪個消費組就可以了,這樣每個消費組都會消費消息,成功避免了消息競爭。

方法笨了點,有用就行!

9. 報告!流量太大,撐不住?。?/h3>

原因:現(xiàn)有4臺機(jī)器無法支撐百萬并發(fā),需進(jìn)行緊急擴(kuò)容

解決:緊急新申請了10臺機(jī)器,完成初始化配置,成功部署服務(wù)后修改負(fù)載均衡服務(wù)配置,成功增大了并發(fā)度。

小技巧:多機(jī)器做重復(fù)操作時,有兩種快捷的做法

1.利用ssh連接工具自帶的并行操作功能,自動給所有機(jī)器鍵入命令(xshell支持)2.配置好一臺機(jī)器后,可使用rsync命令同步配置至其他機(jī)器(大數(shù)據(jù)的同學(xué)應(yīng)該不陌生)

10. 為什么新增機(jī)器上的服務(wù)沒有記錄日志?

排查:先發(fā)請求測試服務(wù)是否可用。測試發(fā)現(xiàn)服務(wù)是可用的,只是沒有記錄日志。dump_thread發(fā)現(xiàn),日志線程被持續(xù)阻塞。

原因:服務(wù)啟動時,會激活TubeMQ消費者,上面提到,Tube消費者有消費組的概念,同組內(nèi)的消費者會競爭消息(負(fù)載均衡),只有一個消費者會收到消息。由于消費組中的最大消費者數(shù)量等同于配置的數(shù)據(jù)分區(qū)數(shù),導(dǎo)致新增機(jī)器的服務(wù)中,消費者訂閱不成功,訂閱線程持續(xù)占用日志資源(加鎖不釋放),導(dǎo)致日志線程被持續(xù)阻塞。

解決:另一個框架的日志能夠生成,因此影響不大,暫未解決。

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

原因:溝通出現(xiàn)嚴(yán)重問題!

其實工作中,很多同事因為自身業(yè)務(wù)繁忙,可能在核對接口設(shè)計方案的時候不說話,周知的消息不看,給文檔也不看。等他們忙完了,會反復(fù)@你、私聊你詢問。我們一定不要這樣!

解決:緊急電話會議,拉群核對方案

有時4個人能拉4個群。。。

12. 線上出bug了!?。?/h3>

線上出bug,是一件很大的事,必須緊急響應(yīng)。在夢里也得給我爬起來!

原因:測試環(huán)境和線上環(huán)境未必完全一致,且測試環(huán)境未必能測出所有問題。因此驗證時通常需要預(yù)發(fā)布環(huán)境,數(shù)據(jù)使用線上數(shù)據(jù),但卻是獨立的服務(wù)器,保證不影響線上。

解決:緊急排查定位問題,三分鐘成功修復(fù)!

修復(fù)bug有一定的技巧,分享下個人的排錯路徑:

截圖/問題 => 請求 => bug是否可復(fù)現(xiàn),和測試緊密配合 => 數(shù)據(jù) => 數(shù)據(jù)源(真實數(shù)據(jù)與接口數(shù)據(jù)是否一致) => 數(shù)據(jù)處理

解釋一下:

通常發(fā)現(xiàn)問題的是運維、用戶或者測試,他們會拋出一個問題或者問題的相關(guān)的截圖,這時,我們要快速想到這個問題對應(yīng)的功能(即對應(yīng)的請求/接口),然后讓問題描述者盡可能多的提供信息(比如請求參數(shù)、問題時間等)。

如果問題時間較久,看日志及監(jiān)控不易排查,可以詢問是否可以造一個復(fù)現(xiàn)該問題的case,這樣只需觀察最新的日志即可,方便排錯。

定位到請求后,我們要分析請求及響應(yīng)的哪些數(shù)據(jù)是異常的,即定位關(guān)鍵數(shù)據(jù),然后定位數(shù)據(jù)來源(是從數(shù)據(jù)庫查的,還是從緩存查的),并觀察響應(yīng)數(shù)據(jù)與真實數(shù)據(jù)源是否一致。如果不一致,可能是業(yè)務(wù)邏輯中對數(shù)據(jù)的處理出現(xiàn)了問題,再進(jìn)一步去做分析。

高效溝通建議:描述問題,盡量用數(shù)據(jù)說話,別光截圖,要提供完整的數(shù)據(jù)信息,有助他人分析。

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

這是一個可以預(yù)見的問題。還好已經(jīng)在項目中配置了郵件告警,能夠報告錯誤數(shù)據(jù)的信息,錯誤數(shù)據(jù)量也不大。

解決:修復(fù)導(dǎo)致錯誤數(shù)據(jù)的bug后,編寫程序循環(huán)所有錯誤信息并生成請求list,然后手動發(fā)送請求,刷新線上不同步數(shù)據(jù)即可。

設(shè)計時還是要盡可能考慮到風(fēng)險,可以按照問題的嚴(yán)重程度做分級報警策略(短信 > 郵件 > 通訊軟件)。

14. 線上機(jī)器OOM?。?!

上線三天后發(fā)現(xiàn)的問題,部分線上機(jī)器竟然出現(xiàn)了OOM(堆內(nèi)存溢出)的情況,導(dǎo)致服務(wù)不可用。

血淚教訓(xùn)

1.有問題一定盡可能在測試環(huán)境去解決,否則線上出問題對心臟很不友好2.不要盲目樂觀,以為上線就沒問題,要多驗證,保持警惕。

PS:上線后如果發(fā)現(xiàn)問題,會經(jīng)歷如下的流程,我稱它為happy流程:

上線后的變更流程:

undefined

當(dāng)發(fā)現(xiàn)DB服務(wù)的bug后,你只需要改DB服務(wù)的一行代碼。你需要重復(fù)如下流程:

1.修改DB服務(wù)的一行代碼2.跑單元測試3.DB服務(wù)打成依賴包4.修改“狀態(tài)流轉(zhuǎn)系統(tǒng)”、“查詢系統(tǒng)”對DB服務(wù)的依賴包(改動版本號/更新本地緩存拉取最新包)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讀代碼,通過CR9.合并分支10.發(fā)布“狀態(tài)流轉(zhuǎn)系統(tǒng)”、“查詢系統(tǒng)”至線上環(huán)境,每發(fā)一臺機(jī)器,都要進(jìn)行一次驗證(滾動部署)11.再次發(fā)現(xiàn)新的bug

這是一件惡心到爆炸的事情,但是在這個過程中我們發(fā)現(xiàn),2、6、8狀態(tài)時,是存在空余時間的,這個時候我們可以做做其他工作,記錄一下工作內(nèi)容、問題等 刷刷抖音,看看???。

總結(jié)

首先總結(jié)一下這個項目各階段的耗時:

·理解需求:5%·開發(fā):15%·溝通確認(rèn)問題:30%·測試及驗證:30%·上線及驗證:20%

其中,修復(fù)bug貫穿后面的幾個流程,大概占了總時間的60%。

項目過程存在的問題:

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

自我感覺良好的地方:

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

成長與收獲:

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

后續(xù)

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

如下:

1. 兩個系統(tǒng)中有部分相同的配置,目前采用復(fù)制粘貼的方式去同步

這種方式的優(yōu)點是比較簡單,無需額外的操作。但缺點也很明顯,如果一個系統(tǒng)的配置改了,而忘了修改另一個系統(tǒng)的配置,就會出現(xiàn)錯誤。

事實上,可以引入一個配置中心,集中管理配置文件,并且支持手動修改、多環(huán)境、灰度等功能。

公司內(nèi)部做了調(diào)研,發(fā)現(xiàn)了一個不錯的開源協(xié)同項目。當(dāng)然也可以采用阿里的Nacos或攜程的Apollo。

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

無法保證進(jìn)程不閃退,但是可以采取對進(jìn)程實時監(jiān)控,并自動對閃退進(jìn)程進(jìn)行重啟的策略。

實現(xiàn)方式有兩種:

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

由于公司內(nèi)部的平臺比較完善,我選擇第二種方式。

原來自己寫過一個分布式郵件調(diào)度平臺[4],參考了分布式任務(wù)調(diào)度平臺的實現(xiàn)方式,大家有興趣可以了解下原理,感覺對拓寬后端思路很有幫助。

工作簡單而不簡單,做著有意義的事就好~

================================ 此處回答一些牛友們的問題,歡迎牛友們拋出疑問、指出不足、積極討論。

問題討論

1. 事務(wù)依賴的服務(wù)也有事務(wù),怎么處理?

答:同一個數(shù)據(jù)訪問對象(dao)開啟多個事務(wù)才會出現(xiàn)此問題,處理方式是不使用依賴服務(wù)中有事務(wù)的方法。比如可以用for循環(huán)單條刪除來代替批量刪除。

2. 為什么不用主流的Spring + SpringMVC,而是用Jersey + Guice框架?

的確,Spring是主流,生態(tài)好,一般大家都會選擇SpringBoot + Tomcat。但主流不代表適用于所有的業(yè)務(wù)場景,還是要貼合業(yè)務(wù)去做技術(shù)選型。其實這里應(yīng)該拿SpringMVC去對標(biāo)Jersey、Spring對標(biāo)Guice,但實際上SpringMVC也依賴Spring(一家人)。

這里不用Spring有如下幾個原因:

1.系統(tǒng)較小型。Spring和SpringMVC功能雖大而全,但是相對于Jersey,顯得有些重量級,需要做更多的工作(比如編寫配置文件等等)。2.系統(tǒng)僅提供查詢服務(wù)。而Jersey框架專門提供Restful風(fēng)格接口,完全可以滿足需求。3.由于Jersey輕量的特性,支持手動注冊接口,相對Spring更為靈活,與其他框架搭配使用也很方便(比如Guice、Grizzly),不易出現(xiàn)版本沖突。4.Guice可以在一個文件中手動注入管理所有依賴,便于查找。而用Spring的時候我們通常是在每個類上加注解掃包或者編寫配置文件,雖然寫起來爽的飛起,但非常不利于代碼閱讀(import *和lombok也是同理,最好不要用)!

這里也提一下用Grizzly服務(wù)器來替代Tomcat的好處,主要是:

1.性能更高,高并發(fā)場景表現(xiàn)更穩(wěn)定。2.操作管理方便,在代碼中啟動即可(雖然Tomcat也提供了embed版本)。

3. 負(fù)載均衡怎么實現(xiàn)?

企業(yè)負(fù)載均衡一般都是軟硬結(jié)合(例如l5、Nginx)、四七層結(jié)合(例如lvs+keepalived、Nginx)。

要提高負(fù)載,首先增加機(jī)器或擴(kuò)容(以設(shè)置更大的jvm內(nèi)存),給每個機(jī)器部署相同的服務(wù),然后配置負(fù)載均衡器,增加到新機(jī)器的路由即可。當(dāng)然完成上述操作后要去做驗證,看是否有請求路由到了新機(jī)器。

緩存和DB都是集群的,提供統(tǒng)一接口供查詢服務(wù)調(diào)用,不用擔(dān)心各機(jī)器的查詢結(jié)果不一致。

References

[1] 各服務(wù)器性能對比: https://blog.csdn.net/antony1776/article/details/78962535
[2] 千萬別用keys命令: https://blog./2018/09/21/redis_incident/
[3] TubeMQ 萬億級分布式消息中間件: https://tubemq./en-us/
[4] 分布式郵件調(diào)度平臺: https://www.bilibili.com/video/av47442014

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多