青團社:億級靈活用工平臺的雲原生架構實踐

發表於2024-03-01

作者:楊磊

青團社是國內領先的一站式靈活用工招聘服務企業,靈活用工行業的 Top1。青團社於 2013 年在杭州成立,業務已經覆蓋全國,在行業深耕 10 年。我的分享將分為以下三部分:

  • 青團社架構演進的歷程
  • 青團社如何實現雲原生
  • 總結與展望

雲原生架構的演進歷程

2020 年,我們的技術架構比較薄弱,存在較多問題。面對這些問題,團隊開始了架構演進,存在的問題主要是以下多個方面。

圖片

第一,運維能力和可觀測性比較差,因為公司大部分都是業務研發人員,專業的 DBA 和運維都沒有。

第二,在業務剛剛開始起步時,業務迭代速度非常快,每天都會有很頻繁的釋出,線上經常因為釋出導致一些穩定性的問題,作為平臺型公司連線 B 端和 C 端兩端,對線上可用性要求非常高,但早期的架構設計也不太合理,所以很多時候應用是無法支援高可用的。

第三,因為線上的資源部署不太合理,比較浪費資源,資源成本較高。

第四,部署模式比較粗放,日誌、告警都沒有,所以出了問題之後排查非常困難,研發人員通常需要很長時間才能把這些問題弄清楚,響應時間比較長,相信大部分初創型公司在業務早期發展的階段都存在這種問題。

那我們如何去應對這些挑戰呢?答案就是使用雲原生架構來重塑架構體系, 不斷地對架構進行演進,選擇合適的技術棧,配合使用雲的基礎設施,來構建業務平臺,讓系統達到好的水準。

從下圖中可以看到,青團社的業務架構演變遵循從單體架構到 SOA 架構再到微服務。基礎架構物理機是沒有的,團隊從 2014 年開始就直接使用阿里雲 ECS,在 2021 年開始容器化,最終到達期望的雲原生架構形態。

圖片

雲原生基金會官方對雲原生的定義是 5 部分,第一是容器化,第二是不可變基礎設施,第三個是宣告式 API,然後是服務網格和微服務,其中微服務作為承載業務應用的核心,圍繞這個,會有像排程編排、流量管理、可觀測、DevOps 這些領域的一些能力,這是技術架構要做的事情。

從技術角度看,雲原生架構是基於雲原生技術的一組架構原則和一些設計模式的組合,將應用中的非核心的業務邏輯剝離出去,然後下沉到雲原生基礎設施這一層來統一處理,這樣業務開發人員只需要關心自己的業務開發,讓我們的業務應用變得更加輕量,高效。

圖片

因為公司是 2013 年成立的,早期的業務非常簡單,運維能力也比較差,所以單體架構是優選。經過四五年的發展,業務有了長足的進步,平臺的功能和模組都已經比較多了,因此,就升級到 Spring Cloud 微服務架構。當時用的是一套標準的用法,比如服務註冊中心、配置中心用的是 Eureka,閘道器用的是 Spring Cloud Gateway。

圖片

此時,雖然實現了微服務架構,但也存在諸多問題,例如服務不穩定、排查效率低下、資源利用率低等。基於這些問題,開始做業務容器化改造。

首先,選用成熟的 K8s 平臺去做業務容器平臺,先解決部署與排查問題。 一開始我們選型的是阿里雲容器服務 ACK Serverless 版,主要是看中了它開箱即用,不需要額外去維護,比較簡單的優點。在使用的過程中,主要是先在開發側去驗證它,用了一段時間到 2021 年的時候,就完成了線上的遷移。

之後選用阿里雲 ACK 的技術底座去完成線上容器化改造的原因是,當時在用 Serverless 過程中出現一些問題,比如排程比較慢等,在當時我們是沒有這些能力去解決的。改造之後,大概是 300 多個微服務。此外,還涉及到一些基礎架構的改造,比如服務註冊中心,我們原先用的是 Eureka,後來遷移到 MSE 的 Nacos 裡,配置中心使用了 MSE Nacos,來提升效能和穩定性。

在可觀測性和應用性的架構上,開始用阿里雲應用實時監控服務 ARMS 的應用監控能力和 MSE 產品來對應用服務進行效能觀測與流量治理,這些都是在 2021 年這一年去完成的。

2021 年 8 月,我們將 Spring Cloud Gateway 進行了遷移,因為當時 Spring Cloud Gateway 的問題比較多,效能也比較差,所以就基於開源做了自己的 API 閘道器,再結合 MSE 的微服務套件,實現了流量管理。2022 年之後,開始做業務指標監控和穩定性建設這方面的工作。

青團社雲原生架構實踐

接下來是實踐的部分,這張圖是線上的部署圖。

圖片

前面這 4 個部分都是技術接入層,如 BGP 高防、WAF、BFF 等,主要提供基礎的安全防護和路由轉發功能。到了虛線這一部分是 K8s 叢集,是基於 ACK 構建的容器執行平臺,我們所有的業務容器都執行在 ACK 裡面。

大家可以看到,我們運用了很多阿里雲的中介軟體服務,比如 Kafka、RocketMQ。這些都是在使用 MSE 微服務引擎之後最新的一版架構,由於我們人手有限,所以為了線上的服務穩定性和降低運維成本,會直接用阿里雲的這些雲產品。 閘道器方面,微服務內部的東西向流量主要由微服務引擎 MSE 來做流量管理,它給我們提供了一些能力,比如服務優雅上線下線,流量灰度,還有同可用區域這些部署能力。

接下來,我們將從排程編排、流量管理、可觀測 3 個維度展開我們的實踐。

1. 雲原生架構實踐排程編排

圖片

第一部分是排程編排方面,我們有三個手段。首先是使用阿里雲 ACK 作為技術底座來構建容器平臺,再配合資源隔離的部署模式,保證多條業務線互不影響,因為我們有兩條不同的業務線,所以無論是在成本核算還是服務穩定性,都會做到資源隔離。彈性伸縮方面是透過一些彈性伸縮策略取得成本和穩定性之間的平衡,降成本的同時不能損失穩定性。

接下來,透過兩個案例闡述一下,第一是我們怎麼樣用 ACK 來實現高效彈性部署。

圖片

首先,在部署的時候是多可用區的,有杭州 H 區和 K 區,這是兩個主可用區,所有的服務在部署的時候,在 K8s 的節點分隔上和排程策略上加一些標記,讓它能夠把業務負載給打散,這樣一個服務有兩個例項的話就是 K 區和 H 區各一個,一個掛了另一個還是好的。

在釋出階段,因為滾動更新是 K8s 內建的機制,可以透過簡單的配一些健康檢查的機制來得到好的釋出體驗,保證服務在釋出的過程中不會出現業務受損。透過資源監控和業務容器監控,可以靈活伸縮業務容器的規模。節點池設計是 ACK 獨有的,它相當於能為不同的業務線配專屬節點,這樣就可以達到物理隔離,有了節點池,要去做叢集的彈性伸縮容的時候就非常方便,叢集資源不夠時可以透過簡單的透過節點池的擴容操作,瞬間把節點池資源能力提升上去。

CSI 外掛主要是用在開發測試環境。我們為了節省成本,很多開發測試環境,像中介軟體都是用容器自建的,容器自建屬於有狀態應用,有狀態應用需要儲存來支援它。CSI 外掛,阿里雲提供了很多對應的對接,比如阿里雲的雲盤 OSS、NAS 等。我們主要是用雲盤外掛來對接,把雲盤掛到容器裡,這樣像資料庫、Redis 等就可以得到穩定高效的儲存。

VPC 方面,因為 ACK 裡 VPC 網路是直通的,我們用的是阿里雲的 Terway 外掛,這個外掛可以把容器內部的網路和我們的 VPC 互相打通,這個能力我們覺得比較重要,是因為沒有上容器平臺之前,我們的服務都是部署在 ECS 機器上的,現在如果要遷進去,我們的服務發現元件它在叢集之外,就必然要讓網路能夠互通,否則它發現不了也就無法遷移了,所以 VPC 直通功能對我們是非常有用的。

另外還有叢集監控,主要是體現在 ACK 提供了開箱即用的叢集,藉助與 ACK 深度整合的可觀測監控 Prometheus 版,對 K8s 叢集和業務容器輕鬆構建資源監控體系。一方面,可以及時瞭解容器執行情況和叢集執行情況,另一方面,這些叢集監控的技術指標可以作為我們判斷系統是否需要擴容縮容的資料依據。透過部署基於指標或者是事件的彈性深度機制,能夠快速對容器進行擴容。

以上這些使用場景,大部分公司應該都是類似的,可以總結一點:透過容器化來部署,充分運用雲的能力,降低應用成本,保障應用高可用。 這是第一個案例。

第二個案例是如何利用雲來實現業務彈性。

圖片

這裡有三個小的業務場景,第一是埋點,第二個是廣告投放,第三個是熱點活動。

埋點大家應該都不陌生,每個網際網路公司都會需要埋點,透過埋點資料來了解使用者,分析使用者。埋點資料作為分析使用者行為的資料資源,在整個產品的生命週期裡面都非常重要。但是埋點資料的量通常都是非常巨大的,使用者每一次點選,頁面的曝光,還有使用者的互動都會產生很多埋點資料。這些資料可以上傳到後臺去分析產品的使用情況,分析使用者的行為和使用習慣,還可以延伸出做使用者畫像,使用者偏好及使用者轉化路徑這一系列資料產品。

我們的埋點有很明顯的潮汐特徵,流量通常是早上七八點鐘開始逐漸上升,到了中午十一點、下午兩點到達一天的頂峰,然後再開始逐漸下降,到夜晚四五點鐘的時候就達到一天中最低,埋點資料量的規模也遵循這樣的規律。

埋點資料,我們通常是先把資料發到後臺,後臺有埋點接收資料的處理程式,先簡單的把它處理一下,然後給它丟到 Kafka 裡,再由大資料的一個平臺的元件去消費,消費完之後儲存進去。

我們的大資料團隊會透過埋點資料來構建不同的資料層,供不同的業務場景使用,在部署埋點接收程式的時候,就會充分考慮埋點流量的潮汐特徵,去把它做一些定時擴容縮容的機制,比如可以加一些定時任務,早上九點、十點開始擴容擴一倍,就可以應對一天的流量高峰,到晚上再把它縮回去。

廣告投放方面也很重要。我們平臺也和很多網際網路平臺有廣告投放的合作。在他們平臺裡面去投放廣告吸引新使用者。作為一項日常的運營工作,投放的時間點可能不太固定,它的效果也不一定能按照預期來,有時候出現爆點,流量就可能會被打爆。同時,伴隨流量而來的一些點選資料或埋點資料都會劇增。

為了做好日常廣告投放的工作,我們做了基於指標和事件的動態擴縮容機制。如果是因為應用容器資源,比如 CPU 記憶體爆了或者是達到了警戒線,又或者是處理資料的程式,有 MQ 訊息積壓的事件出現了之後,就去對事件進行監控,然後動態的去擴容。

我們用開源的 KEDA 工具配置業務指標進行監聽,KEDA 工具透過監聽 Prometheus 裡面的指標 (我們所有的指標都存在 Prometheus 裡面) ,如果觸發條件了之後會向 K8s 的 API server 發起一個 Pod 的擴容請求,這樣就完成了擴容操作,整個過程都是自動化的。

最後的熱點活動,類似於電商裡面的促銷活動,這個場景的特點是它的開始時間和結束時間都是已經提前知道的,這樣只需要配備提前擴容的程式就可以了,比如到體驗活動開始前的半小時先把容器給擴上去,結束之後就縮回去,我們主要是基於指標和事件這兩點來做彈性擴容。

2. 流量管理

這部分主要分享一下怎麼去對流量進行管理。我們主要分三個部分:閘道器、流量服務治理引擎 MSE、訊息佇列。

這裡有兩個案例,因為作為頭部的靈活用工企業,我們有很多端,比如有 C 端,B端,有安卓平臺,有 iOS 平臺。各大網際網路平臺,像支付寶、抖音、快手、百度、QQ 等都有對應的投放、產品和小程式在上面。

圖片

行業上也主要聚焦於 8 大行業,像餐飲、物流、商超這些。在這種在多埠,多行業的場景下,我們的報名崗位在類目上,或者是埠上都有很多差異,無論展示邏輯還是流量分發的規則都是有差異的。我們透過 API 閘道器和  BFF 來實現流量編排和不同埠的差異化處理。

閘道器這塊主要是把流量引進來,BFF 主要是適配各端,它自己可能需要獨有的一些資料格式,然後再呼叫後端的資料返回去。在閘道器裡, BFF 本身是作為後端服務存在的,流量先經過閘道器,再經過 BFF 後透過後端把資料返回去。BFF 具體的實踐架構不再贅述,但在青團社是用這個模式來做多埠的適配。

圖片

第二個案例是基於事件驅動構建靈活響應系統,案例是我們靈工管家這個產品,該產品主要是提供一系列的管理服務,比如考勤、發薪,還有排班等服務,這些服務是企業用到的一些企業級服務。平臺使用者可以做到薪資日結,像很多兼職崗位,商家都是提供兼職日,你早上去上班打卡,然後下班打完卡,還沒到你回家,工資就到賬了,這個就職體驗是非常好的。

這就是基於事件來驅動,下班打卡之後會觸發下班打卡的事件,觸發算工時、算薪資的邏輯,再到提前到賬,整個流程是全部事件驅動的,快的話可能幾秒鐘你的薪資就能到賬,這也是靈工管家的比較好的一個產品賣點。

當然訊息 MQ 的場景是很常見的訊息解耦,但我們還有別的場景,我們把 MQ 用在資料同步和訊息分發上。資料同步用了一些外掛和元件做一些資料同步的工作, MQ可以給它做一個緩衝,避免資料很多,一下子把對端給打爆了。

訊息分發的話,我們訊息平臺會有一些定時需要觸發的定時訊息,比如給使用者發推送簡訊,我們會利用 MQ 的延遲訊息能力去做,相當於到點之後,你就去觸發這一訊息,然後給使用者發簡訊,發 push,這是一個具體的案例。

圖片

下面的案例介紹一下怎麼實現灰度。早期我們沒有灰度,所有的服務只要一上線,就相當於是全量狀態,沒法去驗證服務到底對使用者有多大影響。在 2021 年完成業務容器化改造之後,我們就引入了 MSE 微服務引擎來幫助我們實現全鏈路的灰度。

所謂全鏈路,指的是在流量鏈路這一層,閘道器進來之後到服務再到資料庫,或者到經過訊息中介軟體的這個鏈路。還有一個就是訊息方面,要對流量的特徵進行打標,然後鏈路的下一跳可能也需要打標,標識一下它要去到哪裡。閘道器要負責南北流量的分發,在外部,我們透過開源的 APISIX 閘道器,它是有流量分拆外掛的,可以在釋出的時候,透過部署多個版本,在釋出的時候,部署兩個版本或者或多個版本,叫 deployment。部署完了之後,再給它打標,然後閘道器上面會有個流量分拆外掛,你可以配一些特徵,然後讓流量進到指定的版本。

進來之後,這裡面東西向的流量就屬於 MSE 微服務引擎來做的事情。它透過 agent 插裝的方式,把整個鏈路給串起來,實現了整個鏈路的灰度。

比如說像 HTTP 請求,它可以在請求頭上加 gray 標識,然後依次透傳到底層去。到訊息中介軟體這一塊,它對 MQ 這塊做一些增強,相當於是埋點一樣,把這些流量的灰度標記埋進去。然後在消費端做一下控制,這樣就可以保證你的流量能按照你預定的規則順利的進來。

重要的線上服務要釋出的時候,先走一下灰度,可以明顯的增強我們的信心。原先沒有灰度的情況下,釋出的時候都是很忐忑的,一般白天不敢發,都是夜晚才發,就是為了防止故障,因為你如果有問題的話,可能會影響很多使用者。現在我們已經有 7300 萬使用者了,雖然說日活不是很高,但月活也有 1000 多萬,所以說白天的流量還是非常大的。透過灰度釋出,有問題的話在灰度階段就能發現把它解決掉。

圖片

下面的案例是使用微服務引擎實現優雅上下線,這個能力也比較重要。因為早期很多線上故障都是因為釋出導致的,經常在釋出中發現很多服務調不通了,是因為它在下線過程中,但呼叫方這邊不知道還去請求,就會報錯。因此,在 2021 年,我們用微服務引擎 MSE 把服務期間不平滑的問題解決了。

優雅下線的原理其實非常簡單,比如說服務提供者,我們稱為 provider,他如果發了新的例項,當然流程還跟以前 K8s 滾動更新機制是一樣的。他先滾動更新一個新版本的過程中,會觸發老版本的下線動作,老版本下線動作就會執行 pre stop 鉤子函式,這個函式是 K8s 提供了內建的機制,這個函式里 MSE 會提供一個介面,透過呼叫這個介面,讓 MSE 的 agent 感知到服務要下線了,趕緊觸發下線的事件。

事件觸發之後,它的呼叫方可以感受到事件,然後在自己本地的 ribbon 服務列表快取裡面把 IP 給摘掉,摘掉之後,後面的請求就不再呼叫了,相當於我知道你要下線就把你提前摘掉,不呼叫就不會報錯了。

服務上線的原理也差不多,上線之前先延遲一會兒,先不那麼快到註冊中心,而是放一點點流量進來,這個節奏是透過 K8s 健康檢查機制來實現的。MSE 提供健康檢查的介面,它會透過介面去向 K8s 暴露服務到底有沒有準備就緒。現在沒有準備就緒,流量就不能全部放進,可以放一點點,比如百分之零點幾的流量進來,我先把服務預熱一下,該建立的連結先建立起來,等到服務完全就緒之後,再把流量放進來,這樣無論是下線還是上線,服務都是處於相對平穩的狀態,下線呼叫端提前知道的話就不會再呼叫了。上線是先給你一段時間,讓你先準備好,準備好之後,我再把流量放進來,這是優雅上線的原理。

3. 可觀測和監控

接下來我講一下可觀測的實踐,可觀測主要用到阿里雲 ARMS 應用監控 + Prometheus + Grafana 以及雲監控這個組合。

圖片

這個圖就是用阿里雲的雲監控進行基礎資源監控,如 ECS、雲資料庫 PolarDB、雲訊息佇列,這些基礎監控都有些對應的指標。

那如果要進行更精細、全面的指標監控,阿里雲也提供 Prometheus 指標監控能力,它會把你的指標放到 Prometheus 裡面,利用預置模板快速構建告警體系的同時,也可以透過自己的業務需求去配置相應的自定義告警規則。

第二個是應用實時監控服務 ARMS,作為一個具備諸多監控模組的雲原生可觀測平臺,我們用其中的應用監控來解決 Java 應用效能的監控問題,我們的應用線上上跑的時候可能會突然發現有幾個請求報錯,或者是響應極慢,那研發人員要要怎麼去排查呢?

透過 ARMS 應用監控去觀測整個呼叫鏈路,及時發現整個鏈路到底哪一環節執行的比較慢。透過耗時數看得到,看得到之後定位一下的問題,比如說像這個例項裡面,這是高德的三方介面比較慢,因為三方介面耗時確實是不可控的,這種問題我們可以提前知道,還有一些超時、異常問題,這些都可以透過 ARMS 應用監控發現,當然也可以配相應的一些告警規則。

圖片

除了雲基礎設施以及應用效能,我們希望進一步對業務指標進行監控,實現全棧可觀測。針對業務指標監控,我們主要是用 Prometheus 和 Grafana 來進行加工與呈現。這裡有兩個案例,一個案例是基於業務指標,也就是訊息中心的監控大盤,這裡面的所有的資料都是透過 Java 端用 Prometheus 的客戶端把指標資料暴露出來,然後 Prometheus 服務端把這些資料採集上來,再給它配成這種圖表。

圖片

配成圖表之後就可以視覺化了,能看到現在的業務執行狀況,這個曲線和兩個圖例應該都是實際的業務運營狀況,有了這些資料,就有了監控告警的條件,沒有這些東西就不知道業務到底執行怎麼樣。

圖片

然後日誌告警中心這部分,像一些嚴重的日誌報錯,Error 日誌這些比較重要的日誌報錯,我們會配對應的一些告警規則,在出現問題的時候進行及時告警。

經過這麼多年業務發展,我們的業務一直是在雲上不斷的發展和壯大,充分用了雲的各項能力來構建平臺。我們主要考慮的是成本,穩定性和研發效率這三塊,希望能達到平衡。因為我們團隊本身也比較小,所以用雲的優勢是非常明顯的,可以利用雲的彈性有效應對日益劇增的業務增長規模。雲原生之路我們還將繼續,在此先彙報我們的成果。

圖片

透過容器化部署,提高部署密度的方式,把原先的 ECS 成本降低了 50%, 因為原先 ECS 部署的比較粗放,可能一臺機器上只部署一兩個或者兩三個服務。透過容器化的部署,可以提高部署密度。

第二個是應用實現了高可用和彈性排程,使我們可以從容的應對未來的業務增長。

第三個是透過全面實施基礎資源、應用服務及業務監控,快速瞭解系統執行狀態。過去,系統執行狀況對我們來說是一個黑盒。即使有一部分資料,也無法有效的對不同型別資料進行加工與利用,一切都是未知。透過這些能力,從無到有的建設,我們現在可以非常快速的去了解、觀測系統的狀態。

第四個成果是運維成本大幅降低,把機器給省下去了,像一些人工需要做的事情,現在透過高度的自動化可以實現大規模的叢集管理。

總結與展望

展望未來,可能會更多的考慮這以下三個方向,這些也是我們未來要做的事情。

  • 我們現在比較關心的服務網格,因為以後也會有更多語言,像一些應用比如說 Java、Python、Go 這些,MSE 目前可能對 Java 的支援非常好,後面我們也會探索基於服務網格的通用的流量治理能力。
  • 因為 Java 佔我們整個應用的體量大概是 80%,後續會考慮用一些新的技術,比如用 GraaLVM native 來實現原生映象部署,這樣可以進一步降低應用的資源佔用情況,提高應用的響應峰值效能。
  • 透過混沌工程的實施,進一步提高線上的穩定性。目前我們的穩定性可能還沒有達到理想的目標,這是後面的努力方向。

相關文章