目錄
通信協議
REST API 與 GraphQL
gRPC 如何工作?
什么是Webhook?
如何提高應用程序接口的性能?
HTTP 1.0 -> HTTP 1.1 -> HTTP 2.0 -> HTTP 3.0 (QUIC)
SOAP vs REST vs GraphQL vs RPC
代碼優先與應用程序接口優先
HTTP 狀態代碼
API 網關有什么作用?
如何設計有效、安全的應用程序接口?
TCP/IP 封裝
為什么 Nginx 被稱為 “反向 “代理?
常見的負載平衡算法有哪些?
URL、URI、URN - 您知道它們的區別嗎?
CI/CD
簡單解釋 CI/CD 管道
Netflix 技術棧(CI/CD 管道)
架構模式
MVC、MVP、MVVM、MVVM-C 和 VIPER
每個開發人員都應了解的 18 種關鍵設計模式
數據庫
云服務中不同數據庫的小抄
為數據庫提供動力的 8 種數據結構
如何在數據庫中執行 SQL 語句?
CAP 定理
內存和存儲器類型
可視化 SQL 查詢
SQL 語言
緩存
數據緩存無處不在
Redis 為什么這么快?
如何使用 Redis?
頂級緩存策略
微服務架構
典型的微服務架構是什么樣的?
微服務最佳實踐
微服務通常使用什么技術棧?
Kafka 為何如此快速
支付系統
如何學習支付系統?
為什么信用卡被稱為 “銀行最賺錢的產品”?VISA/Mastercard 如何賺錢?
當我們在商鋪刷卡時,VISA 是如何運作的?
世界各地的支付系統系列(第 1 部分):印度的統一支付接口(UPI)
DevOps
DevOps vs. SRE vs. 平臺工程。有什么區別?
什么是 k8s(Kubernetes)?
Docker 與 Kubernetes。我們應該使用哪一個?
Docker 如何運行?
GIT
Git 命令的工作原理
Git 如何工作?
Git merge 與 Git rebase
云服務
不同云服務的小抄(2023 年版)
什么是云原生?
開發人員生產力工具
可視化 JSON 文件
自動將代碼轉化為架構圖
Linux]
Linux 文件系統說明
你應該知道的 18 種最常用 Linux 命令
安全
HTTPS 如何工作?
Oauth 2.0 簡明解釋
四大認證機制形式
會話、Cookie、JWT、令牌、SSO 和 OAuth 2.0 - 它們是什么?
如何在數據庫中安全存儲密碼以及如何驗證密碼?
向 10 歲的孩子解釋 JSON 網絡令牌 (JWT)
Google Authenticator(或其他類型的雙因素身份驗證器)如何工作?
真實世界案例研究
Netflix 的技術棧
推特架構 2022
Airbnb 微服務架構在過去 15 年中的演變
Monorepo 與 Microrepo。
您將如何設計 Stack Overflow 網站?
亞馬遜 Prime Video 監控為何從無服務器轉向單體?如何節省 90% 的成本?
迪斯尼 Hotstar 如何在一場比賽中捕獲 50 億個表情符號?
Discord 如何存儲數以萬億計的信息
YouTube、TikTok Live 或 Twitch 上的視頻直播是如何進行的?
?
花了一周的晚上,把youtube 上system-design的視頻像幻燈片一樣的過了一遍,收獲還是挺多的。
好記性不如爛筆頭,剛好周末有空,整理了一下~
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ———ByteByteGo 筆記整理,原文倉庫地址
" 用直觀和簡單的術語解釋復雜的系統。"
?
通信協議
架構風格定義了應用程序編程接口(API)不同組件之間的交互方式。因此,它們通過提供設計和構建 API 的標準方法,確保了效率、可靠性以及與其他系統集成的便捷性。以下是最常用的樣式:
?

- SOAP:
成熟、全面、基于 XML
最適合企業應用
- RESTful:
流行、易于實施的 HTTP 方法
網絡服務的理想選擇
- GraphQL:
查詢語言,請求特定數據
減少網絡開銷,加快響應速度
- gRPC:
現代化、高性能的協議緩沖器
適合微服務架構
- WebSocket:
實時、雙向、持久連接
非常適合低延遲數據交換
- Webhook
事件驅動、HTTP 回調、異步
事件發生時通知系統
REST API 與 GraphQL
在應用程序接口設計方面,REST 和 GraphQL 各有優缺點。
下圖顯示了 REST 和 GraphQL 的快速比較。
?

REST
- 使用 GET、POST、PUT、DELETE 等標準 HTTP 方法進行 CRUD 操作。
- 當你需要在不同的服務/應用程序之間建立簡單、統一的接口時,它就能很好地發揮作用。
- 緩存策略可以直接實施。
- 缺點是可能需要多次往返,從不同的端點收集相關數據。
GraphQL
- 為客戶提供單個端點,以便準確查詢所需數據。
- 客戶端在嵌套查詢中指定所需的確切字段,服務器只返回包含這些字段的優化有效載荷。
- 支持用于修改數據的突變和用于實時通知的訂閱。
- 非常適合聚合多個來源的數據,并能很好地滿足快速發展的前端需求。
- 不過,它將復雜性轉移到了客戶端,如果沒有適當的保護措施,可能會允許濫用查詢
- 緩存策略可能比 REST 更加復雜。
REST 和 GraphQL 之間的最佳選擇取決于應用程序和開發團隊的具體要求。GraphQL 非常適合復雜或頻繁變化的前端需求,而 REST 則適合需要簡單一致的合同的應用。
API 方法都不是萬能的。仔細評估需求和權衡利弊對于選擇正確的風格非常重要。REST 和 GraphQL 都是公開數據和支持現代應用程序的有效選擇。
gRPC 如何工作?
RPC(遠程過程調用)之所以被稱為 “遠程”,是因為在微服務架構下,當服務部署到不同的服務器時,它可以實現遠程服務之間的通信。從用戶的角度來看,它就像一個本地函數調用。
下圖說明了 gRPC 的整體數據流。
?
步驟 1:從客戶端發出 REST 調用。請求體通常為 JSON 格式。
步驟 2 - 4:訂單服務(gRPC 客戶端)接收 REST 調用,對其進行轉換,然后向支付服務發出 RPC 調用。
第五步:gRPC 通過 HTTP2 在網絡上發送數據包。由于采用了二進制編碼和網絡優化,gRPC 據說比 JSON 快 5 倍。
步驟 6 - 8:支付服務(gRPC 服務器)接收來自網絡的數據包,解碼后調用服務器應用程序。
步驟 9 - 11:結果從服務器應用程序返回,經過編碼后發送到傳輸層。
步驟 12 - 14:訂單服務接收數據包、解碼并將結果發送給客戶端應用程序。
什么是Webhook?
下圖顯示了輪詢和 Webhook 的比較。
假設我們運行一個電子商務網站。客戶通過 API 網關向訂單服務發送訂單,訂單服務轉到支付服務進行支付交易。然后,支付服務與外部支付服務提供商(PSP)對話以完成交易。
有兩種方法可以處理與外部 PSP 的通信。
**1.輪詢(Polling)
向 PSP 發送支付請求后,支付服務會不斷詢問 PSP 的支付狀態。幾輪之后,PSP 最終會返回付款狀態。
簡而言之,輪詢有兩個缺點:
- 不斷輪詢狀態需要支付服務的資源。
- 外部服務直接與支付服務通信,會造成安全漏洞。
2.Webhook
我們可以向外部服務注冊網絡鉤子。這意味著:當您有關于請求的最新信息時,請在某個 URL 上給我回電。PSP 完成處理后,將調用 HTTP 請求更新付款狀態。
這樣,編程模式就發生了變化,支付服務就不再需要浪費資源來輪詢支付狀態了。
如果 PSP 一直不回電話怎么辦?我們可以設置一個管家任務,每小時檢查一次付款狀態。
Webhook 通常被稱為反向 API 或推送 API,因為服務器會向客戶端發送 HTTP 請求。使用網絡鉤子時,我們需要注意以下三點:
- 我們需要設計一個適當的應用程序接口,供外部服務調用。
- 出于安全考慮,我們需要在 API 網關中設置適當的規則。
- 我們需要在外部服務中注冊正確的 URL。
如何提高應用程序接口的性能?
下圖顯示了提高應用程序接口性能的 5 種常見技巧。
?

分頁
當結果較大時,這是一種常見的優化方法。結果會以流式方式傳回客戶端,以提高服務響應速度。
異步日志記錄
同步日志記錄每次調用都要處理磁盤,會降低系統運行速度。異步日志記錄會先將日志發送到無鎖緩沖區,然后立即返回。日志會定期刷新到磁盤。這大大減少了 I/O 開銷。
緩存
我們可以將經常訪問的數據緩存到緩存中。客戶端可以先查詢緩存,而不是直接訪問數據庫。如果出現緩存缺失,客戶端可以從數據庫中查詢。Redis 等緩存將數據存儲在內存中,因此數據訪問速度比數據庫快得多。
有效載荷壓縮
可以使用 gzip 等對請求和響應進行壓縮,從而大大縮小傳輸數據的大小。這樣可以加快上傳和下載速度。
連接池
訪問資源時,我們經常需要從數據庫加載數據。打開和關閉數據庫連接會增加大量開銷。因此,我們應該通過一個開放連接池來連接數據庫。連接池負責管理連接的生命周期。
HTTP 1.0 -> HTTP 1.1 -> HTTP 2.0 -> HTTP 3.0 (QUIC)
每一代 HTTP 解決了什么問題?
下圖說明了主要特征。
?

-
1996 年,HTTP 1.0 最終定稿并形成完整文檔。對同一服務器的每個請求都需要單獨的 TCP 連接。
-
HTTP 1.1 于 1997 年發布。TCP 連接可以保持開放以便重復使用(持久連接),但這并不能解決 HOL(行首)阻塞問題。
HOL 阻塞–當瀏覽器允許的并行請求數用完時,后續請求需要等待前一個請求完成。
-
HTTP 2.0 于 2015 年發布。它通過請求多路復用解決了 HOL 問題,消除了應用層的 HOL 阻塞,但傳輸(TCP)層仍存在 HOL。
如圖所示,HTTP 2.0 引入了 HTTP “流 “的概念:這是一種抽象概念,允許在同一 TCP 連接上復用不同的 HTTP 交換。每個流無需按順序發送。
-
HTTP 3.0 第一稿于 2020 年發布。它是 HTTP 2.0 的擬議后續版本。它使用 QUIC 代替 TCP 作為底層傳輸協議,從而消除了傳輸層中的 HOL 阻塞。
QUIC 基于 UDP。它將數據流作為一等公民引入傳輸層。QUIC 流共享同一個 QUIC 連接,因此無需額外的握手和慢速啟動來創建新的 QUIC 流,但 QUIC 流是獨立傳輸的,因此在大多數情況下,影響一個流的數據包丟失不會影響其他流。
SOAP vs REST vs GraphQL vs RPC
下圖說明了 API 時間軸和 API 樣式的比較。
隨著時間的推移,不同的應用程序接口架構風格相繼問世。它們都有自己的數據交換標準化模式。
您可以在圖中查看每種樣式的用例。
?
代碼優先與應用程序接口優先
下圖顯示了代碼優先開發和 API 優先開發之間的區別。為什么要考慮 API 優先設計?
?
- 微服務增加了系統的復雜性,我們需要單獨的服務來服務于系統的不同功能。雖然這種架構有利于解耦和職責分離,但我們需要處理服務之間的各種通信。
在編寫代碼和仔細定義服務邊界之前,最好先考慮清楚系統的復雜性。
- 不同的職能團隊需要使用同一種語言,而專門的職能團隊只負責自己的組件和服務。建議組織通過應用程序接口設計使用同一種語言。
我們可以模擬請求和響應,以便在編寫代碼前驗證應用程序接口的設計。
- 提高軟件質量和開發人員的工作效率 由于我們在項目開始時就消除了大部分不確定因素,因此整個開發過程會更加順利,軟件質量也會大大提高。
開發人員對這一過程也很滿意,因為他們可以專注于功能開發,而不是商討突然的變化。
減少了項目生命周期末期出現意外的可能性。
因為我們先設計了應用程序接口,所以可以在開發代碼的同時設計測試。在某種程度上,使用 API 優先開發時,我們還可以進行 TDD(測試驅動設計)。
HTTP 狀態代碼
?

HTTP 的響應代碼分為五類:
信息 (100-199) 成功 (200-299) 重定向 (300-399) 客戶端錯誤 (400-499) 服務器錯誤 (500-599)
API 網關有什么作用?
下圖顯示了詳細情況。
?

第 1 步 - 客戶端向 API 網關發送 HTTP 請求。
第 2 步 - API 網關解析并驗證 HTTP 請求中的屬性。
第 3 步 - API 網關執行允許列表/拒絕列表檢查。
第 4 步 - API 網關與身份提供商對話,進行身份驗證和授權。
步驟 5 - 對請求應用速率限制規則。如果超過限制,請求將被拒絕。
第 6 步和第 7 步 - 既然請求已通過基本檢查,API 網關就會通過路徑匹配找到要路由的相關服務。
第 8 步 - API 網關將請求轉換為適當的協議,并將其發送到后端微服務。
步驟 9-12:API 網關可以正確處理錯誤,并在錯誤需要較長時間恢復(斷路)時處理故障。它還可以利用 ELK(Elastic-Logstash-Kibana)棧進行日志記錄和監控。我們有時會在 API 網關中緩存數據。
如何設計有效、安全的應用程序接口?
下圖以購物車為例展示了典型的應用程序接口設計。
?
請注意,應用程序接口設計不僅僅是 URL 路徑設計。大多數時候,我們需要選擇合適的資源名稱、標識符和路徑模式。設計適當的 HTTP 頭域或在 API 網關中設計有效的速率限制規則也同樣重要。
TCP/IP 封裝
數據如何通過網絡發送?為什么 OSI 模型需要這么多層?
?
下圖顯示了數據在網絡上傳輸時的封裝和解封過程。
步驟 1:當設備 A 通過 HTTP 協議在網絡上向設備 B 發送數據時,首先會在應用層添加一個 HTTP 標頭。
步驟 2:然后在數據中添加 TCP 或 UDP 報頭。數據在傳輸層被封裝成 TCP 段。報頭包含源端口、目的端口和序列號。
步驟 3:然后在網絡層用 IP 標頭對網段進行封裝。IP 標頭包含源/目的 IP 地址。
步驟 4:在數據鏈路層為 IP 數據報添加 MAC 標頭,其中包含源/目的 MAC 地址。
步驟 5:封裝后的幀被發送到物理層,并以二進制位的形式通過網絡發送。
步驟 6-10:設備 B 從網絡接收到比特后,會執行去封裝過程,這是對封裝過程的逆向處理。數據頭被逐層刪除,最終,設備 B 可以讀取數據。
在網絡模型中,我們需要分層,因為每一層都專注于自己的職責。每一層都可以依靠標頭來處理指令,而不需要知道上一層數據的含義。
為什么 Nginx 被稱為 “反向 “代理?
下圖顯示了 𝐟𝐨𝐫𝐰𝐚𝐫𝐝 𝐩𝐫𝐨𝐱𝐲 和 𝐫𝐞𝐯𝐞𝐫𝐬𝐞 𝐩𝐫𝐨𝐱𝐲 之間的區別。
?
前向代理是位于用戶設備和互聯網之間的服務器。
前向代理通常用于
- 保護客戶
- 規避瀏覽限制
- 阻止訪問某些內容
反向代理是一種服務器,它接受客戶端的請求,將請求轉發給網絡服務器,然后將結果返回給客戶端,就好像代理服務器處理了請求一樣。
反向代理可用于:
- 保護服務器
- 負載平衡
- 緩存靜態內容
- 加密和解密 SSL 通信
常見的負載平衡算法有哪些?
下圖顯示了 6 種常見算法。
?
- 靜態算法
- 循環賽
客戶請求會按順序發送到不同的服務實例。服務通常要求無狀態。
- 粘性循環賽
這是對輪循算法的改進。如果 Alice 的第一個請求轉到服務 A,那么接下來的請求也會轉到服務 A。
- 加權循環
管理員可以為每項服務指定權重。權重越高的服務處理的請求就越多。
- 散列
該算法對輸入請求的 IP 或 URL 應用哈希函數。根據哈希函數的結果,將請求路由到相關實例。
- 動態算法
- 連接最少
新請求會發送到并發連接最少的服務實例。
- 響應時間最短
新請求會發送到響應時間最快的服務實例。
URL、URI、URN - 您知道它們的區別嗎?
下圖顯示了 URL、URI 和 URN 的比較。
?
- 通用資源識別號
URI 是 Uniform Resource Identifier(統一資源標識符)的縮寫。它標識網絡上的邏輯或物理資源。URL 和 URN 是 URI 的子類型。URL 用于定位資源,而 URN 用于命名資源。
URI 由以下部分組成:scheme:[//authority]path[?query][#fragment][?
- 網址
URL 代表統一資源定位器,是 HTTP 的關鍵概念。它是網絡上唯一資源的地址。它可與 FTP 和 JDBC 等其他協議一起使用。
- 通用名
URN 代表統一資源名稱。它使用 urn 方案。URN 不能用于定位資源。圖中給出的一個簡單示例由命名空間和命名空間特定字符串組成。
如果您想了解這方面的更多詳情,我建議您閱讀 W3C 的說明。
CI/CD
簡單解釋 CI/CD 管道
?
第 1 節 - 采用 CI/CD 的 SDLC
軟件開發生命周期(SDLC)包括幾個關鍵階段:開發、測試、部署和維護。CI/CD 對這些階段進行自動化和集成,以實現更快、更可靠的發布。
當代碼推送到 git 倉庫時,會觸發自動構建和測試流程。端到端(e2e)測試用例將被運行以驗證代碼。如果測試通過,代碼就能自動部署到暫存/生產階段。如果發現問題,代碼將被送回開發部門進行錯誤修復。這種自動化可為開發人員提供快速反饋,并降低生產中出現錯誤的風險。
第 2 部分 - 傳播和信息與會議(CI)與會議文件(CD)的區別
持續集成(CI)實現了構建、測試和合并流程的自動化。每當提交代碼時,它都會運行測試,以便及早發現集成問題。這鼓勵了代碼的頻繁提交和快速反饋。
持續交付(CD)實現了基礎架構變更和部署等發布流程的自動化。它通過自動化工作流程確保軟件可以隨時可靠地發布。CD 還可以自動執行生產部署前所需的手動測試和審批步驟。
第 3 節 - CI/CD 管道
一個典型的 CI/CD 管道有幾個相連的階段:
- 開發人員將代碼更改提交到源代碼控制
- CI 服務器檢測更改并觸發構建
- 編譯代碼并進行測試(單元測試和集成測試)
- 向開發人員報告測試結果
- 成功后,工件將部署到暫存環境中
- 在發布之前,可在暫存階段進行進一步測試
- CD 系統將批準的變更部署到生產中
Netflix 技術棧(CI/CD 管道)
?
規劃:Netflix 工程部使用 JIRA 進行規劃,使用 Confluence 編寫文檔。
編碼:Java 是后臺服務的主要編程語言,其他語言用于不同的使用情況。
構建Gradle 主要用于構建,而 Gradle 插件則用于支持各種使用情況。
打包:將軟件包和依賴項打包到亞馬遜機器映像(AMI)中,以便發布。
測試:測試:測試強調生產文化對構建混亂工具的關注。
部署:Netflix 使用自建的 Spinnaker 來部署金絲雀。
監測:監控指標集中在 Atlas 系統中,Kayenta 系統用于檢測異常情況。
事件報告:根據優先級派遣事件,并使用 PagerDuty 進行事件處理。
架構模式
MVC、MVP、MVVM、MVVM-C 和 VIPER
無論是 iOS 還是 Android 平臺,這些架構模式都是應用程序開發中最常用的模式之一。開發人員引入這些模式是為了克服早期模式的局限性。那么,它們有什么不同呢?
?

- MVC 是最古老的模式,可追溯到近 50 年前
- 每個模式都有一個 “視圖”(V),負責顯示內容和接收用戶輸入
- 大多數模式都包含一個 “模型”(M),用于管理業務數據
- “控制器”、“演示器 “和 “視圖-模型 “是視圖和模型(VIPER 模式中的 “實體”)之間的翻譯器。
每個開發人員都應了解的 18 種關鍵設計模式
模式是針對常見設計問題的可重復使用的解決方案,可使開發過程更順暢、更高效。它們是構建更好的軟件結構的藍圖。以下是一些最流行的模式:
?

- 抽象工廠:家族創建器 - 創建相關項目組。
- 建造者樂高大師 - 逐步構建物體,將創建和外觀分開。
- 原型:克隆制作器 - 制作完全準備好的示例的副本。
- 單例:獨一無二:只有一個實例的特殊類。
- 適配器:通用插頭 - 可連接不同接口的設備。
- 橋梁:功能連接器 - 將對象的工作方式與功能聯系起來。
- 合成:樹形生成器 - 由簡單和復雜部件組成樹形結構。
- 裝飾器:自定義器 - 在不改變對象核心的情況下為其添加功能。
- 門面:一站式服務–以簡化的單一界面代表整個系統。
- Flyweight:節省空間–有效分享可重復使用的小物品。
- 代理:代理:替身–代表另一個對象,控制訪問或操作。
- 責任鏈:請求中繼 - 通過對象鏈傳遞請求,直至處理完畢。
- 命令:任務包裝器 - 將請求轉化為對象,隨時可執行操作。
- 迭代器集合瀏覽器 - 逐個訪問集合中的元素。
- 調解器:通信樞紐 - 簡化不同類之間的交互。
- 記憶:時間膠囊 - 捕捉并恢復對象的狀態。
- 觀察者新聞播報員 - 通知類其他對象的變化。
- 游客技藝高超的訪客 - 在不改變類別的情況下為類別添加新的操作。
數據庫
云服務中不同數據庫的小抄
?
為項目選擇合適的數據庫是一項復雜的任務。數據庫選項眾多,每種都適合不同的使用情況,很快就會導致決策疲勞。
我們希望這份小抄能提供高層次的指導,幫助您找到符合項目需求的正確服務,并避免潛在的陷阱。
注:谷歌數據庫用例文檔有限。盡管我們盡最大努力查看了現有資料,并得出了最佳方案,但某些條目可能需要更加準確。
為數據庫提供動力的 8 種數據結構
答案因使用情況而異。數據可以在內存或磁盤中建立索引。同樣,數據格式也各不相同,如數字、字符串、地理坐標等。系統可能重寫,也可能重讀。所有這些因素都會影響數據庫索引格式的選擇。
?
以下是一些最常用的索引數據結構:
- Skiplist:一種常見的內存索引類型。在 Redis 中使用
- 哈希索引:“地圖 “數據結構(或 “集合”)的一種非常常見的實現方式
- SSTable:磁盤上不可變的 “地圖 “實現
- LSM 樹Skiplist + SSTable。高寫入吞吐量
- B 樹:基于磁盤的解決方案。一致的讀寫性能
- 反轉索引:用于文檔索引。在 Lucene 中使用
- 后綴樹:用于字符串模式搜索
- R 樹:多維搜索,如尋找最近的鄰居
如何在數據庫中執行 SQL 語句?
下圖顯示了這一過程。請注意,不同數據庫的架構各不相同,下圖展示了一些常見的設計。
?
步驟 1 - 通過傳輸層協議(如 TCP)向數據庫發送 SQL 語句。
第 2 步 - SQL 語句被發送到命令解析器,在那里進行語法和語義分析,然后生成查詢樹。
第 3 步 - 將查詢樹發送給優化器。優化器會創建一個執行計劃。
步驟 4 - 將執行計劃發送給執行器。執行器從執行計劃中獲取數據。
步驟 5 - 訪問方法提供執行所需的數據獲取邏輯,從存儲引擎獲取數據。
步驟 6 - 訪問方法決定 SQL 語句是否只讀。如果查詢是只讀的(SELECT 語句),則將其傳遞給緩沖區管理器進行進一步處理。緩沖區管理器會在緩存或數據文件中查找數據。
第 7 步 - 如果語句是 UPDATE 或 INSERT,則將其傳遞給事務管理器作進一步處理。
步驟 8 - 在事務處理期間,數據處于鎖定模式。這是由鎖管理器保證的。這也確保了事務的 ACID 屬性。
CAP 定理
CAP 定理是計算機科學中最著名的術語之一,但我敢打賭,不同的開發人員對它有不同的理解。讓我們來看看它到底是什么,以及為什么會讓人感到困惑。
?

CAP 定理指出,分布式系統無法同時提供這三種保證中的兩種以上。
一致性:一致性意味著所有客戶端無論連接到哪個節點,都能在同一時間看到相同的數據。
可用性:可用性意味著,即使部分節點宕機,任何請求數據的客戶端都能得到響應。
分區容忍度:分區表示兩個節點之間的通信中斷。分區容錯是指盡管出現網絡分區,系統仍能繼續運行。
2 of 3 “的提法可能有用,但這種簡化可能會產生誤導。
- 選擇數據庫并非易事。僅僅根據 CAP 定理來證明我們的選擇是不夠的。例如,公司不會僅僅因為 Cassandra 是 AP 系統就為聊天應用選擇它。Cassandra 有一系列優良特性,是存儲聊天信息的理想選擇。我們需要深入挖掘。
- “CAP 只禁止了設計空間的一小部分:在存在分區的情況下具有完美的可用性和一致性,而這種情況很少見”。引自論文:十二年后的 CAP:規則 “是如何改變的。
- 該定理涉及 100% 的可用性和一致性。更現實的討論是在沒有網絡分區的情況下,如何權衡延遲和一致性。詳見 PACELC 定理。
CAP 定理真的有用嗎?
我認為它仍然有用,因為它為我們提供了一系列權衡討論的思路,但它只是故事的一部分。在選擇合適的數據庫時,我們需要深入挖掘。
內存和存儲器類型
?
可視化 SQL 查詢
數據庫系統執行 SQL 語句有幾個步驟,包括
- 解析 SQL 語句并檢查其有效性
- 將 SQL 轉換為內部表示法,如關系代數
- 優化內部表示法,創建可利用索引信息的執行計劃
- 執行計劃并返回結果
SQL 的執行非常復雜,需要考慮很多因素,例如
- 索引和緩存的使用
- 表格連接的順序
- 并發控制
- 事務管理
SQL 語言
1986 年,SQL(結構化查詢語言)成為一種標準。在接下來的 40 年里,它成為關系數據庫管理系統的主流語言。閱讀最新標準(ANSI SQL 2016)可能很費時間。如何學習?
?

SQL 語言有 5 個組成部分:
- DDL:數據定義語言,如 CREATE、ALTER、DROP
- DQL:數據查詢語言,如 SELECT
- DML:數據操作語言,如 INSERT、UPDATE、DELETE
- DCL:數據控制語言,如 GRANT、REVOKE
- TCL:事務控制語言,如 COMMIT、ROLLBACK
對于后端工程師來說,您可能需要了解其中的大部分內容。作為數據分析師,您可能需要充分了解 DQL。選擇與您最相關的主題。
緩存
數據緩存無處不在
該圖說明了我們在典型架構中緩存數據的位置。
?

水流有多個層次。
- 客戶端應用程序:瀏覽器可以緩存 HTTP 響應。我們第一次通過 HTTP 請求數據時,HTTP 頭會返回一個過期策略;我們再次請求數據時,客戶端應用程序會嘗試先從瀏覽器緩存中檢索數據。
- CDN:CDN 緩存靜態網絡資源。客戶端可以從附近的 CDN 節點檢索數據。
- 負載平衡器:負載平衡器還可以緩存資源。
- 信息傳遞基礎設施:消息代理首先將消息存儲在磁盤上,然后消費者按自己的節奏檢索消息。根據保留策略,數據會在 Kafka 集群中緩存一段時間。
- 服務:服務中有多層緩存。如果 CPU 緩存中沒有緩存數據,服務就會嘗試從內存中檢索數據。有時,服務會有一個二級緩存,將數據存儲在磁盤上。
- 分布式緩存:分布式緩存(如 Redis)可在內存中保存多個服務的鍵值對。它的讀/寫性能比數據庫好得多。
- 全文搜索:我們有時需要使用全文搜索(如用于文檔搜索或日志搜索的 Elastic Search)。數據副本也會被索引到搜索引擎中。
- 數據庫:即使在數據庫中,我們也有不同級別的緩存:
- WAL(先寫日志):數據先寫入 WAL,然后再建立 B 樹索引
- 緩沖池分配用于緩存查詢結果的內存區域
- 物化視圖:預先計算查詢結果并將其存儲在數據庫表中,以提高查詢性能
- 事務日志:記錄所有事務和數據庫更新
- 復制日志:用于記錄數據庫群集中的復制狀態
Redis 為什么這么快?
如下圖所示,主要有 3 個原因。
?
- Redis 是一種基于 RAM 的數據存儲。RAM 訪問速度至少是隨機磁盤訪問速度的 1000 倍。
- Redis 利用 IO 多路復用和單線程執行循環提高執行效率。
- Redis 利用了幾種高效的底層數據結構。
問題另一種流行的內存存儲是 Memcached。你知道 Redis 和 Memcached 的區別嗎?
您可能已經注意到,這張圖的風格與我以前的文章不同。請告訴我您更喜歡哪一種。
如何使用 Redis?
?
Redis 不僅僅是緩存。
如圖所示,Redis 可用于多種場景。
- 會議
我們可以使用 Redis 在不同服務之間共享用戶會話數據。
- 緩存
我們可以使用 Redis 來緩存對象或頁面,尤其是熱點數據。
- 分布式鎖
我們可以使用 Redis 字符串在分布式服務之間獲取鎖。
- 計數器
我們可以計算文章的點贊數或閱讀數。
- 速率限制器
我們可以為某些用戶 IP 設置速率限制器。
- 全球 ID 生成器
我們可以使用 Redis Int 作為全局 ID。
- 購物車
我們可以使用 Redis Hash 來表示購物車中的鍵值對。
-
計算用戶留存率
我們可以使用位圖來表示用戶每天的登錄情況,并計算用戶留存率。
-
信息隊列
我們可以使用 List 作為消息隊列。
- 排名
我們可以使用 ZSet 對文章進行排序。
頂級緩存策略
設計大型系統通常需要仔細考慮緩存問題。以下是經常使用的五種緩存策略。
?

微服務架構
典型的微服務架構是什么樣的?
?
下圖顯示了典型的微服務架構。
- 負載平衡器:它將傳入流量分配給多個后端服務。
- CDN(內容分發網絡):CDN 是一組分布在不同地理位置的服務器,用于保存靜態內容以加快傳輸速度。客戶首先在 CDN 中查找內容,然后再轉到后端服務。
- API 網關:它負責處理傳入的請求,并將其路由到相關服務。它與身份提供商和服務發現者進行對話。
- 身份供應商:它負責用戶的身份驗證和授權。
- 服務注冊和發現:微服務注冊和發現在此組件中進行,API 網關在此組件中尋找相關服務進行對話。
- 管理:該部分負責監控服務。
- 微服務:微服務在不同的域中設計和部署。每個域都有自己的數據庫。API 網關通過 REST API 或其他協議與微服務對話,同一域內的微服務通過 RPC(遠程過程調用)相互對話。
微服務的優勢
- 它們可以快速設計、部署和橫向擴展。
- 每個域都可由一個專門團隊獨立維護。
- 因此,每個領域的業務需求都可以定制,并得到更好的支持。
微服務最佳實踐
一圖勝千言:開發微服務的 9 項最佳實踐。
?
在開發微服務時,我們需要遵循以下最佳實踐:
- 為每個微服務使用單獨的數據存儲
- 使代碼保持類似的成熟度
- 為每個微服務單獨構建
- 為每個微服務分配單一職責
- 部署到容器中
- 設計無狀態服務
- 采用領域驅動設計
- 設計微型前端
- 協調微服務
微服務通常使用什么技術棧?
下圖展示了開發階段和生產階段的微服務技術棧。
?
?? 𝐏𝐫𝐞-𝐏𝐫𝐨𝐝𝐮𝐜𝐭𝐢𝐨𝐧
- 定義應用程序接口(API)–這將在前臺和后臺之間建立合約。為此,我們可以使用 Postman 或 OpenAPI。
- 開發–Node.js 或 react 用于前端開發,java/python/go 用于后端開發。此外,我們還需要根據 API 定義更改 API 網關中的配置。
- 持續集成 - JUnit 和 Jenkins 用于自動測試。代碼打包成 Docker 鏡像,并作為微服務部署。
?? 𝐏𝐫𝐨𝐝𝐮𝐜𝐭𝐢𝐨𝐧
- NGinx 是負載平衡器的常見選擇。Cloudflare 提供 CDN(內容分發網絡)。
- API 網關 - 我們可以使用 Spring Boot 作為網關,并使用 Eureka/Zookeeper 進行服務發現。
- 微服務部署在云上。我們可以選擇 AWS、Microsoft Azure 或 Google GCP。緩存和全文搜索–Redis 是緩存鍵值對的常見選擇。Elasticsearch 用于全文搜索。
- 通信–為了讓服務之間相互通信,我們可以使用 Kafka 或 RPC 消息傳遞。
- 持久性 - 我們可以使用 MySQL 或 PostgreSQL 作為關系數據庫,使用 Amazon S3 作為對象存儲。如有必要,我們還可以使用 Cassandra 進行寬列存儲。
- 管理與監控 - 為了管理如此多的微服務,常用的運維工具包括 Prometheus、Elastic Stack 和 Kubernetes。
Kafka 為何如此快速
Kafka 的性能得益于許多設計決策。在本篇文章中,我們將重點討論其中兩項。我們認為這兩項決定的分量最重。
?

- 首先是 Kafka 對順序 I/O 的依賴。
- 賦予 Kafka 性能優勢的第二個設計選擇是其對效率的關注:零拷貝原則。
該圖說明了數據如何在生產者和消費者之間傳輸,以及零拷貝的含義。
- 步驟 1.1 - 1.3:生產者向磁盤寫入數據
- 步驟 2:消費者讀取不帶零拷貝的數據
2.1 數據從磁盤載入操作系統緩存
2.2 數據從操作系統緩存復制到 Kafka 應用程序
2.3 Kafka 應用程序將數據復制到套接字緩沖區
2.4 數據從套接字緩沖區復制到網卡
2.5 網卡向用戶發送數據
- 步驟 3:消費者以零拷貝方式讀取數據
3.1:3.2 操作系統緩存通過 sendfile() 命令直接將數據復制到網卡 3.3 網卡向用戶發送數據
零拷貝是保存應用程序上下文和內核上下文之間多個數據副本的快捷方式。
支付系統
如何學習支付系統?
?
為什么信用卡被稱為 “銀行最賺錢的產品”?VISA/Mastercard 如何賺錢?
下圖顯示了信用卡支付流程的經濟學原理。
?

- 持卡人向商家支付 100 美元購買產品。
2.商戶因使用信用卡提高了銷售額而受益,并需要補償發卡行和卡網絡提供的支付服務。收單銀行向商戶收取一定費用,稱為 “商戶折扣費”。
收單銀行保留 0.25 美元作為收單加價,1.75 美元作為交換費支付給發卡銀行。商戶折扣費應包含交換費。
交換費由銀行卡網絡確定,因為每家發卡銀行與每個商家協商費用的效率較低。
- 銀行卡網絡與每家銀行確定網絡分攤額和費用,銀行每月向銀行卡網絡支付服務費。例如,VISA 對每次刷卡收取 0.11% 的分攤費,外加 0.0195 美元的使用費。
- 持卡人向發卡銀行支付服務費。
為什么要補償發行銀行?
- 即使持卡人未向發卡機構付款,發卡機構也會向商戶付款。
- 發卡機構在持卡人向發卡機構付款之前向商戶付款。
- 發行機構還有其他運營成本,包括管理客戶賬戶、提供報表、欺詐檢測、風險管理、清算和結算等。
當我們在商鋪刷卡時,VISA 是如何運作的?
?
VISA 卡、萬事達卡和美國運通卡是清算和結算資金的銀行卡網絡。收卡銀行和發卡銀行可以是不同的,而且往往是不同的。如果銀行在沒有中間人的情況下逐一結算交易,那么每家銀行都必須與所有其他銀行結算交易。這樣做效率很低。
下圖顯示了 VISA 在信用卡支付流程中的作用。其中涉及兩個流程。客戶刷卡時發生授權流。捕獲和結算流程發生在商家希望在一天結束時拿到錢的時候。
- 授權流程
步驟 0:發卡銀行向客戶發行信用卡。
步驟 1:持卡人想購買一件商品,在商家店鋪的銷售點(POS)終端刷卡。
步驟 2:POS 終端將交易發送給提供 POS 終端的收單銀行。
步驟 3 和 4:收單銀行將交易發送到銀行卡網絡,也稱為銀行卡計劃。銀行卡網絡將交易發送給發卡銀行審批。
步驟 4.1、4.2 和 4.3:如果交易被批準,發卡銀行將凍結資金。批準或拒絕的信息將發回收單銀行和 POS 終端。
- 捕獲和結算流程
步驟 1 和 2:商戶希望在一天結束時收款,因此在 POS 終端上點擊 “抓取”。交易被批量發送到收單機構。收單機構將包含交易的批處理文件發送給銀行卡網絡。
步驟 3:銀行卡網絡對從不同收單機構收集的交易進行清算,并將清算文件發送給不同的發卡銀行。
步驟 4:發卡銀行確認清算文件的正確性,并向相關收單銀行轉賬。
步驟 5:收單銀行將錢轉給商戶的銀行。
步驟 4:銀行卡網絡對來自不同收單銀行的交易進行清算。清算是對相互抵消的交易進行凈額結算,從而減少交易總數的過程。
在此過程中,銀行卡網絡承擔了與每家銀行對話的負擔,并收取服務費作為回報。
世界各地的支付系統系列(第 1 部分):印度的統一支付接口(UPI)
什么是 UPI?UPI 是印度國家支付公司開發的即時實時支付系統。
目前,它占印度數字零售交易的 60%。
UPI = 支付標記語言 + 互操作支付標準
?
DevOps
DevOps vs. SRE vs. 平臺工程。有什么區別?
DevOps、SRE 和平臺工程的概念出現于不同時期,由不同的個人和組織發展而來。
?
DevOps 這一概念是 Patrick Debois 和 Andrew Shafer 于 2009 年在敏捷大會上提出的。他們試圖通過推廣協作文化和分擔整個軟件開發生命周期的責任,來彌合軟件開發和運營之間的差距。
SRE,即網站可靠性工程,由谷歌于 2000 年代初首創,旨在解決管理大型復雜系統時遇到的運營挑戰。谷歌開發了 SRE 實踐和工具,如 Borg 集群管理系統和 Monarch 監控系統,以提高其服務的可靠性和效率。
平臺工程是一個較新的概念,建立在 SRE 工程的基礎之上。平臺工程的確切起源不太清楚,但一般認為它是 DevOps 和 SRE 實踐的延伸,重點是為產品開發提供一個支持整個業務視角的綜合平臺。
值得注意的是,雖然這些概念出現的時間不同。它們都與改善軟件開發和運營中的協作、自動化和效率這一更廣泛的趨勢有關。
什么是 k8s(Kubernetes)?
K8s 是一個容器協調系統。它用于容器部署和管理。它的設計深受谷歌內部系統 Borg 的影響。
?
k8s 集群由一組運行容器化應用程序的工作機器(稱為節點)組成。每個集群至少有一個工作節點。
工作節點托管作為應用程序工作負載組件的 Pod。控制平面管理集群中的工作節點和 Pod。在生產環境中,控制平面通常在多臺計算機上運行,集群通常運行多個節點,以提供容錯和高可用性。
- 控制平面組件
- 應用程序接口服務器
API 服務器與 k8s 集群中的所有組件對話。Pod 上的所有操作都是通過與 API 服務器對話來執行的。
- 調度員
調度程序會監控 pod 的工作負載,并為新創建的 pod 分配負載。
- 控制經理
控制器管理器運行控制器,包括節點控制器、作業控制器、EndpointSlice 控制器和服務帳戶控制器。
- 其他
etcd 是一個鍵值存儲,用作 Kubernetes 所有集群數據的后備存儲。
- 節點
- 豆莢
pod 是一組容器,是 k8s 管理的最小單位。pod 中的每個容器都有一個 IP 地址。
-
Kubelet
在集群中每個節點上運行的代理。它能確保容器在 Pod 中運行。
-
Kube 代理
Kube-proxy 是一種網絡代理,可在集群中的每個節點上運行。它會路由從服務進入節點的流量。它將工作請求轉發給正確的容器。
Docker 與 Kubernetes。我們應該使用哪一個?
?

什么是 Docker?
Docker 是一個開源平臺,可讓你在隔離的容器中打包、分發和運行應用程序。它專注于容器化,提供封裝應用程序及其依賴關系的輕量級環境。
什么是 Kubernetes?
Kubernetes 通常被稱為 K8s,是一個開源容器編排平臺。它為跨節點集群的容器化應用程序的自動化部署、擴展和管理提供了一個框架。
兩者有何不同?
DockerDocker 在單個操作系統主機上的單個容器級別運行。
您必須手動管理每臺主機,而且為多個相關容器設置網絡、安全策略和存儲可能非常復雜。
KubernetesKubernetes 在集群級別運行。它管理多個主機上的多個容器化應用程序,為負載平衡、擴展和確保應用程序的理想狀態等任務提供自動化。
簡而言之,Docker 專注于容器化和在單個主機上運行容器,而 Kubernetes 則擅長在主機集群中大規模管理和協調容器。
Docker 如何運行?
下圖顯示了 Docker 的架構,以及當我們運行 “docker build”、“docker pull “和 “docker run “時它是如何工作的。
?
Docker 架構有 3 個組成部分:
- Docker 客戶端
docker 客戶端與 Docker 守護進程對話。
- Docker 主機
Docker 守護進程會偵聽 Docker API 請求,并管理映像、容器、網絡和卷等 Docker 對象。
- Docker 注冊表
Docker 注冊表存儲 Docker 映像。Docker Hub 是一個公共注冊表,任何人都可以使用。
讓我們以 “docker run “命令為例。
- Docker 從注冊表中提取映像。
- Docker 會創建一個新容器。
- Docker 會為容器分配一個讀寫文件系統。
- Docker 會創建一個網絡接口,將容器連接到默認網絡。
- Docker 啟動容器
GIT
Git 命令的工作原理
首先,必須確定代碼的存儲位置。通常的假設是只有兩個位置,一個在 Github 等遠程服務器上,另一個在我們的本地機器上。然而,這并不完全準確。Git 在我們的機器上有三個本地存儲空間,這意味著我們的代碼可以在四個地方找到:
?
- 工作目錄:我們編輯文件的地方
- 暫存區:為下一次提交保存文件的臨時位置
- 本地版本庫:包含已提交的代碼
- 遠程存儲庫:存儲代碼的遠程服務器
大多數 Git 命令主要是在這四個位置之間移動文件。
Git 如何工作?
下圖顯示了 Git 的工作流程。
?
Git 是一種分布式版本控制系統。
每個開發人員都維護一個主版本庫的本地副本,并對本地副本進行編輯和提交。
提交速度非常快,因為該操作不與遠程版本庫交互。
如果遠程存儲庫崩潰,可以從本地存儲庫恢復文件。
Git merge 與 Git rebase
有哪些區別?
?
當我們從一個 Git 分支合并改動到另一個分支時,可以使用 “git merge “或 “git rebase”。下圖顯示了這兩個命令的工作原理。
Git 合并
這樣就在主分支中創建了一個新的提交 G’。G’ 綁定了主分支和特性分支的歷史。
Git 合并是非破壞性的。主分支和特性分支都不會改變。
Git 重定向
Git rebase 會將特性分支的歷史移到主分支的頭部。它會為特性分支中的每個提交創建新的提交 E’、F’和 G’。
rebase 的好處是它有一個線性的提交歷史。
如果不遵守 “git rebase 黃金法則”,重定向可能會很危險。
Git 重置的黃金法則
切勿在公共分支機構使用!
云服務
不同云服務的小抄(2023 年版)
?
什么是云原生?
下圖顯示了自 20 世紀 80 年代以來架構和流程的演變。
?

企業可以使用云原生技術在公共云、私有云和混合云上構建和運行可擴展的應用程序。
這意味著應用程序在設計上充分利用了云功能,因此它們能夠承受負載并易于擴展。
云原生包括 4 個方面:
- 發展進程
從瀑布式到敏捷式,再到 DevOps。
-
應用架構
架構已從單體變為微服務。每個服務都設計得很小,以適應云容器中有限的資源。
-
部署和包裝
以前,應用程序都部署在物理服務器上。2000 年左右,對延遲不敏感的應用程序通常部署在虛擬服務器上。而云原生應用程序則被打包成 docker 鏡像,部署在容器中。
-
應用基礎設施
應用程序被大規模部署在云基礎設施上,而不是自托管服務器上。
開發人員生產力工具
可視化 JSON 文件
嵌套的 JSON 文件很難讀取。
JsonCrack 可從 JSON 文件生成圖表,并使其易于閱讀。
此外,生成的圖表還可以下載為圖片。
?
自動將代碼轉化為架構圖
?
它有什么作用?
- 用 Python 代碼繪制云系統架構圖。
- 圖表也可以直接在 Jupyter 筆記本中呈現。
- 無需設計工具。
- 支持以下提供商:AWS、Azure、GCP、Kubernetes、阿里云、甲骨文云等。
Github repo
Linux]
Linux 文件系統說明
?
過去,Linux 文件系統就像一個無序的小鎮,人們隨心所欲地建造自己的房屋。然而,1994 年,文件系統層次標準(FHS)的引入為 Linux 文件系統帶來了秩序。
通過實施像 FHS 這樣的標準,軟件可以確保在不同的 Linux 發行版中使用一致的布局。不過,并非所有 Linux 發行版都嚴格遵守這一標準。它們通常會融入自己獨特的元素或迎合特定的要求。要熟練掌握這一標準,可以從探索開始。使用 “cd “等命令進行導航,使用 “ls “命令列出目錄內容。將文件系統想象成一棵樹,從根 (/) 開始。隨著時間的推移,這將成為你的第二天性,使你成為一名熟練的 Linux 管理員。
你應該知道的 18 種最常用 Linux 命令
Linux 命令是與操作系統交互的指令。它們有助于管理文件、目錄、系統進程和系統的許多其他方面。你需要熟悉這些命令,才能高效地瀏覽和維護基于 Linux 的系統。
下圖顯示了常用的 Linux 命令:
?
- ls - 列出文件和目錄
- cd - 更改當前目錄
- mkdir - 創建新目錄
- rm - 刪除文件或目錄
- cp - 復制文件或目錄
- mv - 移動或重命名文件或目錄
- chmod - 更改文件或目錄權限
- grep - 在文件中搜索模式
- 查找 - 搜索文件和目錄
- tar - 處理 tar 包檔案文件
- vi - 使用文本編輯器編輯文件
- cat - 顯示文件內容
- top - 顯示進程和資源使用情況
- ps - 顯示進程信息
- kill - 通過發送信號終止進程
- du - 估算文件空間使用情況
- ifconfig - 配置網絡接口
- ping - 測試主機之間的網絡連通性
安全
HTTPS 如何工作?
超文本傳輸協議安全(HTTPS)是超文本傳輸協議(HTTP)的擴展。HTTPS 使用傳輸層安全(TLS)傳輸加密數據。
?
如何加密和解密數據?
步驟 1 - 客戶端(瀏覽器)和服務器建立 TCP 連接。
第 2 步 - 客戶端向服務器發送 “客戶端你好 “信息。該信息包含一組必要的加密算法(密碼套件)和可支持的最新 TLS 版本。服務器響應 “服務器你好”,以便瀏覽器知道自己是否支持這些算法和 TLS 版本。
然后,服務器將 SSL 證書發送給客戶端。證書包含公鑰、主機名、有效期等信息。客戶端驗證證書。
第 3 步 - 驗證 SSL 證書后,客戶端生成會話密鑰,并使用公鑰對其進行加密。服務器接收加密的會話密鑰,并用私鑰解密。
第 4 步 - 既然客戶端和服務器都持有相同的會話密鑰(對稱加密),加密數據就會在安全的雙向信道中傳輸。
為什么 HTTPS 會在數據傳輸過程中切換到對稱加密?主要有兩個原因:
- 安全性:非對稱加密只能單向進行。這意味著,如果服務器嘗試將加密數據發送回客戶端,任何人都可以使用公開密鑰解密數據。
- 服務器資源:非對稱加密增加了大量數學開銷。它不適合長時間的數據傳輸。
Oauth 2.0 簡明解釋
OAuth 2.0 是一個強大而安全的框架,它允許不同的應用程序代表用戶進行安全交互,而無需共享敏感憑據。
參與 OAuth 的實體包括用戶、服務器和身份提供者(IDP)。
OAuth 令牌能做什么?
使用 OAuth 時,您會得到一個代表您的身份和權限的 OAuth 令牌。這個令牌可以做幾件重要的事情:
單點登錄(SSO):有了 OAuth 令牌,只需登錄一次,就能登錄多個服務或應用程序,讓生活更輕松、更安全。
跨系統授權:OAuth 令牌可讓您在不同系統間共享授權或訪問權限,這樣您就不必到處單獨登錄。
訪問用戶配置文件:擁有 OAuth 令牌的應用程序可以訪問您允許訪問的用戶配置文件的某些部分,但不會看到所有內容。
請記住,OAuth 2.0 的目的是保證您和您的數據安全,同時讓您的在線體驗在不同的應用程序和服務之間無縫銜接、輕松自如。
四大認證機制形式
?
- SSH 密鑰:
加密密鑰用于安全訪問遠程系統和服務器
- OAuth 標記:
可在第三方應用程序上有限訪問用戶數據的令牌
- SSL 證書:
數字證書確保服務器和客戶端之間的通信安全和加密
- 證書
用戶身份驗證信息用于驗證和授予對各種系統和服務的訪問權限
會話、Cookie、JWT、令牌、SSO 和 OAuth 2.0 - 它們是什么?
這些術語都與用戶身份管理有關。當你登錄一個網站時,你要聲明你是誰(身份識別)。你的身份會得到驗證(認證),并被授予必要的權限(授權)。過去已經提出了許多解決方案,而且這個清單還在不斷擴大。
?
從簡單到復雜,這就是我對用戶身份管理的理解:
- WWW 身份驗證是最基本的方法。瀏覽器會要求你輸入用戶名和密碼。由于無法控制登錄生命周期,這種方法如今已很少使用。
- 會話 Cookie 是對登錄生命周期更精細的控制。服務器保存會話存儲,瀏覽器保存會話 ID。cookie 通常只適用于瀏覽器,對移動應用程序不友好。
- 為了解決兼容性問題,可以使用令牌。客戶端向服務器發送令牌,服務器驗證令牌。缺點是需要對令牌進行加密和解密,這可能會比較耗時。
- JWT 是表示令牌的標準方式。由于該信息經過數字簽名,因此可以驗證和信任。由于 JWT 包含簽名,因此無需在服務器端保存會話信息。
- 通過使用 SSO(單點登錄),您只需登錄一次,即可登錄多個網站。它使用 CAS(中央驗證服務)來維護跨網站信息。
- 通過使用 OAuth 2.0,您可以授權一個網站訪問您在另一個網站上的信息。
如何在數據庫中安全存儲密碼以及如何驗證密碼?
?
不該做的事
- 用純文本存儲密碼不是一個好主意,因為任何有內部訪問權限的人都可以看到它們。
- 直接存儲密碼哈希值是不夠的,因為它會受到預計算攻擊,如彩虹表。
- 為了減少預計算攻擊,我們對密碼進行了加鹽處理。
鹽是什么?
根據 OWASP 指南,“鹽是一個隨機生成的唯一字符串,作為散列過程的一部分添加到每個密碼中”。
如何存儲密碼和鹽值?
- 每個密碼的哈希結果都是唯一的。
- 密碼可以使用以下格式存儲在數據庫中:hash(password + salt)。
如何驗證密碼?
要驗證密碼,可以通過以下過程:
- 客戶輸入密碼。
- 系統會從數據庫中獲取相應的鹽。
- 系統會將鹽添加到密碼中并進行散列。我們將散列值稱為 H1。
- 系統會比較 H1 和 H2,其中 H2 是存儲在數據庫中的哈希值。如果兩者相同,則密碼有效。
向 10 歲的孩子解釋 JSON 網絡令牌 (JWT)
?
想象一下,你有一個叫做 JWT 的特殊盒子。在這個盒子里,有三個部分:頭、有效載荷和簽名。
頁眉就像盒子外面的標簽。它告訴我們這是什么類型的盒子,以及它是如何固定的。它通常以一種名為 JSON 的格式編寫,這是一種使用大括號 { } 和冒號 : 來組織信息的方式。
有效載荷就像您要發送的實際信息或資訊。它可以是你的姓名、年齡或任何其他你想分享的數據。它也是用 JSON 格式編寫的,因此很容易理解和使用。現在,簽名是保證 JWT 安全的關鍵。它就像一個特殊的印章,只有發送方才知道如何創建。簽名是用密碼創建的,有點像口令。這個簽名可以確保沒有人可以在發送方不知情的情況下篡改 JWT 的內容。
當您要將 JWT 發送到服務器時,您需要將標頭、有效載荷和簽名放在盒子里。然后發送給服務器。服務器可以很容易地讀取標頭和有效載荷,以了解您是誰以及您想做什么。
Google Authenticator(或其他類型的雙因素身份驗證器)如何工作?
當啟用雙因素身份驗證時,Google Authenticator 通常用于登錄我們的賬戶。它如何保證安全?
Google Authenticator 是一款基于軟件的驗證器,可實現兩步驗證服務。下圖提供了詳細信息。
?
這涉及兩個階段:
- 階段 1 - 用戶啟用 Google 兩步驗證。
- 第 2 階段 - 用戶使用驗證器登錄等。
讓我們來看看這些階段。
第 1 階段
步驟 1 和 2:Bob 打開網頁,啟用兩步驗證。前端請求輸入秘鑰。驗證服務會為鮑勃生成秘鑰,并將其存儲在數據庫中。
步驟 3:驗證服務向前端返回一個 URI。URI 由密鑰發放者、用戶名和密鑰組成。URI 以 QR 碼的形式顯示在網頁上。
步驟 4:然后,鮑勃使用 Google Authenticator 掃描生成的 QR 碼。秘鑰存儲在驗證器中。
第 2 階段 第 1 步和第 2 步:Bob 想通過 Google 兩步驗證登錄一個網站。為此,他需要密碼。每隔 30 秒,Google Authenticator 會使用 TOTP(基于時間的一次性密碼)算法生成一個 6 位數的密碼。鮑勃使用密碼進入網站。
步驟 3 和 4:前臺將鮑勃輸入的密碼發送到后臺進行驗證。身份驗證服務從數據庫中讀取秘鑰,并使用與客戶端相同的 TOTP 算法生成一個 6 位數密碼。
步驟 5:身份驗證服務比較客戶端和服務器生成的兩個密碼,并將比較結果返回前端。只有當兩個密碼匹配時,鮑勃才能繼續登錄。
這種驗證機制安全嗎?
-
他人能否獲取秘鑰?
我們需要確保使用 HTTPS 傳輸秘鑰。驗證器客戶端和數據庫都會存儲秘鑰,我們需要確保秘鑰經過加密。
-
6 位數密碼會被黑客猜到嗎?
密碼有 6 位數字,因此生成的密碼有 100 萬種可能的組合。另外,密碼每 30 秒就會更改一次。如果黑客想在 30 秒內猜出密碼,他們每秒需要輸入 3 萬個密碼組合。
真實世界案例研究
Netflix 的技術棧
本文章基于對許多 Netflix 工程博客和開源項目的研究。如果您發現任何不準確之處,請隨時告知我們。
?
移動和網絡:Netflix 采用 Swift 和 Kotlin 構建本地移動應用程序。在網絡應用方面,它使用 React。
前端/服務器通信:Netflix 使用 GraphQL。
后臺服務:Netflix 依靠 ZUUL、Eureka、Spring Boot 框架和其他技術。
數據庫:Netflix 使用 EV 緩存、Cassandra、CockroachDB 和其他數據庫。
消息傳遞/流媒體:Netflix 采用 Apache Kafka 和 Fink 進行消息傳遞和流媒體處理。
視頻存儲:Netflix 使用 S3 和 Open Connect 進行視頻存儲。
數據處理:Netflix 利用 Flink 和 Spark 進行數據處理,然后使用 Tableau 將數據可視化。Redshift 用于處理結構化數據倉庫信息。
CI/CD:Netflix 在 CI/CD 流程中使用了 JIRA、Confluence、PagerDuty、Jenkins、Gradle、Chaos Monkey、Spinnaker、Atlas 等多種工具。
推特架構 2022
沒錯,這就是真正的 Twitter 架構。它是由埃隆-馬斯克發布的,我們重新繪制了它,以提高可讀性。
?
Airbnb 微服務架構在過去 15 年中的演變
Airbnb 的微服務架構主要經歷了三個階段。
?
巨石(2008 - 2017)
Airbnb 最初只是一個簡單的房東和客人市場。它是由 Ruby on Rails 應用程序構建而成的,即單體。
挑戰是什么?
- 混淆團隊所有權和非所有權代碼
- 部署緩慢
微服務(2017 - 2020 年)
微服務旨在解決這些挑戰。在微服務架構中,關鍵服務包括
- 數據獲取服務
- 業務邏輯數據服務
- 編寫工作流程服務
- 用戶界面聚合服務
- 每項服務都有一個擁有團隊
挑戰是什么?
數以百計的服務和依賴關系是人類難以管理的。
微服務 + 宏服務(2020 年至今)
這就是 Airbnb 目前正在努力的方向。微服務和宏服務混合模式的重點是統一應用程序接口。
Monorepo 與 Microrepo。
哪種方案最好?為什么不同的公司選擇不同的方案?
?
Monorepo 并不新鮮;Linux 和 Windows 都是使用 Monorepo 創建的。為了提高可擴展性和構建速度,谷歌開發了內部專用工具鏈以加快擴展速度,并制定了嚴格的編碼質量標準以保持一致性。
亞馬遜和 Netflix 是微服務理念的主要倡導者。這種方法自然而然地將服務代碼分離到不同的資源庫中。它的擴展速度更快,但可能會導致日后的治理痛點。
在 Monorepo 中,每個服務都是一個文件夾,每個文件夾都有 BUILD 配置和 OWNERS 權限控制。每個服務成員負責自己的文件夾。
另一方面,在 Microrepo 中,每個服務負責自己的版本庫,通常為整個版本庫設置構建配置和權限。
在 Monorepo 中,依賴關系在整個代碼庫中共享,與業務無關,因此當版本升級時,每個代碼庫都會升級自己的版本。
在 Microrepo 中,依賴關系受控于每個版本庫。企業可根據自己的時間表選擇何時升級版本。
Monorepo 有一個簽到標準。谷歌的代碼審查流程以設置高標準而聞名,確保 Monorepo 的質量標準一致,無論業務如何。
Microrepo 既可以制定自己的標準,也可以通過采納最佳實踐來采用共享標準。它可以更快地擴展業務,但代碼質量可能會有些不同。谷歌工程師開發了 Bazel,Meta 開發了 Buck。還有其他開源工具,包括 Nix、Lerna 等。
多年來,Microrepo 支持的工具越來越多,包括 Java 的 Maven 和 Gradle、NodeJS 的 NPM 和 C/C++ 的 CMake 等等。
您將如何設計 Stack Overflow 網站?
如果你的答案是內部部署服務器和單片機(如下圖底部),你很可能無法通過面試,但這就是現實中的構建方式!
?
人們認為它應該是什么樣子
面試官可能希望看到類似圖片上半部分的內容。
- 微服務用于將系統分解成小的組件。
- 每個服務都有自己的數據庫。大量使用緩存。
- 服務是分片的。
- 服務之間通過消息隊列進行異步對話。
- 該服務是利用 CQRS 的事件源功能實現的。
- 展示分布式系統知識,如最終一致性、CAP 定理等。
它究竟是什么
Stack Overflow 僅使用 9 臺內部網絡服務器為所有流量提供服務,而且是單體服務器!它有自己的服務器,不在云上運行。
這與我們如今的流行觀念背道而馳。
亞馬遜 Prime Video 監控為何從無服務器轉向單體?如何節省 90% 的成本?
下圖顯示了遷移前后的架構對比。
?

什么是亞馬遜 Prime 視頻監控服務?
Prime Video 服務需要監控數千個直播流的質量。監控工具會自動對流媒體進行實時分析,并識別塊損壞、視頻凍結和同步問題等質量問題。這是提高客戶滿意度的重要流程。
共有 3 個步驟:媒體轉換器、缺陷檢測器和實時通知。
-
舊架構有什么問題?
舊架構基于亞馬遜 Lambda,適合快速構建服務。但是,在大規模運行該架構時,其成本效益并不高。最昂貴的兩個操作是
- 協調工作流–AWS 步進功能通過狀態轉換向用戶收費,協調每秒執行多個狀態轉換。
- 分布式組件之間的數據傳遞–中間數據存儲在亞馬遜 S3 中,以便下一階段下載。當數據量較大時,下載的成本可能會很高。
-
單片架構可節省 90% 的成本
設計單片架構是為了解決成本問題。雖然仍有 3 個組件,但媒體轉換器和缺陷檢測器部署在同一流程中,從而節省了通過網絡傳輸數據的成本。令人驚訝的是,這種部署架構變革方法節省了 90% 的成本!
這是一個有趣而獨特的案例研究,因為微服務已成為科技行業的首選和時尚。令人欣慰的是,我們正在就架構的發展進行更多的討論,并對其利弊進行更坦誠的討論。將組件分解成分布式微服務是有代價的。
-
亞馬遜領導對此有何評論?
亞馬遜首席技術官 Werner Vogels:“構建可進化的軟件系統是一種戰略,而不是一種信仰。以開放的心態重新審視你的架構是必須的”。
前亞馬遜可持續發展副總裁 Adrian Cockcroft:“Prime Video 團隊走的是一條我稱之為無服務器優先(Serverless First)的道路……我并不主張只使用無服務器”。
迪斯尼 Hotstar 如何在一場比賽中捕獲 50 億個表情符號?
?

- 客戶端通過標準 HTTP 請求發送表情符號。您可以將 Golang 服務視為典型的 Web 服務器。之所以選擇 Golang,是因為它能很好地支持并發性。Golang 中的線程是輕量級的。
- 由于寫入量非常大,Kafka(消息隊列)被用作緩沖區。
- Emoji 數據由名為 Spark 的流式處理服務聚合。它每 2 秒鐘聚合一次數據,這個時間間隔是可以配置的。需要根據時間間隔進行權衡。更短的時間間隔意味著表情符號能更快地傳送到其他客戶端,但也意味著需要更多的計算資源。
- 匯總后的數據將寫入另一個 Kafka。
- PubSub 消費者從 Kafka 提取表情符號聚合數據。
- 表情符號通過 PubSub 基礎設施實時傳送到其他客戶端。PubSub 基礎設施非常有趣。Hotstar 考慮了以下協議:Socketio、NATS、MQTT 和 gRPC,最終選擇了 MQTT。
LinkedIn 也采用了類似的設計,它能以每秒一百萬個贊的速度傳播信息。
Discord 如何存儲數以萬億計的信息
下圖顯示了 Discord 消息存儲的演變過程:
?
MongoDB ?? Cassandra ?? ScyllaDB
2015 年,Discord 的第一個版本建立在單個 MongoDB 復制之上。2015 年 11 月左右,MongoDB 存儲了 1 億條消息,RAM 無法再容納數據和索引。延遲變得不可預測。消息存儲需要轉移到另一個數據庫。最終選擇了 Cassandra。
2017 年,Discord 擁有 12 個 Cassandra 節點,存儲了數十億條信息。
2022 年初,它擁有 177 個節點,信息量達數萬億條。此時,延遲不可預測,維護操作成本過高。
造成這一問題的原因有幾個:
- Cassandra 使用 LSM 樹作為內部數據結構。讀取比寫入更昂貴。在一臺擁有數百名用戶的服務器上,可能會有很多并發讀取,從而產生熱點。
- 維護群集(如壓縮 SST 表)會影響性能。
- 垃圾收集暫停會導致明顯的延遲峰值
ScyllaDB 是用 C++ 編寫的 Cassandra 兼容數據庫。Discord 重新設計了自己的架構,使其具有單片式 API、用 Rust 編寫的數據服務和基于 ScyllaDB 的存儲。
ScyllaDB 的 p99 讀取延遲為 15 毫秒,而 Cassandra 為 40-125 毫秒。p99 的寫延遲為 5 毫秒,而 Cassandra 為 5-70 毫秒。
YouTube、TikTok Live 或 Twitch 上的視頻直播是如何進行的?
實時流媒體不同于普通流媒體,因為視頻內容是通過互聯網實時發送的,延遲時間通常只有幾秒鐘。
下圖解釋了實現這一點的幕后原因。
?
步驟 1:原始視頻數據由麥克風和攝像頭采集。數據被發送到服務器端。
步驟 2:對視頻數據進行壓縮和編碼。例如,壓縮算法會分離背景和其他視頻元素。壓縮后,按照 H.264 等標準對視頻進行編碼。經過這一步驟后,視頻數據的大小會小得多。
步驟 3:編碼后的數據被分成較小的片段,長度通常為幾秒鐘,因此下載或流式傳輸所需的時間更短。
步驟 4:將分段數據發送到流媒體服務器。流媒體服務器需要支持不同的設備和網絡條件。這就是所謂的 “自適應比特率流”。這意味著我們需要在步驟 2 和 3 中以不同的比特率生成多個文件。
步驟 5:將實時流媒體數據推送到 CDN(內容分發網絡)支持的邊緣服務器。CDN 大大降低了數據傳輸延遲。
步驟 6:觀眾的設備對視頻數據進行解碼和解壓,并在視頻播放器中播放視頻。
第 7 步和第 8 步:如果視頻需要存儲以便重放,則將編碼數據發送到存儲服務器,觀眾可在稍后要求重放。
實時流媒體的標準協議包括
- RTMP(實時信息傳輸協議):最初由 Macromedia 開發,用于在 Flash 播放器和服務器之間傳輸數據。現在,它用于在互聯網上傳輸視頻數據流。請注意,Skype 等視頻會議應用程序使用 RTC(實時通信)協議,以降低延遲。
- HLS(HTTP 實時流):它需要 H.264 或 H.265 編碼。蘋果設備只接受 HLS 格式。
- DASH(HTTP 動態自適應流):DASH 不支持蘋果設備。
- HLS 和 DASH 都支持自適應比特率流媒體。
?