一行程式碼引發的恐懼
1
我工作的前5年,都是從事基礎系統研發相關的工作。做過後臺的接入層,後臺的儲存系統,RPC框架。說來不怕你笑話,那個時期裡面,我對程式碼一直有一種恐懼感。這種恐懼是怎麼來的呢?且讓我慢慢說來。
我們所構建的基礎系統,都是使用在億級甚至十億級使用者產品的業務系統之上的。從客戶端(前端)到後臺業務邏輯層,再到基礎架構層,所寫的程式碼是跑在整個呼叫鏈路的最後端的。
你可以認為,幾乎每個使用者的每個請求都會跑到我們寫得那部分的程式碼。
這個對系統帶來的影響是: 一,程式碼出問題後,影響的使用者範圍會很大;二,在這億級甚至十億級使用者量的情況下,每天所帶來的請求可能是千億級,萬億級的,在如此龐大請求量的情況下,幾乎各種奇葩的異常,你都會遇到,程式碼要極其的健壯,一個小異常沒處理好就會帶來大麻煩。
這讓我想起來,我們故障時候的情形。
幾年前,我們每做完一次版本變更,晚上基本都會睡不好,擔心變更的程式碼有問題。對手機的報警簡訊特別敏感,一有風吹草動,立馬就會開啟電腦vpn看看,即使是在深夜凌晨的時候。
我自己有個習慣,每次變更完,都要間隔幾個小時去看看監控曲線和日誌,看看有沒有異常的苗頭,一旦發現有不對勁地方,就會立即著手排查,直到確保沒有問題為止。
不過即使如此,還是不可避免的會出現問題。
半夜兩三點的時候,你的手機突然響起,報警語音機器人跟你說,你有一個重要的監控曲線出現異常,請檢視。然後你的血壓立馬升高,心跳加速,你從床上,一躍而起,開啟電腦,連上公司的VPN,立馬著手排查起來。
幾分鐘後,QA(質量工程師)電話過來,告知你,這個故障目前已經上報到部門故障系統,目前影響的使用者有XXX的數量,請你加快處理的速度,然後你的心跳再次加速。
半小時後,終於有了眉目,這時,你的leader, 電話過來,詢問你是怎麼回事,大概還需要多長的時間,才能處理完畢。待你語焉不詳地回覆完你的leader, 你又開始埋頭,一行行的排查故障。
一個小時後,你終於,將問題定位出來,執行了故障處理方案,例如回滾新的程式碼,或者遮蔽某些機器等。你才終於有了喘息的時間。
(ps: 這裡正確的流程是,出問題後,立馬回滾程式碼,但儲存系統因為資料的關係,在沒有確定原因前不太敢回滾,怕對資料有影響)
你趕緊爬上床去,睡上2-3個小時,因為第二天還要早起,趕到公司,去處理故障的後遺症,資料損壞和資料錯亂。
2
那個時期,我們寫程式碼都是特別小心的,變更,更是極度的謹慎。所以使得自己對程式碼變更有了一種焦慮和恐懼的心理。至少在那時候,寫程式碼不是一件輕鬆的事情。
這個事情,我現在回過頭來看。你可以認為有一部分是人的原因,但仔細的想想,寫程式碼不出bug ,幾乎也是極難做到,所以這裡在研發流程上,其實也是有缺失的。
前期因為業務發展太快,團隊的整體人力跟不上,所以,一開始很多流程,都是很原始的,那時候,是想做但客觀條件不允許。
後來,業務穩定了,流程就規範了不少。比如引入了coverity的程式碼檢查,也推行過測試用例覆蓋,持續整合等。
但最終,並不是所有的流程都延續了下去。比如,程式碼測試用例覆蓋,有的團隊到後面就放棄了,需求變化太快,測試用例成本太高。
coverity倒是自動化程度高,沒啥人力投入,執行了下來。
但我相信不是所有的公司,所有的團隊,都會有這種規範的流程。一個是研發流程成熟度建設的問題,但除此,還有成本,業務迭代速度。在網際網路,產品高速迭代的時候,產品都還沒有存活下來,成熟流程就更不太可能有了。
綜合來看,一種規範,但相對較重的研發流程的建立,應該也是根據具體情況而定的。需要考慮產品的形態,產品迭代的速度,團隊的人力預算成本,產品的生命週期等等。當然,無論怎麼說,反正這不是個人可以決定的事情,如果你所在的團隊有完善的研發流程,那是最好的事情,但如果沒有那麼完善,自己又能夠做些什麼呢?
我的經驗來看,以下的一些措施,對於個人而言也有不錯的效果
測試驅動的開發(TDD)
有段時間,因為業務高速發展,對效能的要求不斷提高,儲存模型也跟隨著不斷迭代改進,所以那段時間的程式碼修改是比較多的,那個時間的焦慮感也特別重。
我記得是在 《重構:改善既有程式碼的設計》中瞭解到TDD的。
簡單來說, 就是先構建測試用例,再開始寫你的功能程式碼。在設計測試用例之前,你需要先定義好模組對外的介面,包括介面的種類,引數,返回值等。
然後,你針對定義好的介面,編寫測試用例。這過程中,你可能會發現介面設計不合理的地方,也需要隨著修改。待你測試用例寫完,基本你的介面也被修改的比較好了,所以TDD還能改善你的介面設計。
後續再為每個介面實現特定的程式碼邏輯。
我當時將這種方法運用到了一個磁碟儲存引擎中,發現相當不錯。我特地花了一週左右的時間寫測試用例。後面,每天實現部分的功能後,都立馬跑測試用例,每次跑完透過,你的心裡都有穩的一B的感覺。有種媽媽再也不擔心我寫的程式碼有bug,被被老闆叼,導致扣工資了。
因為有了完善的測試用例,而且隨著你測試用例不斷的增加和覆蓋,你的信心會越來越足,焦慮自然減少了很多。
不過這種方式,比較適合底層的系統和核心穩定的系統。對於需求多變的系統,構建測試用例的人力付出太大,而且需求一變,已有的測試用例可能失效,導致投入產出比不夠高。
灰度釋出
簡單來說,就是一個特性要上線的時候,不是一下就開放給所有的使用者使用。有點像產品上的內測,只不過是用在技術上。
比如我新增加了一個產品需求,例如就微信裡面的 “看一看”入口,不是一開始就對所有使用者開放的。
首先會上線一個新的客戶端版本,程式碼邏輯已經預埋,但設計了一個開關,對所有使用者都是關閉的。前期,可能會找個千分之一,甚至萬分之一的使用者(隨機或者特定的使用者群體),讓他們使用。
這過程中,收集各種log ,監控,使用者的反饋。來確認和fix 系統存在的各種問題。一般經過兩三週後,如果沒有大問題,就會進一步的放開使用的使用者。比如變成百分之一,十分之一,一直迭代,直至覆蓋全部使用者。
灰度這個思想,在網際網路是特別常用的。客戶端,前端,後臺都可以使用。比如後臺,上線一個新修改後,也不是一下就開放給所有使用者。而是按照某種規則,例如以QQ使用者為例,可能是這種規則
計算Hash值(QQ號) % 1000 <= 灰度使用者的比例(取0 --- 1000)
放量的最小力度就是千分之一,被灰度到的使用者,看到新功能,沒灰度到的使用者不受影響。
這招用在新功能,用在系統最佳化,程式碼重構上都很不錯。
付出的額外成本不大,有的公司有自研的灰度系統,那最好。沒有的話,在重大且沒有把握的功能上,自己加上幾行灰度控制程式碼也不難。
監控和log
監控和log不是什麼新鮮的東西。
工作第一年,我們的技術總監在一次會議上跟我們說:你寫完的程式碼是死的,只有線上上跑的程式碼是活的。監控和log(特別是監控),就像是你程式碼的體徵資訊,隨時反應著你程式碼在實際環境中的執行情況,要高度的重視。
這段話,在後面,我深有感觸。透過完善設計的監控和log,預先發現了很多的問題,也避免了很多,或程式碼bug,或系統設計缺陷導致重大故障。
後面,監控和log的設計,也成了我們方案設計的一部分。一般都會在方案最後,加上必須的監控的點和log點,例如請求數,成功數,失敗數,各種異常數,極端邏輯執行次數等等。
你應該要意識到監控和log的重要性,而且應該要花時間特別地設計。
經過良好設計的監控和log,能發揮的價值,是那種憑感覺隨便加的監控log不可比擬的。
雙寫,雙讀驗證
這招,新業務程式碼用的不多。更多用於基礎系統或者核心系統的最佳化和重構上面。而且有前置條件,需要一個操作可以重複執行(例如只讀操作和冪等的資料操作)。
簡單來說,就是將新舊程式碼,劃分為兩個流程(兩個介面),上線到實際環境,然後在同個模組裡面呼叫。
一個請求進來後,兩個流程分別執行一次,逐位元組做對比(例如 memcmp)新舊流程的結果。新流程的結果只用於對比,返回得依舊是舊流程的結果,所以不影響線上業務。
如果對比失敗,就可能存在異常,要查詢並解決,在實際環境跑了幾天後,都沒問題,就可以採用灰度的方式,進一步放量。不過,一般業務不常使用,在基礎系統上使用比較多,這裡就不展開了。
其他
另外,對於客戶端,還有熱補丁機制,客戶端log收集系統等。不過這種需要的開發量比較大,一個人不一定可以搞定,可能需要有個小團隊來完成。
最後
軟體工程是個龐大的話題,我也沒能力論述這麼大的話題。這裡給大家講了個以前的故事,並且分享了我常用的一些低成本,但可以提高線上程式碼質量的方法,給大家參考參考。大家有好的做法,也歡迎在留言裡分享出來。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31499124/viewspace-2640680/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 克服命令列恐懼症命令列
- 測試人員對程式設計天生“恐懼”麼?程式設計
- 《密特羅德 生存恐懼》Fami 通評測:完美駕馭恐懼與安心間的微妙平衡
- 《層層恐懼2》今日正式在多平臺發售!
- 《密特羅德 生存恐懼》的千層套路
- 一行程式碼引發的”血案“!!!(軟體開發、專案管理、skycto JEEditor)行程專案管理
- 如何克服解決Git衝突的恐懼症?(序)Git
- 恐懼華語歌壇入伏天費用胡椒
- 「讀懂原始碼系列1」還在恐懼讀原始碼?看完這篇就不怕了原始碼
- 如何克服解決Git衝突的恐懼症?(Git分支策略)Git
- 如何克服解決Git衝突的恐懼症?(Git高階篇)Git
- 還記得面試時被演算法支配的恐懼嗎?面試演算法
- 讓我們看破恐懼!解析恐怖類遊戲的慣用套路遊戲
- 一行 CSS 程式碼的魅力CSS
- 如何克服解決Git衝突的恐懼症?(Git移交提交記錄)Git
- 如何克服解決Git衝突的恐懼症?(Git基礎篇--下)Git
- 如何克服解決Git衝突的恐懼症?(Git基礎篇--上)Git
- 如何克服解決Git衝突的恐懼症?(Git入門介紹)Git
- 如何克服解決Git衝突的恐懼症?(Git高階話題)Git
- 那一天,我被Redis主從架構支配的恐懼Redis架構
- 《密特羅德 生存恐懼》:苦等多年的系列正統續作
- 騰訊成為《靈媒》《層層恐懼》研發商最大股東,佔股22%
- 如何克服解決Git衝突的恐懼症?(Git四大元件)Git元件
- 黑客利用人們對冠狀病毒的恐懼傳播惡意軟體黑客
- 做好準備就能預防Jumpscare?《人偶館綺幻夜》的恐懼心理探究
- Xcode 程式碼提示失效以及引發的感想XCode
- 用無人機打點作畫,密集恐懼症患者慎入!無人機
- 第一行程式碼——書的理解行程
- 人工智慧(AI)在市場營銷中的應用——從恐懼到接受人工智慧AI
- 《暗夜長夢》CJ試玩報告:開啟心結 直面恐懼
- 你為什麼會恐懼人工智慧?它有什麼可怕之處?人工智慧
- 一行程式碼建立cell行程
- 元宇宙的“吸金”時刻:大廠狂買、VC重金入場,恐懼又貪婪元宇宙
- 從《層層恐懼》到《靈媒》,這支小團隊如何找到自己的賽道?
- 讓 Chrome 崩潰的一行 CSS 程式碼ChromeCSS
- 一行能裝逼的JavaScript程式碼的延伸JavaScript
- Neuron雜誌:研究者發現前額葉中調控社交恐懼的去抑制神經微環路
- 在玩恐怖遊戲時,到底是什麼讓你感到如此恐懼?遊戲