本文是根據 KubeSphere 雲原生 Meetup 杭州站講師祁寧分享內容整理而成。
SegmentFault 是一家綜合性技術社區,因爲它的內容跟編程技術緊密相關,所以訪問量的波動也和這一羣體的做息時間深度綁定。一般狀況下 web 頁面的請求量峯值在 800 QPS 左右,但咱們還作了先後端分離,因此 API 網關的峯值 QPS 是請求量峯值的好幾倍。php
SegmentFault 做爲一個技術社區的系統架構變化,裏面有些東西仍是頗有意思的。node
緊接着,咱們遇到了很多挑戰,促使使咱們不得不往 K8s 架構上遷移。react
2020 年之前,SegmentFault 的網站仍是很是傳統的後端渲染頁面的方法,因此服務端的架構也很是簡單。服務端將瀏覽器的 http 請求轉發到後端的 php 服務,php 服務渲染好頁面後再返回給瀏覽器。這種架構用原有的部署方法還能支撐,也就是在各個實例上部署 php 服務,再加一層負載均衡就基本知足需求了。web
然而隨着業務的持續發展,後端渲染的方式已經不適合咱們的項目規模了,所以咱們在 2020 年作了架構調整,準備將先後端分離。先後端分離的技術特色我在這裏就不贅述了,這裏主要講它給咱們帶來了哪些系統架構上的挑戰。一個是入口增多,由於先後端分離不只涉及到客戶端渲染(CSR),還涉及到服務端渲染(SSR),因此響應請求的服務就從單一的服務變成了兩類服務,一類是基於 node.js 的 react server 服務(用來作服務端渲染),另外一類是 基於 php 寫的 API 服務(用來給客戶端渲染提供數據)。而服務端渲染自己還要調用 API,而咱們爲了優化服務端渲染的鏈接和請求響應速度,還專門啓用了了使用專有通信協議的內部 API 服務。數據庫
因此實際上咱們的 WEB SERVER 有三類服務,每種服務的環境各不相同,所需的資源不一樣,協議不一樣,各自之間可能還有相互鏈接的關係,還須要負載均衡來保障高可用。在快速迭代的開發節奏下,使用傳統的系統架構很難再去適應這樣的結構。編程
咱們迫切須要一種可以快速應用的,方便部署各類異構服務的成熟解決方案。segmentfault
首先是開箱即用,理論上來講這應該是 KubeSphere 的優勢,咱們直接點一點鼠標就能夠打造一個高可用的 K8s 集羣。這一點對咱們這種沒有專職運維的中小團隊來講很重要。根據個人親身經歷,要從零開始搭建一個高可用的 K8s 集羣仍是有點門檻的,沒有接觸過這方面的運維人員,一時半會是搞不定的,其中的坑也很是多。後端
若是雲廠商能提供這種服務是最好的,咱們不用在服務搭建與系統優化上花費太多時間,能夠把更多的精力放到業務上去。以前咱們還本身搭建數據庫,緩存,搜索集羣,後來所有都使用雲服務了。這也讓咱們的觀念有了轉變,雲時代的基礎服務,應該把它視爲基礎設施的一部分加以利用。瀏覽器
若是能把運維工做所有用代碼來管理,那就再理想不過了。而目前 K8s 確實給咱們提供了這樣一個能力,如今咱們每一個項目都有一個 Docker 目錄,裏面放置了不一樣環境下的 Dockerfile,K8s 配置文件等等。不一樣的項目,不一樣的環境,不一樣的部署,一切均可以在代碼中描述出來加以管理。緩存
好比咱們以前提到的一樣的 API 服務,使用兩種協議,變成了兩個服務。在這如今的架構下,就能夠實現後端代碼一次書寫,分開部署。其實這些文件就代替了不少部署操做,咱們須要作的只是定義好之後執行命令把它們推送到集羣。
而一旦將這些運維工做代碼化之後,咱們就能夠利用現有的代碼管理工具,像寫代碼同樣來調整線上服務。更關鍵的一點是,代碼化以後無形中又增長了版本管理功能,這離咱們理想中的全自動化運維又更近了一步。
持續集成標準化了代碼發佈流程,若是能將持續集成和 K8s 的部署能力結合起來,無疑能大大加快項目迭代速度。而在使用 K8s 以前咱們就一直用 GitLab 做爲版本管理工具,它的持續集成功能對咱們來講也比較適用。在作了一些腳本改造以後,咱們發現它也能很好地服務於現有的 K8s 架構,因此也沒有使用 K8s 上諸如 Jenkins 這樣的服務來作持續集成。
步驟其實也很簡單,作好安全配置就沒什麼問題。咱們本地跑完單元測試以後,會自動上線到本地的測試環境。在代碼合併到上線分支後,由管理員點擊確認進行上線步驟。而後在本地 build 一個鏡像推送到鏡像服務器,通知 K8s 集羣去拉取這個鏡像執行上線,最後執行一個腳原本檢查上線結果。整個流程都是可視化可追蹤的,並且在代碼管理界面就能夠完成,方便開發者查看上線進度。
目前咱們用一個專門的倉庫來管理這些基礎鏡像,這可使開發人員擁有與線上一致的開發環境,並且後續的版本升級也能夠在基礎鏡像中統一完成。
除了將 Dockerfile 文件統一管理之外,咱們還將鏡像 build 服務與持續集成結合起來。每一個 Dockerfile 文件都有一個所屬的 VERSION 文件,每次修改裏面的版本號並提交,系統都會自動 build 一個相應的鏡像並推送到倉庫。基礎鏡像的管理工做徹底自動化了,大大減小了人爲操做帶來的錯誤與混亂。
最後是一點感想:當作完容器化後,會發現應用在集羣裏運行的時候並不須要佔用那麼多臺服務器。這是由於下降了資源的粒度,因此能夠作更多的精細化規劃,所以使用效率也提升了。
本文由博客一文多發平臺 OpenWrite 發佈!