Sentry 是什麼?這是一個用於錯誤上報的服務中心,使用近乎一致的 API 設計,統一了不同語言生產環境代碼異常上報的難題。
2020 年二月份,領導讓我負責在公司內部測試和使用 Sentry,彼時 Sentry 的文檔還不是很完善,我也只是初步接觸基礎服務的搭建,Sentry 於我而言就是一個黑盒子。
2016 年,Sentry 的開發者答覆說目前沒有任何關於 Sentry 架構的公開資料,最佳的途徑就是閱讀源碼:)這個工程量確實比較大,我個人在使用 Docker-compose 搭建 Sentry 時,借用一連串的日誌輸出來觀察整個數據流,根據服務間的依賴也只能猜測大致的架構。
2020 年下半年,Sentry 開始陸續將文檔補全,這個項目的架構圖終被公開,結合其他文檔,Sentry 的數據流浮出水面。
架構概述
下方這個圖是根據 Sentry 官方文檔重繪的,我把所有存儲相關的組件用紫色的圖形做了區分,其他 Sentry 服務組件用藍色表示(除了頂部的應用)。
這樣畫下來之後,服務基本就分層完畢:
- Loadbalancer(負載均衡器)負責路由轉發(這一服務由用戶搭建),錯誤上報轉發到
/api/\d+/store
,其他項目、成員、錯誤管理功能由 Sentry Web 負責。這一層的承擔數據入口、展示的作用 - Relay 負責消息中繼轉發,並把數據先彙集到 Kafka;Snuba 負責接收 SentryWeb 的請求,進行數據的聚合、搜索;Sentry Worker 則是一個隊列服務,主要負責數據的存儲。
- Kafka 作爲消息隊列,ClickHouse 負責接近實時的數據分析,Redis(主要) 和 Memcached 負責項目配置、錯誤基礎信息的存儲和統計。Postgres 承擔基礎數據持久化(主要是項目、用戶權限管理等)Symbolicator 主要用於錯誤信息格式化。
- 最底下的 Zookeeper 是 Kafka 用於節點信息同步的,如果我們設置了多個 ClickHouse 節點,也可以用它來保存主從同步信息或者做分佈式表。
Relay —— 錯誤信息處理的中轉站
Relay 收到原始數據後,主要做這幾件事。
- 對其格式進行有效性校驗
- 查詢內存或者從 Redis 拉取緩存得到項目配置信息,校驗請求是否合法(項目是否存在或者有沒有觸發限流,沒觸發限流則會對 API 額度進行累計,寫入 Redis)
- 發起一個異步請求給定時任務(SentryWorker,postprocess-event)做下一步處理
Kafka 和 Celery —— 應用解耦和異步保存數據
Relay 數據轉發到 Kafka 的 ingest-events Topic(Ingest 即攝取),消費者消費後把消息放入 postprocess-event 這個 Celery 定時任務服務排隊處理。隊列做的事情如下
- Symbolicate-event,在 iOS 上有個叫 symbolicate-crash 的工具,是將機器的崩潰日誌轉化爲可讀的崩潰代碼定位日誌,這裏的 Symbolicator 同樣承擔類似的職能,由它經手的消息,我們就可以在頁面上看到代碼在哪裏出錯了。
- process-event,字面含義就是處理消息,在 Sentry 上啓用的插件(Plugins or Integration)會在這個步驟中應用到消息體上,例如,整合了一個 Slack bot(機器人),就會在這個步驟發送告警。
- save-event,消息經過簡化,保存到數據庫,同時再次發到 Kafka,但這次換到 event Topic,Snuba 這個搜索組件內部會有一個消費者,對這部分數據批量寫入到 ClickHouse。你可能好奇爲什麼不直接存進去算了還要搞多這一步,這是因爲 ClickHouse 雖然大數據量處理能力很強,但頻繁寫入能力是真的菜雞(假設做了主從,那就更災難了,把從庫和 Zookeeper 都一起拉下水),所以需要 Snuba 來限制寫入頻率。
Sentry Web
Sentry Web 這邊主要跟配置等持久化數據打交道,創建項目、權限控制、限流分配等都是它負責。查詢搜索錯誤消息、Dashboard 聚合等功能則是 Snuba 承擔,由它來當翻譯官,把用戶查詢條件轉化爲 SQL 語句發給 ClickHouse。
題外話 —— 爲什麼 Sentry 適合商用
以往的開源項目大部分可以看成是單個組件,升級修復的工作量對一般的工程師而言還是可以接受的。但是 Sentry 這個錯誤上報服務背後卻是十幾二十個微服務組成的,一次服務升級可能涉及到很多個微服務、存儲服務,瞬間依賴爆炸,測試無從下手。
對於小公司而言,如果不使用 Docker,搭建一個 Sentry 服務,就需要很多臺服務器,如果要做主從、集羣還需要再乘以 N,如果要做 TLS,又得花大筆錢去購置證書。本來是想節省代碼查錯的時間成本,可能最後卻多花了錢在部署和運維上。
單租戶隔離(Single Tenant Isolation)、持續集成測試、TLS 加密、容災都交給了 Sentry 來做,給它打錢自然而然地成了最划算的方案,不得不說,真羨慕這種站着賺錢的項目:)。