微服務改造過程中那些必須重視的問題

“微服務”近幾年尤其火熱,各大廠都在進行微服務化改造和微服務建設,想享受微服務化帶來的好處以便對自己的系統進行改造。分散式實驗室特約記者李鵬採訪了廣州輕閱科技系統架構師陳珙,就微服務與SOA的區別與聯絡、企業引入微服務會帶來的問題以及解決方案和陳珙自己的工作經驗進行了交流。

李鵬:談到微服務都不可避免的會提到SOA,請問微服務與SOA有區別與聯絡?分別適用於什麼場景?

陳珙:果然一談到微服務,SOA也絕對不會避而不談。首先,對於這個問題我也曾經思考與總結過的,我的看法跟大多數人百度、Google到的那種看法並不一樣,下面我將從兩者的發展史、兩者的出發點與核心思想進行闡述。

SOA與微服務的關係,我從多個方面的資料梳理後,總結出有這樣兩種看法:

微服務是SOA的最佳實踐 (出自維基百科)—— 微服務是SOA的演進版,粒度更細,基礎設施去中心化。

微服務拒絕SOA的標籤 (出 Martin Fowler 的《Microservices》原文)——微服務與SOA,是兩個完全不同的架構風格,只不過剛好長得像。

首先是發展史,這裡我整理了微服務發展的小歷史。

時間

事件

2005年

Peter教授在Web Servces Edge大會提出了“Micro-Web-Services”

2007年

JuvalLöwy在他的著作與演講建議用服務構建系統,並意識到細粒度因此擴充套件了WCF。

2011年

一個軟體架構工作組在威尼斯附近舉行的軟體架構師研討會上使用了”Microservice”來代表這種架構模式

2012年

Jame Lewis針對微服務概念在某大會發表了演講

2014年

Jame Lewis和Martin Fowler合寫了關於微服務的一篇學術性文章

從上文我們可以總結出三個核心關鍵點:

微服務的起源最早追溯到2005年;

微服務不是由 Martin Fowler 他本人創造的;

那篇舉世聞名2014年寫的《Microservices》原文是由 Jame Lewis 和 Martin Fowler 他們兩人共同合作編寫的。

雖然說微服務架構並非 Martin Fowler 所創造的,但是稱《Microservices》這篇文章是推動微服務的崛起的緣由,一點都不為過,而 Jame Lewis 和 Martin Fowler 兩位對微服務的盛行起到了非常關鍵的作用。

我相信不少同行討論微服務都會拿維基百科的定義作為標準(維基百科仍然寫著微服務是SOA的一種變種),不得不承認,微服務當時的出現就是作為一種輕量化的解決方案,用來解決SOA的一些詬病的,但是隨著微服務的這些年的發展與蛻變,漸漸的脫離了SOA的標籤,成為了一種獨立的架構風格。

因此在2014年 Jame Lewis 和 Martin Fowler 合作編寫的《Microservices》其中一段寫著微服務倡導者拒絕SOA的標籤。因此我認為維基百科的定義已經過時了。

微服務改造過程中那些必須重視的問題

接著說兩者的出發點與核心思想,我認為,要看清楚它們關係的本質,就得從兩者各自的處理場景目的出發。

首先從微服務角度出發,因為單體應用的大而全的高耦合與臃腫,隨著業務的發展迭代的時間越久,就會有各種各樣的問題,因此透過把應用拆成了多個“小”的服務,這裡使用到了化繁為簡、分而治之的核心思想,解決原有單體的“痛點”和“難點”。

接著從SOA的角度出發,在當時那個年代,希望把各種異構的系統給整合起來,這些異構的系統,有可能是從其他地方買的,也有可能是研發的,也有可能是找外包做的,因緣由存在各種不確定性,所以希望透過一個“聰明的”ESB解決所有的“愚蠢的”問題,也是因此ESB的高複雜度,導致當年SOA那會只是炒得火熱,卻無法普遍落實。

微服務改造過程中那些必須重視的問題

總地來說,微服務以拆與約定作為出發點,而SOA是以整合與配置作為出發點,所以我個人認為從它們的出發點與目的的角度出發,直接決定了它們在本質上是完全不同的架構。 所以我更加傾向於《Microservices》原文提到的看法,微服務的倡導者拒絕SOA這個標籤的。

以上就是我對SOA與微服務的關係的一些見解。

李鵬:團隊引入微服務技術會不會帶來新問題?比如會帶來什麼新問題?應該怎麼解決?

陳珙:引入微服務的話,從我的經驗來看還是會帶來不少的問題,我自己還是總結了一番,用一句話概括:兩文化與一思維。

自動化文化、可觀測性文化和分散式系統思維。

首先是自動化文化,有些人覺得疑惑,自動化這種能給團隊省時省力、減少重複工作量、增加幸福度的技術難道還有人或者團隊會抗拒的?是的,還真的有。

我曾經就接觸過幾個團隊的Leader,他們的團隊都是推行自動化失敗了。 失敗的原因就在於成員不配合,成員拒絕配合的理由是:這麼多框框條條很麻煩麻煩、沒有自己親手去做總覺得機器不靠譜。

作為已經使用過自動化的其他同行來看,這樣的思想完全覺得不可思議,但是我卻可以理解,大家回憶下自己是否曾經對沒使用過的框架與技術引入到生產同樣會產生“恐懼”、“擔心”,是的,從某角度來看這是“謹慎”,但是過於謹慎了。

重新回到話題,從上面可知,統一團隊的目標一致性是有必要的,從另外的角度來看,自動化還需要團隊、專案的流程的標準化、統一與約定,任何的技術都無法脫離了業務與團隊而去討論應該如何去實施。

作為技術領導者推行優良的方案,是我們的職責之一。如果團隊成員無法配合,導致推行受阻,我們一共有三種應對策略:激勵、考核和逐步試行。如果有條件的公司可以設定獎金激勵,如果有績效考核的,可以將自動化的實施納入考核目標,如果這倆都沒有,那就選取團隊裡願意改變的同事牽頭試行,假如使用過後都說好,那麼會更有說服力。

其次是可觀測性文化,如果說自動化是給團隊帶來穩定性,減輕工作量的,那麼可觀測性就是提高團隊對系統運作的資訊量。 建立可觀測性的這項工作,雖然無法直接給系統帶來健壯性,但能夠使我們透過這些資訊充分地瞭解到系統正在運作的情況,以至於最大程度地做出最合適的定位、判斷與決策。

在單體應用的場景下,我們也是需要可觀測性的,但是單體的架構相對簡單,專案除錯也更加便捷,無論是從複雜度還是規模的角度來看,單體跟微服務相比都要低不少,也因此單體對可觀測性的需要,相比於微服務顯得沒那麼重要。

而我們只要進行了微服務實施後,因為應用被拆分成了細粒度,從而導致了架構從量變引起質變,這個時候可觀測性的作用在微服務場景下被“無限放大”,也因此我們利用“可觀測性”,給與我們提供應用與伺服器的監控、快速跟蹤與問題定位的功能。

可觀測性的三個要素日誌、跟蹤、指標。 我們在工作中只有靈活結合這三者,才能提高我們對系統執行情況的資訊量,資訊量越高思考的越是更加全面,才能儘可能地減少“不知道問題出在哪”的狀況,所以當我們不清楚具體發生問題的原因時,建議你側重做一件事:就是儘可能想辦法,提高我們對問題與系統的資訊量。

在這裡額外提醒一句,自動化與可觀測性並不是必須跟微服務架構繫結,無論在哪裡的業務,怎樣的系統,在條件允許的情況,越早把這兩者完善,那麼長期收益則越高。

最後就是分散式系統的問題,這個問題又分為三個,冪等性、資料的一致性的讀與寫。

冪等性, 其定義是 相同的引數在同一個方法裡,無論執行一次還是多次都會響應相同的結果。

對於查詢和刪除的場景都有天然的冪等性,那麼我們考慮冪等性的處理,更多是關注於新增資料與更新資料。

新增資料缺乏冪等性,則會因為網路抖動導致請求重試或者是客戶端重複點選,而引發的資料寫入重複,其解決方案也相對簡單,只要從客戶端生成主鍵傳給後端API就可以解決,在這裡得注意一點,只有請求成功或者主動重新整理才會重新生成主鍵。

更新資料缺乏冪等性,主要會造成兩種情況,數值錯誤自增和ABA問題。首先,數值錯誤自增,可以結合事務憑據與新增冪等性的方式解決。

而ABA問題,解決方案相對簡單,可以在更新操作時帶上版本號判斷進行解決。

ABA問題: 對某條記錄先更新了A資料,緊接著又更新了B資料,理應是B是最新的,但是因為其他客觀原因使介面Retry或者別的問題,導致A資料再次請求覆蓋了B。

冪等性處理方案

場景

問題

方案

新建資料

重複建立

由呼叫端預生成訂單號,唯一鍵約束

更新資料

ABA覆蓋問題

新增版本號判斷

金額自增

使用流水憑據

資料一致性讀,其實說白了就是做資料關聯,從我過往用的解決方案來看共有三種,應用層的介面聚合資料、把更新頻率低的欄位冗餘儲存、把資料庫同步到一臺伺服器進行SQL聯表處理,每種方式各有優缺點,我結合切身體會和過往經驗,以表格方式整理呈現出來,你可以根據業務場景自行選擇解決方案。

資料關聯方案

方案名稱

方案描述

優點

缺點

應用層資料聚合

分別呼叫查詢API,在業務邏輯層組裝,適用於簡單的關聯。

實現簡單

該方案只能適合簡單的查詢過濾,以主表為驅動的關聯

冗餘設計(反正規化)

在目標表新增冗餘欄位,適用於記錄遞增的,不適用於冗餘欄位更新頻繁,實現起來簡單,有擴充套件性問題

實現簡單,以應用層資料聚合方案有更多的過濾條件

冗餘的欄位如果更新存在同步問題,該方案適用於更新頻繁少的遞增日誌類資料

資料庫從庫整合

透過主從同步把相關表同步到一臺伺服器做跨庫查詢,適用於複雜查詢、報表類的,有技術複雜度,從長遠收益來看能應對多種場景

透過強大的SQL解決複雜的報表類查詢

擁有技術複雜度,需要資料庫主從處理

寫的資料一致性,其實就是分散式事務,主流的方案有 TCC 、 本地訊息表(基於訊息可靠的最終一致性) 、 非同步請求/回撥。

其他的多數是基於以上幾種方法的變種,例如RocketMQ的訊息事務,就是TCC+本地訊息表的變種。

分散式事務方案,用文字描述起來相對比較吃力,因此我透過流程圖代替文字描述展示給大家。下方表格是我對這三種方案的優缺點與使用場景的總結。

分散式事務方案

名稱

場景

優點

缺點

非同步請求/回撥

跨網路環境、同網路環境

實現簡單

強業務

TCC

跨網路環境、同網路環境

有現成的框架、實現簡單

強業務

基於訊息可靠的最終一致性

同網路環境

有現成的框架、通用性強

中介軟體依賴

以上就是我所經歷微服務的引入後所需要解決的一些問題與方案。

李鵬:工作這麼長時間,你在微服務改造過程中有沒有遇到特別大的困難,都是怎麼解決的?

陳珙:這個問題勾起了我的痛並快樂著的回憶。俗話說得好,萬事開頭難,因此第一次做微服務的實施經歷給我帶來了非常深刻的印象。

第一次做微服務是2019年,受老領導的邀約加入了新公司並以微服務架構風格來從零開始搭建新系統。這也是我工作多年以來,第一次以技術負責人的身份,從零開始組建自己的團隊,同時從零開始開發系統,而且還是得用當時對我來說“陌生的”微服務架構。

我面臨的第一個難題就是我的運維能力。 如大家所瞭解的運維就是微服務架構的地基,如果運維能力有限那麼微服務搭建的規模與完整度自然也會受到影響。在當時來說,我以往工作經驗,接觸運維還是比較少的,因此在實施微服務的同時不得不進行惡補運維的知識,像容器化、Linux基礎、網路知識、自動化等等。

因此,當時我買書與課程應該屬於我這麼多年以來的最瘋狂的一次,每天早上在地鐵上學習,下班後回家也會帶著問題找資料,現在回想起來也非常的充實。

第二個難題就是。Net的技術生態。 。Net並沒有一套像Java一樣比較成熟的、預設的方案,因此在。Net微服務的技術選型上花了不少的時間與精力,主要的問題體現在到各種框架與中介軟體之間的整合,很多時候還要自己看原始碼改擴充套件。

從現在看過往,真正允許我們。Net選擇的框架與中介軟體並不是很多,因為很多中介軟體是不提供。Net SDK的。而且在當時來說,在技術社群裡也沒多少人會分享自己。Net微服務實戰的心得,因此對於我們不得不摸著石頭過河,無論覺得行還是不行都得嘗試一遍,最終總結出適合自己的技術選型。

事後,我也希望後來人避免踩坑,在部落格園寫了個《。Net微服務實戰》系列,在給自己做總結的同時也分享給有需要的同行。

第三個難題則是微服務的劃分。 大家可能都知微服務拆分的其中一種方式是按照業務邊界,DDD的戰略思想與事件風暴被我引入到了工作當中,不得不說DDD戰略的化繁為簡與微服務的分而治之這兩種思想是非常契合的。

但並不是說這種方式在任何時候都完全適用,因為我們整個團隊都是新組建的,業務對我們來說都是全新的,因此不存在領域專家這一個說法。在整個工作當中會存在很多不明確的業務,一般這個時候我們是不做任何服務的拆分處理的,只有隨著我們對業務的熟悉度越來越瞭解,才慢慢地再去重新識別業務邊界從而進行拆分。

雖然說微服務減輕了開發人員的開發負擔,但是對於架構師來說是一件非常考驗綜合能力的事情。

李鵬:請給新手提一些建議,微服務改造應該怎麼上手?改造過程中需要注意什麼?

陳珙:在上個問題,我拿了自己當時作為新手時實施的經歷,大家也可以參考下。那麼接下來我會總結一下,從多個方面出發進行分享。

從硬技能角度出發。 大多數微服務設計者是從開發過來的,因此開發技能無需過多擔憂,但是運維技能肯定對於他們來說是偏弱的,還是那句話運維是架構的地基,所以運維的基礎能力得優先提高。

這裡得注意一下,並不是說需要大家的運維技能一下子成為專家級的,這樣也不現實,但是起碼得夠用,能和專業運維崗無縫溝通,因為作為團隊的技術領導者,很多時候得領先團隊做技術調研、技術選型與評估,而擁有這些基本的能力,能讓自己更加順利的銜接好團隊並完成工作。

從軟能力角度出發。 如我上面所說的,微服務非常考驗架構師的綜合能力,那麼溝通與管理也包含在內。微服務的實施是需要整個團隊配合的,每個人都有自己擅長的專業與領域,因此團隊之間的能力是互補的。

從康威定律可以瞭解到,團隊裡成員之間的比例與技能是跟系統架構相匹配的,那麼架構師作為團隊的銜接點、承上啟下的角色,更加應該有良好的溝通協助方式與大局意識。

想要一個人承擔所有的角色搭建整套微服務架構,我認為是不現實的,特別是對有一定規模的老系統進行改造,裡面會有數不盡的“坑”,脫離了業務進行架構設計無疑是“耍流氓”,技術服務於架構,架構服務於業務,業務服務於商業,這是一條不變的真理。 軟體工程是一項多人協作的工作,每個崗位都有他存在的價值與意義,這裡沒有個人“英雄主義”。

從實施的流程出發。 微服務裡用了不少中介軟體,例如:API閘道器、服務註冊中心、負載均衡器等等,在不是特別必要的情況下,可以稍微延後這些中介軟體的搭建,我們可以先把重心放到可觀測性與自動化的搭建上。

自動化與可觀測性在微服務架構中有著無法代替的重要性。 因為在微服務架構中由於服務的拆分慢慢的從量變引起了質變,原本在單體架構中顯得不重要的流程與問題會逐漸的被放大。當然了,自動化與可觀測性並不是說得準備要微服務才應該著手準備,無論在哪種系統來說,能越儘早完善自動化與可觀測性,那麼收益就會越大,只有系統穩定了,不會每天被那些繁瑣的維護工作佔用過多的時間,我們才可以有時間與機會做更加有意義的事情。

從新舊系統改造出發。 新的系統使用微服務的難點主要在於第一次搭建微服務的“陌生感”,當你形成一套可複用模式後,後續第二次、第三次就如同“堆積木”。

舊系統的改造一般來說會比新系統的複雜點,主要的原因是舊系統是有穩定業務的,因此我們在對舊系統的服務拆分時更多的考慮的是,哪些業務模組相對耦合性低,可以優先獨立出來,拿舊系統試錯還是有一定的風險與成本,因此我們儘可能減少影響面,適當的還要考慮功能的相容性與釋出的可逆性。

原文連結:https://mp。weixin。qq。com/s?__biz=Mzg5Mjc3MjIyMA==&mid=2247553425&idx=1&sn=139504f458e247276d8e8f23e720f4e9&utm_source=tuicool&utm_medium=referral