支撐 “千萬設備日活” 的創米數聯 7 年微服務架構演進之路

作者:金兆旭 上海創米數聯智能科技發展股份有限公司雲服務開發及 SRE 工程師 負責公司雲端基礎設施構建及消息網關等研發工作;十眠

創米數聯是小米生態鏈首批億元俱樂部成員,主營業務爲智能家居產品的研發、設計、生產和銷售,致力於成爲以居家安全爲核心的產品和服務提供商,提供多品類的全屋智能家居產品及服務。公司以居家安全爲核心,洞察用戶在居住環境下的智能化需求,建立物理安全、環境安全、系統安全三類場景及服務體系,主要產品包括智能攝像機、智慧門、智能貓眼、智能門鈴、智能插座等。公司旨在實現“看得見的全屋智能”,以智能家庭安全爲切入點,提供多品類覆蓋的智能家居解決方案。截至 2021 年 12 月 31 日,創米數聯已經在全世界 150 多個國家,銷售了超過 5500 萬臺設備,擁有了 1600 萬設備和 500 萬設備用戶日活。

作爲小米生態鏈的一員,創米採用微服務架構支撐其千萬日活的 IOT 設備。隨着智能家居市場的快速迭代,創米麪臨着發佈和迭代的穩定性挑戰,同時需要解決多方 IOT 接入面臨的性能和安全挑戰。本文將爲您一一道來創米是如何應對這些挑戰的。

雲計算時代的蹣跚學步

創米雲服務從 2016 年創始之初就選擇了雲計算+微服務的技術路線,以應對面臨的大量線上用戶和設備帶來的流量挑戰。構建微服務之初,市面上可選用的解決方案並不多,我們自主實現了一些微服務組件,如 frontend 業務網關和配置中心,並在小米生態雲上部署容器服務來處理設備消息、設備插件 API 和微信公衆號等相關業務,並利用 HPA 及 CronHPA 等容器彈性伸縮策略來應對動態的海量線上流量。

image.png

自此創米數聯在雲計算時代踏上了探索服務容器化的第一步。

新業務及新挑戰

從 2019 年伊始,創米數聯提出了研發自有 APP 和適配自有 APP 的智能家居設備的發展戰略。雲服務部將研發重心轉向自有 APP 雲端業務,並逐步接入自有品牌設備。爲了實現全球業務,創米雲服務部將相關服務部署在阿里雲的 4 個 Region 的 ACK Pro 專有版 Kubernetes 集羣上。阿里雲 ACK 爲創米雲提供了可靠穩定的基礎設施,向下封裝好的數十款雲產品,降低了雲端運維人員的運維壓力,快速對接其他雲產品的能力也對開發人員十分友好,能夠讓創米雲服務在極短的時間內搭建一套線上可用的環境。

在自有業務研發開始階段,我們選擇了 Spring Cloud、Eureka 和 Apollo 等技術棧來搭建我們的微服務基礎架構。然而,經過一年半的摸索,我們發現當前的混合架構存在着不穩定、上線部署風險大以及高人力維護成本等問題。

因此,從 2021 年開始,創米雲服務決定改變現有的微服務架構,逐步擁抱雲原生。我們的目標是在滿足穩定性和低維護成本等需求的基礎上,實現所有組件的可觀測性、全鏈路的流量治理以及更加便捷高效的 DevOps 流程。

雲原生體系探索

首先我們將當前的 Spring Cloud 體系全面轉向 Spring Cloud Alibaba,使用 Nacos 替換 Eureka,以解決 Eureka 服務端壓力過大的問題,並滿足單註冊中心多環境分組的需求。由於 Apollo 在某些情況下存在容器磁盤壓力大的問題,我們逐步將配置中心從 Apollo 替換爲 Nacos。針對之前定製化的 Apollo 配置同步和本地特殊配置緩存,同樣我們也對 Nacos 客戶端進行了部分定製化改造。

image.png

初版上線時,考慮到註冊中心和配置中心的高可用性、熱升級、成本、可觀測配套等因素,我們沒有選擇自建有狀態的開源 Nacos 服務,而是直接使用了阿里雲 MSE Nacos 專業版服務。至今,該服務一直穩定運行,沒有出現可用性問題。

全鏈路流量治理

針對全鏈路的流量治理,由於創米雲服務所處的 AIoT 行業不同於傳統互聯網行業,我們在南北向流量時不僅需要治理下游用戶手機端 APP 及 Web 端的 HTTP 請求,還需要處理來自設備端的 MQTT、第三方 AMQP 和 HTTP 2 長連接 Push 消息的流量治理。這些消息通常經由統一的上游消息網關(消息總線)監聽,經過多級過濾器,如消息來源、消息限流和產品或特定設備級別的白名單等,對消息進行分類和打標籤,然後對消息 Topic 正則路由並進行 HTTP 異步或 rpc 請求。只有經過這些請求後,我們才能對其進行流量治理。

image

因此,創米雲服務的流量治理整體較爲複雜。我們曾考慮過採用侵入式代碼和自定義負載均衡器,並開發控制檯來實現高度自定義的流量方案。我們還考慮過使用 Istio Service Mesh 的方案治理流量。然而,前者在當前百萬級別設備消息的情況下性能嚴重受限,後者由於設備消息鏈路較長、打標較多,導致實現全鏈路灰度時配置文件實現較爲複雜,而且 Envoy 代理無法完整攔截消息總線請求等問題,因此我們否定了這兩種方案。之後在選型過程中,我們採用了 MSE 微服務治理。

我們傳統的 API 業務流量治理選用了多域名、多租戶環境、節點隔離加多業務網關的方案配合 MSE 微服務治理來實現多個環境服務的測試開發及線上灰度部署。我們使用多域名加 DNS 流量劃分的方式對服務重構後的業務網關新路由進行測試,保證服務重構後的安全上線。我們利用多個 K8s 集羣、K8s namespace 以及多個 namespace 的註冊配置中心的隔離構建了不同的線上環境,分別用來線上開發、線上測試、灰度以及基線環境部署。對於同一集羣不同 namespace 的應用 pod 使用多集羣隔離、應用節點親和性、反親和性以及節點污點等集羣調度手段保證環境的安全性,避免不同環境間出現的資源異常導致基線環境不可用的情況。基線環境和灰度環境同屬不同命名空間的相同節點池內,測試和開發環境應用 pod 部署在不同的 K8s 集羣或節點池中。我們的整體流程通常是在 feature 及 bug 修復後涉及的服務在開發環境聯調完畢,在每次測試流程前將 feature 服務部署至測試環境,通過藍綠測試將測試人員的流量導向測試環境,在多輪的覆蓋及迴歸測試完成後,將服務部署至灰度環境,再將測試人員及 Beta 測試用戶的流量導向灰度環境,經過一定時間的檢驗後,逐步將線上基線流量導向灰度環境,灰度環境流量完成 100% 灰度後,替換基線環境鏡像,最後逐步將灰度流量倒流至基線環境。

image

在覈心業務接入 MSE 微服務治理之後,創米雲服務對部分多雲部署及老項目通過 DNS 流量切分+全鏈路灰度的方式進行灰度,逐漸將自有 APP 及自有設備的所有業務重構遷移至新項目中並全部接入 MSE 微服務,實現了雲上 API 業務的 100% 安全發佈。

在設備消息業務的流量治理的推進過程中,爲了解決無法攔截消息請求的問題,我們首先將消息總線拆分爲控制器和路由器兩部分。控制器監聽各個通道的消息後僅對消息進行打標籤和分類,然後通過異步 HTTP 請求經由統一的路由器轉發到各個服務中。我們將路由器服務定義爲流量治理的入口,從而解決了消息無法治理的問題。然後,我們使用統一的全鏈路灰度對打標籤後的 HTTP 請求進行藍綠和灰度的流量治理,並將其分發到指定的命名空間的指定服務中進行消息處理。

MSE 微服務治理接入非常簡單,只需要在 Helm 或組件中心安裝 ack-onepilot 組件,重啓服務便可自動注入服務,除此之外 MSE 提供了較爲友好的全鏈路灰度配置界面,較 Istio 方案更加易於配置和上手。通過這樣的流程,創米雲服務成功實現了設備服務的更新、云云設備的對接以及固件 OTA 版本的迭代過程中的安全發佈。

無損上下線解決發佈擴縮容流量損失問題

image

無損下線邏輯圖

在之前的服務發版部署或 pod 彈性伸縮過程中經常會有部分請求出現超時或不可用的情況,由於創米雲服務承載了大量的用戶設備請求,這些流量損失輕則導致設備消息重試,嚴重時會影響部分用戶設備的可用性,後續我們瞭解了 MSE 微服務治理提供了無損上下線及服務預熱功能,決定將相關服務全部接入了 MSE 微服務治理的無損上下線,並調整對應服務的就緒檢查,在後續的服務上下線過程中經觀察再未出現因爲流量損失導致的請求不可用的情況,一定程度上避免了由部署發佈和服務縮容引起的線上流量損失問題。

image.png

新啓動 Pod 的預熱流量分佈

可觀測體系

爲了實現可觀測性,我們早期就將阿里雲 SLS 日誌服務集成到自有業務框架中。然而,我們遇到了業務索引不規範、唯一 RequestId 索引異步丟失以及 Spring Cloud Gateway 等 Reactive 框架應用日誌異步寫入 Location 導致 CPU 佔用過高等問題。因此,我們對當前的日誌規範進行了改進,並在多個鏈路追蹤方案中選擇了 Skywalking。我們將 Skywalking 的 TraceId 寫入 SLS 日誌索引中,並通過對 ThreadLocal 的改造實現了異步線程的日誌索引信息傳遞。我們的服務掛載了 Skywalking Agent,並自定義了可選插件,然後接入了阿里雲鏈路追蹤服務。相比自建 ElasticSearch 集羣,阿里雲鏈路追蹤服務更經濟實惠且免維護,鏈路追蹤服務可以直接將項目關聯到指定的 SLS logstore 中,更方便進行鏈路問題排查。在上線的第一個月裏,鏈路追蹤服務幫助我們解決了多個項目中的接口性能問題。

創米雲服務的指標信息的觀測主要依賴於 ARMS ACK、ARMS ACK Pro、ARMS 雲服務等多個開箱可用的 Grafana Dashboard,它們提供了相當完善的集羣、Node、Pod 等多個維度的指標信息,除此之外我們依然會使用阿里云云監控或自定義一些 Grafana Dashboard 用來關注其他部分指標。創米雲服務爲了快速預警,設置了雲產品、SLS 日誌、K8s 事件等多個維度的告警配置,對報警進行降噪調優,根據告警等級設置了電話、短信、郵件和飛書羣多個通道的報警通知,建立了相當全面的服務告警體系,以便相關人員及時發現問題,避免線上損失。

CI/CD 提效

早些時候由於多雲部署的問題,我們並沒有統一的全自動 CI/CD 解決方案,爲了解決雲端 DevOps 構建部署和上線安全性等問題,我們將所有的 Devops 流程開始全面轉向阿里云云效。首先,我們將雲服務代碼從自建的 Gitlab 完全同步到阿里雲 CodeUp 代碼庫中,並將之前的 Gitlab CI/CD 和 Jenkins 的 CI/CD 方案全部遷移到阿里云云效流水線。我們建立了單 Region、多 Region、多雲項目的多條流水線,實現了從代碼提交、手動或自動觸發構建,到自動部署到指定的 K8s 集羣和命名空間的全流程。每次構建和部署完成後,我們會發送飛書通知並調用 Newman 自動化測試腳本的 WebHook,根據自動化測試結果報告,評估每次服務版本發佈是否滿足安全規範。

穩定性評估與演練

對於線上環境穩定性評估,創米雲服務選用了混沌工程的方式來檢驗服務的可用性,創米雲服務根據自身業務對 Java 應用 OOM、緩存擊穿、網絡延遲、K8s Pod 資源、K8s 系統組件、關鍵雲服務等多個維度對自身環境的服務進行全方位的演練排查,並檢驗可觀測性中告警配置的靈敏度。我們在沒有造成線上損失的情況下發現並修復了部分漏洞、完善了多 AZ 的雲服務資源的建設、調整了未觸發告警的配置,使自身架構更加健壯。在一定程度上幫助創米雲服務在及時彌補了在 HA 方面不足,並在後續的架構設計中提出了高可用優先的原則。

未來展望

未來創米雲服務將業務網關逐漸轉型爲雲原生網關+WASM 插件方案,代替繁重的 Spring Cloud Gateway 業務網關,進一步提升網關性能、靈活性和可擴展性,並接入現有可觀測體系。我們將繼續致力於創新和技術升級,爲用戶提供更優質的產品體驗。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章