每月處理15億次登入,Auth0高可用架構實踐
【51CTO.com原創稿件】如今,身份驗證對絕大多數應用程式而言至關重要。Auth0 可以為任何堆疊上的各類(移動、Web 和原生)應用程式提供身份驗證、授權和單點登入服務。
我們設計的 Auth0 一開始就可以在任何地方執行:我們的雲、你的雲,甚至在你自己的私有基礎設施上。
在本文中我們將詳細探討我們的公共 SaaS 部署,並簡要介紹 auth0.com 背後的基礎設施,以及用來確保它順暢執行的高可用性策略。
我們曾在 2014 年撰文介紹了 Auth0 的架構,自那以來 Auth0 已發生了很大的變化,下面是幾大要點:
- 我們從每月處理數百萬次登入升級至每月處理逾 15 億次登入,為成千上萬的客戶提供服務,包括 FuboTV、Mozilla 和 JetPrivilege 等。
- 我們實施了新功能,比如自定義域、擴充套件的 bcrypt 操作以及大大改進的使用者搜尋等。
- 為了擴充套件我們組織的規模並處理流量的增加,我們產品的服務數量從不到 10 個增加到了 30 多個。
- 雲資源的數量也大幅增長,我們過去在一個環境(美國)中有幾十個節點,現在我們在四個環境(美國、美國-2、歐盟和澳大利亞)有 1000 多個節點。
- 我們決定為自己的每個環境使用單一雲提供商,並將所有公共雲基礎設施遷移到了 AWS。
核心服務架構
圖 1:Auth0.com 的核心服務架構
我們的核心服務包括如下不同的層:
- 核心應用程式:可自動擴充套件的伺服器組,這些伺服器執行我們堆疊的不同服務(身份驗證、管理 API 和多因子身份驗證 API 等)。
- 資料儲存:MongoDB、Elasticsearch、Redis 和 PostgreSQL 叢集,為不同的應用程式和功能特性儲存眾多資料集。
- 傳輸/佇列:Kinesis 資料流以及 RabbitMQ、SNS 和 SQS 佇列。
- 基礎服務:針對速率限制、bcrypt 叢集和功能標誌等其他的服務。
- 路由:AWS 負載均衡系統(來自 AWS 的 ALB、NLB 和 ELB)以及一些執行 Nginx 充當代理的節點。
高可用性
2014 年,我們使用了多雲架構(使用 Azure 和 AWS,還有谷歌雲上的一些額外資源),多年來該架構為我們提供了良好的服務。隨著使用量(和負載)迅速增加,我們發現自己越來越依賴 AWS 資源。
最初,我們將環境中的主區域切換到 AWS,Azure 留作故障切換區域。我們開始使用更多的 AWS 資源(比如 Kinesis 和 SQS)時,將同樣的功能特性放在這兩家提供商處開始遇到了麻煩。
隨著移動(和擴充套件)的速度越來越快,我們選擇繼續支援 Azure,但功能同等性(feature parity)有限。
如果 AWS 上的一切出現故障,我們仍可以使用 Azure 叢集來支援身份驗證等核心功能,但是不支援我們一直在開發的許多新功能。
2016 年出現幾次嚴重宕機後,我們決定最終集中到 AWS 上。我們停止了與確保服務和自動化平臺無關的全部工作,而是專注於:
- 在 AWS 內部提供更好的故障切換機制,使用多個區域,每個區域至少 3 個可用區。
- 增加使用 AWS 特有的資源,比如自動擴充套件組(而不是使用固定的節點叢集)和應用程式負載均衡系統(ALB)等。
- 編寫更好的自動化:我們改進了自動化,完全採用基礎設施即程式碼,使用 TerraForm 和 SaltStack 來配置新的 Auth0 環境(以及替換現有環境)。
這讓我們從每秒處理約 300 次登入的部分自動化環境升級到每秒處理逾 3400 次登入的全自動化環境;使用新工具更容易向上擴充套件(必要的話還可以向下擴充套件)。
我們實現的自動化水平並不完美,但讓我們極其方便地擴大到新的區域、建立新的環境。
- 編寫更好的劇本(playbook):隨著時間的推移,我們發現除了自動化外,還需要更好的劇本,以便了解、管理和響應與我們越來越龐大的服務網格相關的事件。
這極大地提高了可擴充套件性和可靠性,同時加快了新員工的入職。
比如說,不妨看看我們的美國環境架構。我們有這個總體結構,如下圖:
圖 2:Auth0 美國環境架構
下圖是單一可用區內部的結構:
圖 3:Auth0 單一可用區
在這種情況下,我們使用兩個 AWS 區域:
- us-west-2(我們的主區域)
- us-west-1(故障切換區域)
正常情況下,所有請求都流向 us-west-2,由三個獨立的可用區處理請求。
這就是我們實現高可用性的方式:所有服務(包括資料庫)在每個可用區(AZ)上都有執行中的例項。
如果一個可用區因資料中心故障而宕機,我們仍有兩個可用區來處理請求;如果整個區域宕機或出現錯誤,我們可以通知 Route53 故障切換到 us-west-1、恢復操作。
我們在服務故障切換方面有不同的成熟度級別:一些服務(比如在 Elasticsearch 上構建快取的使用者搜尋 v2)可正常執行,但資料稍顯陳舊,不過核心功能按預期執行。
在資料層中,我們使用:
- 面向 MongoDB 的跨區域叢集。
- 面向 PostgreSQL 的 RDS 複製。
- 面向 Elasticsearch 的每個區域的叢集,自動快照和恢復定期執行,以解決缺少跨區域叢集的問題。
我們每年至少進行一次故障切換演練,我們有劇本和自動化,幫助新的基礎設施工程師儘快瞭解如何演練以及由此帶來的影響。
我們的部署通常由 Jenkins 節點觸發;視服務而定,我們使用 Puppet、SaltStack 及/或 Ansible 來更新單個節點或一組節點,或者我們更新 AMI,為不可變的部署建立新的自動擴充套件組。
我們為新舊服務部署了不同型別的環境;由於我們需要為應該統一的系統維護自動化、文件和監控,結果證明這基本上很低效。
我們目前在為一些核心服務推出藍/綠部署(blue/green deployment),我們打算為每個核心的支援服務實施同樣的一套。
自動化測試
除了每個專案的單元測試覆蓋外,我們還有在每個環境中執行的多個功能測試套件。
我們在部署到生產環境之前先在試執行環境上執行,完成部署後再在生產環境中執行,以確保一切正常。
我們的自動化測試要點:
- 在不同的專案中有數千個單元測試。
- 使用每分鐘執行的 Pingdom 探針(probe)來檢查核心功能。
- 在每次部署前後結合使用基於 Selenium 的功能測試和基於 CodeceptJS 的功能測試。功能測試套件測試不同的 API 端點、身份驗證流程和身份提供者等。
CDN
2017 年之前我們執行自己專門定製的 CDN,在多個區域執行 Nginx、Varnish 和 EC2 節點。
2017 年以後,我們改用 CloudFront,它為我們帶來了幾個好處,包括:
- 更多的邊緣位置,這意味著為我們的客戶縮短了延遲。
- 降低維護成本。
- 配置起來更輕鬆。
但同時也有幾個缺點,比如我們需要執行 Lambdas 來執行一些配置(比如將自定義標頭新增到 PDF 檔案等等)。不過,好處絕對壓倒缺點。
Extend
我們提供的功能之一是能夠通過身份驗證規則或自定義資料庫連線,執行自定義程式碼,作為登入事務的一部分。
這些功能由 Extend(https://goextend.io/)提供支援,Extend 是一個可擴充套件性平臺,由 Auth0 發展而來,現在還被其他公司所使用。
有了 Extend,我們的客戶就可以用那些指令碼和規則編寫所需的任何服務,擴充套件配置檔案、規範屬性和傳送通知等。
我們有專門針對 Auth0 的 Extend 叢集,它們結合使用 EC2 自動擴充套件組、Docker 容器和自定義代理,以處理來自我們使用者的請求,每秒處理數千個請求,並快速響應負載變化。
想了解這如何構建和執行的更多資訊,請參閱這篇介紹如何構建自己的無伺服器平臺的文章(https://tomasz.janczuk.org/2018/03/how-to-build-your-own-serverless-platform.html)。
監控
我們結合使用不同的工具來監控和除錯問題:
- CloudWatch
- DataDog
- Pingdom
- SENTINL
我們的絕大多數警報來自 CloudWatch 和 DataDog。
我們往往通過 TerraForm 來配置 CloudWatch 警報,用 CloudWatch 來監控的主要問題有:
- 來自主負載均衡系統的 HTTP 錯誤。
- 目標組中不健康的例項。
- SQS 處理延遲。
CloudWatch 是基於 AWS 生成的指標(比如來自負載均衡系統或自動擴充套件組的指標)來監控警報的最佳工具。
CloudWatch 警報通常傳送給 PagerDuty,再從 PagerDuty 傳送給 Slack/手機。
DataDog 是我們用來儲存時間序列指標並採取相應操作的服務。我們傳送來自 Linux 系統、AWS 資源和現成服務(比如 Nginx 或 MongoDB)的指標,還發送來自我們構建的自定義服務(比如 Management API)的指標。
我們有許多 DataDog 監控指標,舉幾個例子:
- $environment 上的 $service 響應時間增加。
- $instance 中的 $volume($ ip_address)空間不足。
- $environment / $ host 上的 $process($ ip_address)出現問題。
- $environment 上的 $service 處理時間增加。
- $host($ip_address)上出現 NTP 漂移/時鐘問題。
- $environment 上的 MongoDB 副本集變更。
從上面例子中可以看出,我們監控低階指標(如磁碟空間)和高階指標(如 MongoDB 副本集變更,這提醒我們主節點定義是否發生了變化)。我們做了大量的工作,設計了一些相當複雜的指標來監控一些服務。
DataDog 警報的輸出非常靈活,我們通常將它們全部發送給 Slack,只把那些“引人注意”的警報傳送給 PagerDuty,比如錯誤高峰,或者我們確信對客戶產生影響的大多數事件。
至於日誌記錄方面,我們使用 SumoLogic 和 Kibana;我們使用 SumoLogic 來記錄審計跟蹤記錄和 AWS 生成的許多日誌,我們使用 Kibana 儲存來自我們自己的服務和其他“現成”服務(如 Nginx 和 MongoDB)的應用程式日誌。
未來設想
我們的平臺經歷了很大的變化,以處理額外負載和對客戶來說很重要的眾多使用場景,但我們仍有優化的空間。
不僅我們的平臺在擴大,我們的工程部門規模也在擴大:我們有許多新團隊構建自己的服務,而且需要自動化、工具和可擴充套件性方面的指導。
有鑑於此,我們落實了這些計劃,不僅擴充套件平臺,還夯實工程實踐:
- 構建類似 PaaS 的平臺:如前所述,今天我們有不同的自動化和部署流程,這導致了混亂,給工程師設定了門檻,因為很難在不接觸眾多程式碼庫的情況下進行試驗和擴充套件。
我們正在為目前在 ECS 上執行的平臺開發概念證明(PoC)程式碼,工程師們可以配置 YAML 檔案,只需部署它,即可獲取計算資源、監控、日誌記錄和備份等。
所有這一切都無需明確配置。這項工作還處於早期階段,可能會發生很大變化。然而,鑑於我們不斷擴大的規模和可擴充套件性方面的限制,我們認為我們的方向正確。
- 針對每個新的合併請求實施冒煙測試(smoke test):除了單元測試(已經在每個新的 PR 上執行)外,我們希望儘可能在短暫環境上進行整合測試。
- 將我們的日誌記錄解決方案集中到一家提供商。這可能意味著遠離 Kibana,只使用 SumoLogic,但我們仍需要評估功能集和資料量等。
- 自動衡量指標:現在我們的指標好多都是手動的――部署時新增與指標有關的程式碼呼叫,以及使用 DataDog 介面來構建儀表板和監控器。
如果我們使用標準格式和命名,可以實現一些任務,比如自動構建儀表板/監控器,從日誌提取指標而不是明確新增程式碼呼叫等。
- 確保我們針對每個核心服務都有自動擴充套件和藍/綠部署。這應該是我們新平臺的預設功能,但在構建和測試時,我們需要為這方面仍然不足的核心服務改進擴充套件/部署/回滾機制。
作者:Dirceu Tiegs(沈建苗編譯)
簡介:Auth0 是身份即服務(IDaaS)的全球領導者,為成千上萬的企業客戶提供用於其 Web、移動、物聯網和內部應用程式的通用身份平臺。其可擴充套件的平臺每月為逾 15 億次登入驗證身份和確保安全,因而備受開發人員的喜愛和全球企業的信賴。該公司的美國總部位於華盛頓州貝爾維尤,在布宜諾斯艾利斯、倫敦、東京和悉尼設有辦事處,為 70 多個國家的客戶提供支援。
【51CTO原創稿件,合作站點轉載請註明原文作者和出處為51CTO.com】