1. 程式人生 > >後端工程師都應該知道的最佳實踐

後端工程師都應該知道的最佳實踐

0 前言

《On Designing and Deploying Internet-Scale Services》是一篇非常經典的論文,例舉了設計和部署網際網路規模的服務要注意的方方面面,其核心內容是自動化、輕依賴、可監控且資訊準確、可應急。

上一篇內容翻譯了《On Designing and Deploying Internet-Scale Services》,本篇文章進行總結,對以下各個部分(忽略了硬體部分)的核心原則進行提煉,便於時常回顧自查。建議大家有時間都閱讀一些原文。

  1. 整體設計

  2. 自動化管理和配置

  3. 依賴管理

  4. 釋出週期和測試

  5. 運維和容量規劃

  6. 審計、監控和報警

  7. 優雅降級和准入控制

 

1 整體設計

面向失敗設計(design for failure)

  1. 大規模服務中機器故障是頻繁發生的(大規模服務中,機器數足夠多,那麼每天都可能會發生磁碟、網路等故障)

  2. 常規的機器故障不能依賴於人工介入恢復

  3. 故障恢復過程應該足夠簡單,且經常被測試

  4. 可以考慮永遠採用暴力關閉(比如kill -9)的方式停止服務,來檢驗故障恢復邏輯

冗餘和故障恢復(redundancy and fault recovery)

  1. 任意伺服器在任何時候出現故障不會影響服務的SLA

  2. 考慮每個元件,或者多個元件同時失敗時系統如何執行(明確系統可以接受的情況,比如強依賴DB,DB故障後系統不可用是預期內可接受的)

  3. 當叢集足夠大的時候,多個元件同時故障的概率會大大提高,並且未來一定會發生

通用硬體(commodity hardware slice)

  1. 同等計算/儲存能力下,由普通伺服器組成的大叢集要比由大型伺服器組成的小叢集更便宜

  2. 大叢集中普通伺服器的故障比小叢集中大型伺服器故障造成的影響要小

單一版本軟體(single-version software)

  1. 保持單一版本的軟體,可以使運維成本降低

  2. 為了保持單一版本,需要保證在版本演進時不造成使用者體驗的損失(儘量要保持相容)

多租戶(multi-tenancy)

  1. 讓多個租戶共享一個物理叢集,而不是為每個租戶部署一個物理叢集,這樣才能大大降低運維成本

快速的服務健康檢查(quick service health check)

  1. 提供一套快速的測試機制,一旦這個測試通過就能保證基礎的功能沒有問題,程式碼可以執行Check In,這將大大提高開發效率(比如編寫足夠好的單元測試,保證每次check in程式碼時這些測試都能執行通過,且這些測試保證了程式碼基礎功能的正確性)

在完整環境下進行開發(develope in the full environment)

  1. 儘量保證能提供一個完成的環境給開發人員進行測試,因為開發人員需要確認變更程式碼除了通過自己的測試外,還要不影響系統其它元件的功能(最好是能本機啟動一個完成的環境,這樣將大大提高測試效率)

零信任依賴元件(zero trust of underlying components)

  1. 考慮依賴的元件一定會掛掉,並考慮如何在它掛掉後提供服務,比如:

    1. 以只讀模式提供服務(降級)

    2. 繼續為未受影響的使用者提供服務(隔離)

不重複實現(do not build the same functionality in multi components)

  1. 避免在多個元件中實現相同的功能(保證程式碼不重複、功能不重複)

一個節點或者叢集不應該影響另一個節點或者叢集(one pod or cluster should not affect another pod or cluster)

  1. 一個服務由若干個節點或者子叢集組成,保證每個節點和叢集的獨立性(避免雪崩)

  2. 當依賴不可避免時,儘量將依賴放到叢集內部

允許人工應急干預(allow rare emergency human intervention)

  1. 將系統設計的儘量自動化,避免人工介入

  2. 但是人工介入是不可避免的,將人工介入的步驟製作成指令碼程式,且這些程式要經常進行測試

  3. 需要在生產環境進行演練,沒有經過生產環境演練的程式在應急時是不可靠的

保持簡單和健壯(keep things simple and robust)

  1. 複雜的演算法和元件互動會將除錯和部署變得困難

  2. 一個總體的原則是:超過一個數量級的優化才值得去做,只有幾個百分點的提升和改進是不值得去做的

在所有層級進行准入控制(enforce admission control at all levels)

  1. 在服務入口設計准入控制,避免請求繼續進入已經過載的系統

  2. 在所有重要元件的入口都提供准入的控制(比如核心的非同步處理邏輯,控制佇列的大小)

  3. 儘量提供優雅降級的能力,而不是直接無法提供服務

服務拆分(partition the service)

  1. 分割槽應該是無限可調的,不應該綁在任何物理世界的實體上,否則容易出現熱點問題

理解網路(understand the network design)

  1. 在早期就去了解系統最終部署的物理架構,網路架構,跨資料中心的情況等

分析吞吐和延遲(analyze throughput and latency)

  1. 分析關鍵操作的吞吐和延遲,瞭解這些操作對系統的影響

  2. 針對每個服務需要跟蹤這些指標來為擴容等操作提供依據

將工具作為系統的一部分(treat operations utilites as part of the service)

  1. 開發、測試、運維的工具都需要進行Code Review,跟程式碼一起維護

  2. 通常這些工具非常重要但是又沒有被測試和維護

理解訪問模式(Understand access patterns)

  1. 當規劃新特性時,一定要考慮它給後端儲存帶來的負載。

  2. 通常服務模型和服務開發者所在的抽象層次太高了,以至於他們無法注意到負載給底層儲存資料庫帶來怎樣的影響。

  3. 一個最佳實踐是SPEC(Standard Performance Evaluation Corporation,系統性能評估測試)加上一節:“這個feature對系統其它部分有什麼影響?”然後feature上線時驗證負載的情況是否符合。

對一切進行版本化(version everything)

  1. 目標是隻執行維護一個版本,但是釋出、灰度過程會執行多個版本

  2. 保證N和N-1版本是相容的

保留上一次釋出的所有測試用例(keep the unit/functional tests from the last release)

  1. 這些測試用來保證上一個版本的特性沒有被破壞掉

  2. 持續性的在生產環境跑測試

避免單點失敗(avoid single points of failure)

  1. 優先採用無狀態的架構,保證水平擴充套件的能力

  2. 不要把請求和使用者繫結到特定的伺服器上,採用負載均衡分配到一組伺服器上

  3. 資料庫很難解決單點問題,要合理的拆分Partition

 

2 自動化管理和配置

在設計和部署之後進行服務的自動化是非常困難的。成功的自動化應當是簡單和清晰的,易於做出運維判斷的。這反過來又取決於服務的設計,必要的時候可以犧牲一些吞吐和延遲來達到自動化的目的。

  1. 所有的操作都需要支援重啟,所有的持久化資料都需要有備份

  2. 支援跨分割槽部署(geo-distribution)

  3. 自動化的安裝和配置

  4. 配置和程式碼作為整體提交,將配置和程式碼作為一個整體進行管理

  5. 意識到多系統故障是常態

  6. 始終堅持對非臨時的狀態資料進行備份

  7. 讓部署過程保持簡單

  8. 停掉資料中心,關閉機架,讓伺服器掉電。定期引入人為故障,不斷暴露系統、網路、服務中的弱點

 

3 依賴管理

有如下情況的依賴,那麼依賴管理是有意義的:

  1. 依賴的元件很大或者很複雜

  2. 依賴的服務的價值在於它是單一中心例項的

第一種情況的例項是儲存和一致性演算法的實現。第二種情況的例項是身份管理系統。這些系統的價值在於,他們是單一的共享例項,無法採用多例項避免這種依賴。

假設滿足以上條件,管理他們的最佳實踐如下:

  1. 考慮呼叫延遲:考慮外部呼叫的延遲,不要讓一個服務或者元件的延遲導致其他地方的延遲

  2. 考慮失敗隔離:架構需要能保持隔離,避免級聯故障

  3. 使用可靠的元件:使用穩定的版本,穩定版本總是比嚐鮮版本要好,哪怕新feature有多麼的誘人

  4. 服務間的監控和告警:通過監控和告警,保證一個服務導致另一個服務過載的情況可以被發現

  5. 依賴雙方有一致的設計目標:被依賴元件的SLA需要和依賴者保持一致

  6. 模組解耦:保證一個服務可以在依賴的服務故障時依舊提供服務,哪怕是降級了服務的能力(對於非強依賴的元件發生故障,要保證繼續提供服務,比如以只讀模式提供服務等)

 

4 釋出週期和測試

推薦在新版本的服務經過標準的單元測試、功能測試和類生產環境的測試後,就進入到一個受限制的生產環境進行最後的測試。嚴格遵循以下規則:

  1. 生產環境要保證冗餘,當新服務發生故障時能快速的恢復狀態

  2. 絕對不能破壞資料或狀態的一致性

  3. 錯誤必須能被檢測到,同時工程師團隊必須持續監控受測試程式碼系統狀態

  4. 保證所有變更能被回滾,且回滾操作是經過驗證的

一些釋出和測試相關的最佳實踐:

  1. 頻繁釋出:有點反直覺,但是頻繁的釋出可以避免大爆炸式的變更,建議釋出週期最長不超過3個月,甚至做到按周釋出

  2. 使用生產環境的資料發現問題:收集最原始的資料來反映系統的狀態,減少誤報,分析資料的趨勢;讓系統的健康狀況清晰可見——最好在自己的系統上就包含系統的健康狀況

  3. 在開發中投入更多精力:有些問題看似是運維問題,實際是開發設計的問題,提前做好開發和設計能減少運維問題;將更多的精力投入到設計和開發階段,避免問題在運維階段才被發現

  4. 支援回滾到特定版本:必須支援回滾到特定的版本來做應急

  5. 保持向前和向後相容:保持相容才能做回滾,否則將因為回滾後無法解析磁碟上的資料等問題導致故障

  6. 壓力測試:以兩倍的負載來對系統進行壓測(根據實際情況,以高於預期的負載進行壓測)

 

5 運維和容量規劃

要高效運維服務,關鍵在於構建系統時消除各種運維互動過程。目標在於讓一個高可靠的、7*24小時可用的服務只需要5*8小時工作的運維團隊維護即可。

關於運維和容量相關的最佳實踐:

  1. 任何運維指令碼都需要經過測試,沒有經過頻繁測試的工具是無法使用的;不要開發任何團隊成員沒有勇氣去使用的工具;

  2. you build it, you manage it:如果開發人員經常在半夜被叫醒,那麼他們會去優化系統;如果運維人員經常半夜被叫醒,可能會擴容運維團隊

  3. 只進行軟刪除:只對刪除資料進行標記而不進行刪除,避免因誤操作導致的資料丟失

  4. 追蹤資源分配情況:每個服務需要將線上使用者數,使用者每秒的請求數這些資料和機器負載及資源情況進行繫結跟蹤

  5. 讓一切可配置化:任何可能在系統中發生變更的東西都應該是在生產環境下可配置和調整的,而不需要改變程式碼;即使某個值看起來沒有很好的在生產環境中發生變更的理由,如果很容易的話,也應該將它們做成可配置的

 

6 審計、監控和報警

審計、監控、告警是避免故障,以及保證故障及時被處理的重要手段,關於審計、監控、報警的最佳實踐:

  1. 審計一切:有任何配置發生變更都需要記錄下來:誰,在什麼時候,改了什麼;生產環境出了問題第一個要考慮的問題就是最近是否做了什麼變更

  2. 報警評價標準:只在需要的時候報警,如果報警之後不需要做任何錯誤,那麼這個報警就不是必要的;報警和故障比應該是1,沒有產生報警的故障數應該是0

  3. 從使用者的角度看問題:進行端到端的測試,保證重要和複雜的邏輯都被測試到

  4. 延遲是最難發現的問題:像是IO緩慢但是還沒有不可用,這種情況是很難發現的,要做好監控

  5. 可配置的日誌:可以動態調整日誌級別以幫助快速定位問題

  6. 快速定位問題:系統執行重要的操作時要列印必要的日誌記錄上下文資訊

 

7 優雅降級和准入控制

有些時候比如收到DOS攻擊或者模式發生某些改變時,會導致負載突然爆發。服務需要能夠進行優雅的降級及准入控制。兩個最佳實踐:“Big Red Switch”和准入控制,需要針對每個服務進行量身定製。但是這兩個都是非常強大和必要的。

  1. Big Red Switch:支援應急開關。大體來說“Big Red Switch”是一種當服務不再滿足SLA或者迫在眉睫時,可以採取的經過設計和測試的動作。將優雅的降級比喻為“Big Red Switch”,稍微有些不太恰當,但核心的意思是指那種可以在緊急情況下摒棄那些非關鍵負載的能力。

  2. 准入控制:當系統已經過載時,需要適當地在最前端拒絕掉部分請求,以免系統進入一種完全無法恢復的狀態

  3. 漸進式准入控制:當系統慢慢恢復時,需要可以逐漸讓請求進入,而不是一次全部放開,避免恢復後一時間大量的請求湧入導致系統再次故障

 

相關推薦

工程師應該知道最佳實踐

0 前言 《On Designing and Deploying Internet-Scale Services》是一篇非常經典的論文,例舉了設計和部署網際網路規模的服務要注意的方方面面,其核心內容是自動化、輕依賴、可監控且資訊準確、可應急。 上一篇內容翻譯了《On Designing and Deployi

前後分離師傅們應該知道的一些基本前端知識

跨域問題 分類 port 什麽是 格式 url 就會 是否 option 寫下此文,是因為本人作為前端小白,經常遇到同樣小白的後端,常常不得不三番五次科普一些前端的基礎知識,特此做些總結,也方便有下次的話,直接拿出來給對方看。 1. 什麽是ajax 對

每個程式設計師應該知道的 15 個最佳 PHP 庫

1. PChart PChart是一個令人印象深刻的PHP庫,可以以一種視覺化圖表的形式生成文字資料。資料可以展示為柱狀圖,餅狀圖,以及其他格式。使用SQL查詢可以幫助PHP指令碼建立令人驚歎的圖表和圖形。 2. PHP CAPTCHA PHP CAPTCHA是另一個偉

工程師以後這麼寫程式碼了 現在的人真牛逼

工欲善其事,必先利其器,分享一篇關於後端工程師如何將編碼速度提升10倍的文章原文來自下面連結  有興趣可以瞭解下這款國內人氣很旺的JAVA程式碼生成器基於拖拽,不用寫複雜的模板,支援多種資料庫,適配wap,管理後臺各種功能全有 免費開源 地址:https://blog.cs

每一個JavaScript開發者應該知道的10道面試題

結束 vid 認識 本質 特定 更新 mixin 構造函數 程序猿 JavaScript十分特別。而且差點兒在每一個大型應用中起著至關關鍵的數據。那麽,究竟是什麽使JavaScript顯得與眾不同,意義非凡? 這裏有一些問題將幫助你了解其真正的奧妙所在:

用Canvas生成隨機驗證碼(前端可以)

ntb inf pre text contex back data listen nload 一 、使用前端生成驗證碼 <!DOCTYPE html> <html> <head> <meta charse

Java 工程師實習總結

規範 nbsp 直接 並發 mys 變化 技巧 ted list 2017-9-16 8 月份開始到現在,進行了一個多月的實習,崗位是 Java Web 後端開發。這過程學到的知識著實比自學要來得多,而且也讓我意識到需要學習的知識也更加多。在這裏我會在比較大的方面總結這次實

工程師的技術

數據庫 協議 dock docker 網絡編程 掌握 開發 滿足 http 1 後端開發語言 ————> python/lua/php/java/go/ruby....(編程語言是表達思想的工具) 2 運維————> shell腳本,docker 3 安全 ——

今日頭條2017工程師實習生筆試題 - 題解

進制 true 字符串 從右到左 試題 imp 最終 create head 今日頭條2017後端工程師實習生筆試題 最大映射 題意 給n(不超過50)個字符串,每個字符串(長度不超過12)由A-J的大寫字符組成。要求將每個字符映射為0-9,使得每個字符串可以看作一個整數(

極速彩源碼搭建步驟 Java 開發者應該知道的 5 個註解

推出 註解 http lean error: java編譯 lse 隱式 滿足 自 JDK5 推出以來,註解已成為Java生態系統不可缺少的一部分。雖然開發者為Java框架(例如Spring的@Autowired)開發了無數的自定義註解,但編譯器認可的一些註解非常重要。 在

每一個程序員應該知道的高並發處理技巧、創業公司如何解決高並發問題、互聯網高並發問題解決思路、caoz大神多年經驗總結分享

海量數據 限定 微博 https 2.3 tst 日誌分析 如何 ive 目錄: 場景及解決方法解讀 認識負載 數據跟蹤 腦圖、caoz大神公眾號分享 參考資料 秉承知其然及其所以然的思路,以撥蟬拔絲的思維,一一解讀各個技巧的使用場景: a.網絡通道+前臺控制 原因

炒股,新手應該知道的股票賬戶的10大功能

功能 現場 價格 賣出 時間 相同 直接 開始 買賣 [炒股,新手都應該知道的股票賬戶的10大功能原文](http://blog.sina.com.cn/s/blog_18ba61b410102xf2f.html) 對於剛接觸股票的

每個Ubuntu 18.04用戶應該知道13鍵盤快捷方式!

邊緣 我不 roc 字母 ctrl + c 版本 strong 通過 ffffff 了解鍵盤快捷鍵可以提高你的工作效率。這裏有一些有用的Ubuntu快捷鍵,可以幫助你像專業版一樣使用Ubuntu。 你可以使用鍵盤和鼠標結合的操作系統~~~ 註意:下面提到的鍵盤快捷鍵適用於

雙11來臨,Java工程師書單推薦

《Effective Java 中文版》 豆瓣評分:9.1【1235 人評價】 推薦理由:本書介紹了在Java程式設計中78條極具實用價值的經驗規則,這些經驗規則涵蓋了大多數開發人員每天所面臨的問題的解決方案。 友情提示:同推薦《重構 : 改善既有程式碼的設計》、《程式碼整潔之道》、《程

WYHL 2018.11.12 工程師面試總結

一、WYHL公司面試總結   過程: BOSS上投遞了簡歷,後來hr聯絡後簡短了解後。技術官電話面瞭解了下   一個周後,hr聯絡到公司面試。 時間2018.11.12 早上10:00 (因為公交遲到了幾分鐘) 以後注意出發時間 第一個面試官大概是海歸吧!形象氣質風

【轉載】使用訊息號除錯SAP標準程式 (作為SAP顧問應該知道的ABAP程式除錯方法)

摘要:雖然SAP系統的穩定性很不錯,大部分問題不需要通過除錯程式碼來解決。但是,別忘記我們還有很多自開發程式,或者某些配置不完整等,某些情況下通過除錯ABAP程式是一個能快速找到問題根源的方法。本篇主要針對業務模組顧問來講解一種通過訊息號及簡單的程式除錯來定位系統報錯的原因及解決的方法。 正文:

每個電腦科學專業的學生應該知道些什麼?

每個電腦科學專業的學生都應該知道什麼? “每個電腦科學專業的學生都應該知道什麼?”可以把這個問題作為四個問題的結合點來回答: 1.每個學生應該知道什麼才能找到一份好工作? 2.要維持終身就業,每個學生都應該知道些什麼? 3.進入研究生院應該知道什麼? 4.每個學生都應該知道什麼對社會有益

Python 新手玩家應該知道的程式設計技巧 !

近期 ,不少讀者後臺詢問類似這樣的一些問題 :大佬 ,我是一個小白 ,很想學習 Python ,它能做些什麼啊 ?您這邊有什麼好的入門建議嗎 ? 坦白說 ,這類問題算得上一個很不成功的問題了 ,問問題其實是一個技術活 !當然這另說 ,今天統一給新手玩家講一節入門課 ,推薦一些不錯的學習方法和資源。 Pyt

Python 新手玩家應該知道的編程技巧 !

程序 理論 分享 得出 orf 語言 tensor ces 要求 近期 ,不少讀者後臺詢問類似這樣的一些問題 :大佬 ,我是一個小白 ,很想學習 Python ,它能做些什麽啊 ?您這邊有什麽好的入門建議嗎 ? 坦白說 ,這類問題算得上一個很不成功的問題了 ,問問題其實是一

工程師必知必會的前端 css 知識

後端工程師雖然大部分工作都是跟伺服器快取資料庫打交道,但有時也需要寫一些前端程式碼。 有些公司的OAM後臺基本是由後端工程師承包的,所以前端基礎知識是必須要掌握的;就算開發中不直接寫前段程式碼,瞭解前端知識能讓我們跟前端小夥伴更愉快的交流。 Js對於後端小夥伴來說不