1. 程式人生 > 實用技巧 >主流SpringCloud微服務架構,您可少走彎路

主流SpringCloud微服務架構,您可少走彎路

背景

時間回到2017年底,那會兒SpringCloud正處於如火如荼的狀態,加上與K8s的完美契合,整個網際網路公司也想借著這波熱度做一次真真正正轉型,但真正能落地有經驗的人少之甚少,大部分公司還是摸著石頭過河,不清楚一個完整的體系中到底需要包含哪些東西,我有幸負責了從零到一建設,見證了從一到一百的過程,下面我講帶你揭開什麼是企業級SpringCloud微服務架構吧,就倆字“真™香”。

前言

如果您正在籌備如何搭建電商領域的業務中臺,還在煩惱技術如何選型,那麼這篇文章看完保你治百病,如果你只是想隨便看看,那拿好小本本記好吧,這篇文章乾貨實在太多了。

你說中臺過時了?其實這就是個名詞,沒什麼過不過時這麼一說,我在2012年就開始做類似的事情,只不過當時也沒啥好的代言詞,那會兒在流行的是SOA架構,出去跟人說我在做ESB個個覺得這個厲害,雖然兩者間理念不一樣,但是從設計思路上來看完全一致,SaaS化的模型,多租戶的體系,歸根結底就是要高度抽象複用。這種架構我這一做就是小10年,一直在To B的領域長期奮戰,期間也做過To C的產品,但總覺得不來電,或許這就是To C與To B的區別,兩者間的複雜度並不在一個方向,你要硬讓我說哪個更復雜,我會選To B,因為要求廣度更深,你才能抽象出更快速能交付給前臺可使用的能力,靈活配置成為了To B重中之重,當然並不是說To C不復雜,我認為他們不在一個維度,有著多入口大流量的To C產品,你要設計的絕對是極簡好用架構。

接下來說說我用這個架構承載了什麼樣的業務,搭建的初期壓根也沒想著搞什麼中臺,那會兒公司的生意是做各個頭部品牌電商,當時的玩法是給每個品牌獨立部署屬於他們網站,程式碼也是從一套基線中複製貼上,這種做法並不是完全不可行,其實大部分公司現在還是這個套路,但它的弊端你是也絕對不能忽視的,例如新增的特性如何應用於已經交付的品牌中,再例如基線中程式碼存在缺陷怎麼快速修復應用,這些看似簡單的問題當你真正身處在其中,你會發現最後不是寫程式碼那麼簡單的事情,牽扯到一系列的協調和事務性工作,大大降低了對外的交付效率,所以我們下定決心去做一次轉型,希望能通過一種中心化微服務的方式,讓交付團隊更專注於交付的本身,從而降低企業研發成本。至於能提供什麼樣的能力,這完全取決於你的公司是做什麼生意的,比如做電商要提供商品、訂單、促銷、內容等能力,比如做教育要提供教務、培訓、課程等能力,但是你發現這些能力還是業務產品導向,其實與架構本身沒直接關係,所以基於一套標準的微服務架構建設體系可以在在任何領域。

正文

廢話不多說,先上一張精心打磨的架構圖,喜歡的可以去ProcessOn觀摩(我可不是打廣告,畢竟國內除了它也沒啥好用的線上繪圖工具)戳我去看

接下來我會對著這張架構圖去剖析每個板塊承載的職責

微服務

微服務是一種用於構建應用的架構方案。微服務架構有別於更為傳統的單體式方案,可將應用拆分成多個核心功能。每個功能都被稱為一項服務,可以單獨構建和部署,這意味著各項服務在工作(和出現故障)時不會相互影響。

想把研發團隊做強做大,我還真想不出來有什麼架構比微服務更合適不過了,想想如果幾個人維護個單體應用還是搞定的,但是隨著公司規模擴充套件,業務增長井噴,帶來的就是要擴招產研團隊,那麼相對獨立工程搭建方式就成了最佳實踐,下面我會講講沉澱出的一些標準領域服務,這些服務可能適用於各行各業,各個領域。

業務型

  • 訂單領域,全渠道訂單整合,從傳統零售到新零售在到跨境電商,任何行業多少都會與訂單相關,做為業務中臺最核心領域,設計出漂亮的統一訂單服務至關重要

  • 商品領域,全渠道商品資訊管理,為收集、管理和豐富商品資訊,並將其分發到任何的電商銷售渠道,讓運營團隊上新產品的交付更快速,更便捷

  • 營銷領域,促銷、卡券、大轉盤、拆紅包,但凡你們公司的產品需要拉新還是復購,做營銷就少不了它

  • 內容領域,企業建站,SEO,頁面的動態配置,數字資產維護,幾乎每個公司都會需要

引擎型

  • 支付引擎,聚合支付閘道器,遮蔽業務與支付渠道挨個對接的痛點,真正做到一次接入全渠道打通,而且這個產品無關公司屬性,可以一直擴充渠道

  • 訊息引擎,基於事件驅動訊息的傳送,封裝各類通道如SMS、Email、Push、Callback、Webhook等,通過事件配置化選擇通道傳送

  • 搜尋引擎,在Elasticsearch、Solr之上包裝的一層通用服務,遮蔽由中介軟體升級更新帶來的服務被動升級,弱化查詢語句,對外統一標準,適用於全文檢索、海量訂單多維查詢、業務型日誌場景

技術型

  • 檔案服務,提供統一檔案上傳下載,匯入匯出能力,讓業務無需關係儲存介質的實現,集中化處理任何與檔案相關功能

  • 元資料服務,提供數字字典,系統變數,主資料儲存能力,與業務無關

  • 排程服務,定時任務處理,開源產品XXL-JOB、ELASTIC-JOB都很好用,當然自研也是個不錯的選擇,前提是別重複造輪子

服務治理

配置中心 Apollo

如果你想要做All in one製品釋出,沒有配置中心配置管理起來可非常麻煩,我舉個例子,假設你將服務的全環境配置都打進了製品中,突然在上線的當天說有個配置要修改一下,這個時候可想而知,你需要重新打包製品,而這個重新打包製品的環節,沒有人能保證兩次製品的Gap只是配置的變更,所以我們需要將程式與配置隔離,從而做到All in one輸出能力最大化。

不是講SpringCloud架構嗎,為啥不用Spring Cloud Config,還是那句話Spring給你提供是最基礎的特性,如果想投產使用往往都需要加工,就拿Spring Cloud Config來舉例,配置的維護要是要藉助Repository來完成,這在工程實踐中是不可想象的事,最後還是要研發出一款專門為配置做的視覺化工具,所以像Apollo這種開箱即用的產品還是非常好用。

註冊中心 Eureka

這不都閉源了嗎為什麼還要用,確實註冊中心產品一大把Zookeeper、Consul、Nacos想用哪個都可以,不過我們圍繞著Eureka做了新特性,比如灰度釋出,多租戶隔離,通過Metadata注入的方式,標記著每個服務的用途,配合著SpringBootAdmin可以線上控制每個服務允許接收的流量請求,其實對於註冊中心來說,能做到服務發現和服務註冊的功能也就差不多了,從治理的角度來看,要明確每個角色的職責。

中介軟體

RDS類的選型如果在非自建IDC的情況下,儘可能選用雲服務,像Mysql、Redis、MongoDB這些產品雲服務都提供了完整的生態,無論是擴充套件性、可用性、穩定性來說都要比自建來的更實惠,不然你就要斥巨資讓DBA維護著這些產品,坦率講自建真的能做到跟雲產品媲美嗎,這裡要打上個問號。

非RDS類產品儘可能還是自建吧,比如K8s、RocketMQ、Elasticsearch這些產品牽扯到雲供應商的切換風險,一旦哪天你老闆心血來潮說我們從阿里雲換成AWS吧,那你可真得掂量掂量換得來不。

中介軟體在微服務架構中扮演著非常重要的角色,搭建時一定要保證這些產品的高可用性與叢集擴充套件能力,可不能搞個單機版當遊戲玩,我的經驗來看中介軟體搭建不當發生的事故概率是非常高的

日誌分析

日誌是用時方恨少,我想這是每個工程師的心聲,如果你的公司看日誌還通過登入到伺服器,或者由運維工程師線下私信給你,那你可能要想想是不是換成線上日誌平臺了,畢竟基於Elasticsearch引擎,搜尋的姿勢可以變換自由,想搜啥就搜啥,而且 ELK 也不僅僅侷限於日誌領域,也可以通過Alert元件來實現業務保障特性,例如服務提前埋好點,對於一些業務的例外錯誤,可以收集起來提前預警,第一時間通知運營及產研團隊。

Monitor

完備的監控體系是在微服務架構下不可或缺的環節,我們可以通過不同維度的監控,從而大幅度提升服務的穩定性。

服務監控

這裡使用SpringBootAdmin,它可以實時檢查服務健康程度與記憶體和CPU指標,動態檢視HttpTrace與執行緒使用情況,而外附加輕量日誌查詢功能

K8s叢集監控

這裡使用Prometheus,第一時間獲取Pod超閾值報警,這與服務監控維度不同,更多的是來檢測系統級故障

An open-source monitoring system with a dimensional data model, flexible query language, efficient time series database and modern alerting approach.

主機監控

如果有自建機房,你可選用 Zabbix,如果是用雲服務,那就用自帶的監控吧,絕對不差事

監控視覺化

少了 Grafana 可不行,不然你連裝B投大屏的機會都沒了,把Prometheus實時檢測的資料做幾個Dashboard搞個75存大電視一投,那逼格一下子就上來了,安利老闆的利器。

全鏈路監控

這裡我會選用 Pinpoint,你可能會說Skywalking不比這好多了,如果你不是深度使用者,隨便看幾篇對比的文章就下定論那太草率了,Skywalking支援的監控外掛確實多,社群也很豐富,Agent效能確實比Pinpoint要強,但這些往往不是我們最迫切需要的,我們用全鏈路監控的目的是能看得清呼叫鏈路中存在的潛伏問題,需要的詳細Trace,作為架構師或Director的你,總不能在服務效能出了問題的時候跑到工程師電腦前Debug吧,我們需要用工具提供儘可能的幫助,來讓工程師有自主解決問題的能力,我寧願犧牲些效能來換取更強有力的工程實踐,或許這也就是To C與To B產品的側重點不同之處吧。

DevOps

微服務就必須要結合DevOps?不結合你還敢說你微服務架構精通,我看你連門還都沒入,還跟我扯精通。微服務的精髓亦是與DevOps緊密結合,如果把服務看作產品交付物,DevOps就是車間流水線,保證的是你每次產品迭代升級不出錯,可以更快速更持續的交付出高質量產品,如果你釋出的服務都是一次性的那就當我沒說,不過我還沒見過哪個公司產品那麼牛b,迭代都不用的。

沒聽過DevOps,CI CD總聽過吧,啥,這也沒聽過?彆著急,這其實就是個名詞,你公司指定早就在做了,只是沒那麼標準罷了,或者說沒做到某種程度。

DevOps這詞兒早在10年前就有了,只不過都是歪果仁提出的,當時迷迷糊糊的也確實不知道是幹啥用的,上張圖你一看就明白了。

切,我們公司就是這樣做的啊,開發,測試,運維相輔相成,配合的相當默契。我猜你說的應該是通過即時通訊配合的默契吧,這種協作性不排除在一些規模不大的公司確實很默契,想過研發團隊幾百號人,服務成百上千時的情形嗎?那一定是小馬拉大車,再好的發動機也會被累死。

我們需要做的是讓它自動化,智慧化,數字化。

  • 啥是自動化?讓你連構建按鈕都不要點,Push程式碼到倉庫後,通過webhook自動觸發流水線作業,構建過程引數化,不需要人工干預,自主驅動Jira Task
  • 啥是智慧化?貫穿研發,測試,運維,加速釋出週期,監控釋出成功率,實時反饋結果,確保軟體交付質量
  • 啥是數字化?將程式碼貢獻量,質量率,bug數,構建的成功失敗率,hotfix頻率結合在一個視窗下展示,資料真正的價值一目瞭然,這裡就不展開講了

想想以前釋出個新專案要多久,10分鐘,半小時,還是1天?我怕你一禮拜都搞不定,為啥,上新服務時Ops工程師會問“埠號是啥”,“域名是啥”,“配置配好了嗎”,“要部署幾個節點啊”,“是tomcat部署嗎”,一大堆亂七八糟的問題撲面而來,好不容易你都弄明白了,Ops工程師給你來句“唉,你埠號和別的專案衝突了,換成這個吧”,我去™的那你問我幹嘛。這種無意義的內耗加劇了企業交付的難度,原本很簡單的事情變得複雜化,原因歸根結底都是跟“人”有關係 這也就是為什麼我們需要通過DevOps來解決工程實踐中交付難的重要意義,未來國內研發的時代一定會向Facebook、Google看齊,變成人人自驅、來去自由的時代,阿里的雲效就是在將軟體工程推向另外一個高度。

概念聽完了那再來說說什麼是CI(持續整合)CD(持續交付),這是真正落地的產物,通過兩個核心的平臺來支撐整個流程

自動化運維平臺

你首先得知道這個平臺到底能幹啥?簡單說構建釋出,複雜說你得保證構建和釋出的結果不能有問題,那我們是怎麼搭建這個平臺的?

首先一些產研用到的工具都得先準備好,比如Jira、Confluence、Gitlab、Nexus、YApi(介面文件平臺)、Yearing(SQL工單平臺)等,有了這些產研團隊就可以開始幹活了。

然後要開始準備構建與釋出用到的工具,比如Jenkins、Kuboard(K8s叢集管理工具)、Harbor、Sonarqube等,這些準備好了基本上就可以做第一版的CI/CD流程了,這裡我要重點強調所有與運維相關指令碼一定要放在程式碼倉庫中管理起來。

框架搭建完畢後,剩下的就是在每個需要用到的地方塞東西里,比如你想在構建完成後發個Webhook通知下企業微信或者釘釘訊息

✏️ 劃重點

持續整合是保證軟體質量非常重要的一環,貫穿整個流程需要Jenkinsfile來驅動它,我們這裡採用集中式Jenkinsfile來管理所有的服務,另外構建要恆定從一個分支去做(Hotfix除外),確保構建出來的製品可以釋出至任意環境,步驟如下

⛏️ CI

  • 動態拉程式碼,從Jenkins Job中傳倉庫名做引數
  • 跑單元測試,Jacoco外掛生成報告
  • 通過Sonarqube做靜態程式碼掃描
  • 打包
  • 構建成Docker映象
  • Push到映象倉庫(Harbor)
  • 留存構建記錄