自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

微服務(wù)架構(gòu)的兩大解耦利器與最佳實踐

原創(chuàng)
開發(fā) 架構(gòu) 開發(fā)工具
​這幾年,微服務(wù)架構(gòu)這個術(shù)語漸成熱門詞匯,但它不是一個全新架構(gòu),更不是一個包治百病的架構(gòu)。那么,微服務(wù)架構(gòu)究竟能夠解決什么問題,又帶來哪些痛點?本文將與大家談?wù)勥@個問題,以及微服務(wù)架構(gòu)的兩大解耦利器配置中心和消息總線的最佳實踐。

【51CTO.com原創(chuàng)稿件】​這幾年,微服務(wù)架構(gòu)這個術(shù)語漸成熱門詞匯,但它不是一個全新架構(gòu),更不是一個包治百病的架構(gòu)。那么,微服務(wù)架構(gòu)究竟能夠解決什么問題,又帶來哪些痛點?

本文將與大家談?wù)勥@個問題,以及微服務(wù)架構(gòu)的兩大解耦利器配置中心和消息總線的最佳實踐。

微服務(wù)架構(gòu)解決的問題與帶來的痛點 

 

互聯(lián)網(wǎng)高可用架構(gòu)為什么要服務(wù)化?

 

 

上圖是互聯(lián)網(wǎng)典型的高可用架構(gòu),大部分公司如果沒有使用微服務(wù),正在使用這樣的架構(gòu):

  • 用戶端是瀏覽器 browser,APP 客戶端

  • 后端入口是高可用的 nginx 集群,用于做反向代理

  • 中間核心是高可用的 web-server 集群,研發(fā)工程師主要在這一層進行編碼工作

  • 后端存儲是高可用的 db 集群,數(shù)據(jù)存儲在這一層。更典型的公司,web-server 層是通過 DAO/ORM 等技術(shù)來訪問數(shù)據(jù)庫。

最初的架構(gòu)都沒有服務(wù)層,這樣的架構(gòu)會遇到怎樣的痛點?對于沒有使用微服務(wù)架構(gòu)的公司來說,要不要升級到微服務(wù)架構(gòu)呢?

58 同城和 58 到家的架構(gòu)痛點

回答這個問題之前,先來看看您是否遇到和 58 同城及 58 到家類似的架構(gòu)痛點:

圖一,代碼拷貝。A、B、C 業(yè)務(wù)線,如果沒有微服務(wù)架構(gòu),可能要直接訪問數(shù)據(jù)庫里的數(shù)據(jù)來實現(xiàn)自己的業(yè)務(wù)需求。拿訪問用戶數(shù)據(jù)舉例,用戶中心包括所有公司必備的業(yè)務(wù),比如登陸、注冊、查找用戶信息等。如某業(yè)務(wù)線需要訪問用戶信息,需要通過封裝用戶訪問代碼模塊實現(xiàn)。如業(yè)務(wù)繁多,每個業(yè)務(wù)線都需要訪問用戶信息,潛在的會存在代碼拷貝問題。

圖二,底層復(fù)雜性擴散。隨著流量的增長,需要加入緩存,對數(shù)據(jù)的訪問模式和流程都會帶來影響。從直接訪問數(shù)據(jù)庫,變到先訪問緩存再訪問數(shù)據(jù)庫。這樣的復(fù)雜性,所有的業(yè)務(wù)都需關(guān)注,代碼都要重新做一遍。包括數(shù)據(jù)量增大后,要進行的水平線切分、分庫、分表,存儲引擎的變化等復(fù)雜性,要擴展到業(yè)務(wù)線。

圖三,代碼庫耦合。58 同城遇到圖一和圖二問題,最初想到的方案并不是微服務(wù),而是將相互拷貝的復(fù)雜性代碼封裝到一個代碼庫(DLL 或 jar 包),實現(xiàn)統(tǒng)一的相關(guān)功能,屏蔽復(fù)雜性。

拷貝代碼的好處是代碼獨立演化,做改動互不影響。弊端是一旦用上庫,業(yè)務(wù)就會耦合在一起,因共用jar包,一旦其中某個業(yè)務(wù)升級,其他的業(yè)務(wù)就可能受影響。

圖四,數(shù)據(jù)庫耦合。業(yè)務(wù)線不只訪問 user 數(shù)據(jù),還會結(jié)合自己的業(yè)務(wù)訪問自己的數(shù)據(jù):典型的情況是通過 join 數(shù)據(jù)表來實現(xiàn)各自業(yè)務(wù)線的一些業(yè)務(wù)邏輯。這樣的話:

  • 業(yè)務(wù)線 A 的 table-user 與 table-A 耦合在了一起;

  • 業(yè)務(wù)線 B 的 table-user 與 table-B 耦合在了一起;

  • 業(yè)務(wù)線 C 的 table-user 與 table-C 耦合在了一起;

結(jié)果就是:table-user,table-A,table-B,table-C都耦合在了一起。隨著數(shù)據(jù)量的越來越大,業(yè)務(wù)線 ABC 數(shù)據(jù)庫無法進行垂直拆分,必須使用一個大庫(瘋了,一個大庫 300 多個業(yè)務(wù)表 =_=)。

圖五,SQL 質(zhì)量得不到保證,業(yè)務(wù)之間互相影響。由業(yè)務(wù)方拼裝的 SQL 語句調(diào)用方式,通過 ORM(對象關(guān)系映射)的方法生成 SQL 語句數(shù)據(jù)庫,這個庫是共用的,會影響所有的業(yè)務(wù)線。一旦某業(yè)務(wù)有慢 SQL 出現(xiàn),其他業(yè)務(wù)就會受影響。

回到要不要做微服務(wù)升級的問題,如果大家所負責(zé)的系統(tǒng)、模塊或公司也存在以上的這些問題,建議考慮做服務(wù)化,在中間加一個服務(wù)層,所有調(diào)用不允許直接連接底層庫。服務(wù)化還有一個很重要的特點就是數(shù)據(jù)庫私有化,任何人不能跨越服務(wù)程序,干預(yù)數(shù)據(jù)庫。想調(diào)用要通過接口來實現(xiàn),當(dāng)數(shù)據(jù)庫性能變差,直接加一臺機器,把數(shù)據(jù)庫遷移,對調(diào)用方不會產(chǎn)生影響。 

 

服務(wù)化解決了哪些問題

在 58 同城,用戶中心由專門的部門負責(zé),是全公司、全業(yè)務(wù)依賴比較重的服務(wù),它對代碼要求和穩(wěn)定性要求比較高。整個 SQL 語句是服務(wù)層控制,向上提供有限的服務(wù)接口和無限的性能

工程師要保障雖然提供用戶基礎(chǔ)數(shù)據(jù)的接口數(shù)是有限的,但調(diào)用方不需要關(guān)心底層細節(jié),可以認為性能是無限的。至于如何擴容,就是服務(wù)層的事情了。

下圖是互聯(lián)網(wǎng)典型的服務(wù)化架構(gòu)。以用戶中心為例,用戶中心服務(wù)向上屏蔽底層技術(shù)的復(fù)雜性,上層通過 RPC 接口來調(diào)用服務(wù),如同調(diào)用本地函數(shù)一樣,不需要關(guān)注分庫、分表、緩存。 

業(yè)務(wù)方需要數(shù)據(jù),把數(shù)據(jù)拼裝出來返回 APP/PC 端即可,可以不關(guān)心數(shù)據(jù)存在哪里,底層的復(fù)雜性也由用戶層來承擔(dān)。這樣一來,用戶庫只有用戶服務(wù)依賴,任何人不得跨越用戶服務(wù)來直接調(diào)用數(shù)據(jù)庫,就不會存在代碼拷貝、代碼庫、數(shù)據(jù)庫耦合的情況。

微服務(wù)架構(gòu)的兩大解耦利器

微服務(wù)雖然看上去很好,但也給系統(tǒng)帶來很多問題,如部署方面,越來越復(fù)雜,分層越來越多,處理時間也隨之增加。如網(wǎng)絡(luò)交互方面,運維負載性、追查問題等等。那么:

  • 面對架構(gòu)的耦合及復(fù)雜性如何來優(yōu)化

  • 結(jié)構(gòu)如何配置

接下來,我們介紹配置中心最佳實踐與消息總線最佳實踐這兩大解耦利器。 

 

微服務(wù)架構(gòu)解耦利器-配置中心最佳實踐

 

放棄 IP 連接服務(wù),選擇內(nèi)網(wǎng)域名。58 到家是創(chuàng)業(yè)公司,痛點和很多公司都很相似。其中一個場景是 IP 的變化。最初,IP 寫在配置文件中,通過某個 IP 或端口訪問數(shù)據(jù)與服務(wù)。當(dāng)某臺機器出現(xiàn)問題,DB 同事會在新機器做部署,更換 IP。當(dāng)某個服務(wù)或 IP 發(fā)生變化,就在配置文件中修改,重啟。

這里的經(jīng)驗分享是千萬不要用 IP 連接服務(wù)或數(shù)據(jù)庫,要選擇內(nèi)網(wǎng)域名。這兩者的區(qū)別在于:

  • 使用 IP 連接服務(wù)或數(shù)據(jù)庫的方式,所有的庫都和一個表有關(guān)聯(lián),一旦機器掛掉或升高配,幾乎所有的業(yè)務(wù)都需要修改 IP。即便只是升級一個業(yè)務(wù),都會嚴重影響其他業(yè)務(wù)。

  • 選擇內(nèi)網(wǎng)域名的方式后,如果換 IP,在運維層面可以進行統(tǒng)一切斷,自動向上鏈接,上游的業(yè)務(wù)就不用動,也不受下層變動的影響。

配置私藏。如下圖是 58 到家早期改成內(nèi)網(wǎng)域名之后的配置文件。底層用戶服務(wù)或數(shù)據(jù)庫,是個高可用集群,從 IP1 到 IP3。上游有三個依賴,兩個服務(wù)器,一個 Web 調(diào)用這個高可用集群。Web 包含 WBE2.conf,調(diào)用 IP1,IP2,IP3。

在實踐過程中,這種配置私藏的方式遇到兩個痛點: 

  1. 升級時不知道被那個服務(wù)調(diào)用。當(dāng)遇到流量越來越大,需要添加服務(wù)器時,如上圖,把 IP1 去掉,增加 IP4 和 IP5 的時候,需要通知上游。但問題在于流量不大時,因為對業(yè)務(wù)非常熟悉,工程師能夠準確的找到服務(wù)器對應(yīng)的負責(zé)人。隨著業(yè)務(wù)越來越復(fù)雜,工程師遇到出現(xiàn)了問題,不知道模塊被誰依賴的情況。

  2. 升級時需要上游配合重啟。當(dāng)增加 IP 時,需要找到對應(yīng)的上游服務(wù)器負責(zé)人,通知他進行服務(wù)器重啟。公司成百上千的服務(wù)每天都有人在升級,當(dāng)時的做法是采用建群,隨時做通知,但這樣很影響研發(fā)同事寫代碼的效率。

全局配置。最開始底層的通用基礎(chǔ)服務(wù),配置是寫在每個站點;而且每個應(yīng)用私藏在配置文件里,在升級過程中,不知道誰私藏了這個配置。

面對這兩個痛點,58到家采用了下圖的解決方案:全局配置

 

全局配置也就是升級,只需要做流程與規(guī)范上的優(yōu)化,對原有系統(tǒng)架構(gòu)不產(chǎn)生任何影響,成本低且可平滑的慢慢遷移。 

下圖的實現(xiàn)原理是把最初放在每個服務(wù)器中的配置文件,抽取一個全局配置文件,做好目錄結(jié)構(gòu) global.conf。所有基礎(chǔ)服務(wù)配置如果由多個 global.conf 上游來讀取,必須通過 global.conf 來讀取。這樣所有的業(yè)務(wù)都在 global.conf,就可以保障下一次升級可連接到最新。

那么,在做擴容的時候,能不能實現(xiàn)調(diào)用方不需要升級呢?當(dāng)然可以,兩個小組件就可以實現(xiàn):

  • 監(jiān)控全局文件的變化情況,發(fā)生變化就進行回調(diào),這樣用戶中心要配置修改的是全局配置。

  • 動態(tài)鏈接池組件。這是一個自身及調(diào)整流程成本都很低的組件,負載均衡也會在其中實現(xiàn)。

配置中心。全局配置對于服務(wù)提供方而言,問題依然沒有全部解決,擴容不需要重啟,卻仍不知道被誰依賴,不知道被誰訪問,就沒辦法做服務(wù)治理、限流等操作。這時,工程師就要引入配置中心,來解決這個問題。

配置中心思路是部署用戶中心承載所有配置,取代所有全局配置文件。這樣一來,所有都依賴配置中心上游,服務(wù)1,服務(wù)2,服務(wù)3,都不再訪問global.conf,而是通過配置中心來拉取相關(guān)配置,配置變更,配置中心反向回調(diào),調(diào)用方也不要重啟。 

配置中心最佳實踐總結(jié)。配置中心是微服務(wù)架構(gòu)中一個邏輯解耦但物理不解耦的利器。它原來在邏輯上依賴于自己的配置文件,依賴于下游,現(xiàn)在不再向配置文件索要配置,而是所有調(diào)用方邏輯上只依賴于配置中心。物理上不解耦,是從配置文件拿到配置以后該連誰還是連誰。 

 

微服務(wù)架構(gòu)解耦利器-消息總線最佳實踐

 

消息總線(Message Queue),后文稱 MQ,是一種跨進程的通信機制,用于上下游傳遞消息。它也是微服務(wù)架構(gòu)中很常見的解耦利器之一,在數(shù)據(jù)驅(qū)動的任務(wù)依賴、調(diào)用方不關(guān)注處理結(jié)果、關(guān)注結(jié)果的長時間調(diào)回等場景下使用。

數(shù)據(jù)驅(qū)動的任務(wù)依賴。大部分公司都有 BI、數(shù)據(jù)部門,每天都會跑一些日志、數(shù)據(jù)庫,多個任務(wù)之間往往存在依賴關(guān)系,任務(wù)1先執(zhí)行,依次是任務(wù) 2、任務(wù) 3 輸入,最終得到結(jié)果。在沒有消息總線之前,大多公司和58到家的做法雷同,就是人工排班表。 

人工排班表的弊端如下

  1. 原本執(zhí)行時間是40分鐘,但為保險,每個人都會多加時間,導(dǎo)致任務(wù)總執(zhí)行時間延長。

  2. 萬一某一任務(wù)的執(zhí)行時間超過預(yù)留時間,接下來的任務(wù)不知情,會導(dǎo)致整個業(yè)務(wù)失敗。

  3. 多個業(yè)務(wù)之間可能有多重依賴,特別是在數(shù)據(jù)統(tǒng)計、數(shù)據(jù)分析過程中,一些核心腳本執(zhí)行完,后面一系列腳本才能執(zhí)行。

如下圖,這種數(shù)據(jù)驅(qū)動的任務(wù)依賴非常適合使用MQ解耦。

  • task1準時開始,結(jié)束后發(fā)一個“task1 done”的消息

  • task2訂閱“task1 done”的消息,收到消息后第一時間啟動執(zhí)行,結(jié)束后發(fā)一個“task2 done”的消息

  • task3同理

采用 MQ 的優(yōu)點是:

  • 不需要預(yù)留 buffer,上游任務(wù)執(zhí)行完,下游任務(wù)總會在第一時間被執(zhí)行

  • 依賴多個任務(wù),被多個任務(wù)依賴都很好處理,只需要訂閱相關(guān)消息即可

  • 有任務(wù)執(zhí)行時間變化,下游任務(wù)都不需要調(diào)整執(zhí)行時間

需要特別說明的是,MQ 只用來傳遞上游任務(wù)執(zhí)行完成的消息,并不用于傳遞真正的輸入輸出數(shù)據(jù)。

調(diào)用方不關(guān)注處理結(jié)果,這樣的情況也適合消息總線來做解耦。舉例,58 同城的很多下游需要關(guān)注“用戶發(fā)布帖子”這個事件,比如招聘用戶發(fā)布帖子后,招聘業(yè)務(wù)要獎勵 58 豆;房產(chǎn)用戶發(fā)布帖子后,房產(chǎn)業(yè)務(wù)要送 2 個置頂;二手用戶發(fā)布帖子后,二手業(yè)務(wù)要修改用戶統(tǒng)計數(shù)據(jù)。

對于這類需求,常見的實現(xiàn)方式是使用調(diào)用關(guān)系:帖子發(fā)布服務(wù)執(zhí)行完成之后,調(diào)用下游招聘業(yè)務(wù)、房產(chǎn)業(yè)務(wù)、二手業(yè)務(wù),來完成消息的通知,但事實上,這個通知是否正常、正確的執(zhí)行,帖子發(fā)布服務(wù)根本不關(guān)注。

這種方法的痛點是:

  • 帖子發(fā)布流程的執(zhí)行時間增加了

  • 下游服務(wù)宕機,可能導(dǎo)致帖子發(fā)布服務(wù)受影響,上下游邏輯+物理依賴嚴重

  • 每當(dāng)增加一個需要知道“帖子發(fā)布成功”信息的下游,修改代碼的是帖子發(fā)布服務(wù),這一點是最惡心的,屬于架構(gòu)設(shè)計中典型的依賴倒轉(zhuǎn),誰用過誰痛誰知道(采用此法的請評論留言)

采用下圖的優(yōu)化方案:MQ解耦

  • 帖子發(fā)布成功后,向MQ發(fā)一個消息

  • 哪個下游關(guān)注“帖子發(fā)布成功”的消息,主動去MQ訂閱

采用 MQ 的優(yōu)點是:

  • 上游執(zhí)行時間短

  • 上下游邏輯+物理解耦,除了與 MQ 有物理連接,模塊之間都不相互依賴

  • 新增一個下游消息關(guān)注方,上游不需要修改任何代碼

上游關(guān)注執(zhí)行結(jié)果,但執(zhí)行時間很長。有時候上游需要關(guān)注執(zhí)行結(jié)果,但執(zhí)行結(jié)果時間很長(典型的是調(diào)用離線處理,或者跨公網(wǎng)調(diào)用),也經(jīng)常使用回調(diào)網(wǎng)關(guān)+MQ來解耦。 

舉例:微信支付,跨公網(wǎng)調(diào)用微信的接口,執(zhí)行時間會比較長,但調(diào)用方又非常關(guān)注執(zhí)行結(jié)果,此時一般怎么玩呢?

一般采用“回調(diào)網(wǎng)關(guān)+MQ”方案來解耦,新增任何對微信支付的調(diào)用,都不需要修改代碼。

  • 調(diào)用方直接跨公網(wǎng)調(diào)用微信接口

  • 微信返回調(diào)用成功,此時并不代表返回成功

  • 微信執(zhí)行完成后,回調(diào)統(tǒng)一網(wǎng)關(guān)

  • 網(wǎng)關(guān)將返回結(jié)果通知 MQ

  • 請求方收到結(jié)果通知

這里需要注意的是,不應(yīng)該由回調(diào)網(wǎng)關(guān)來調(diào)用上游來通知結(jié)果,如果是這樣的話,每次新增調(diào)用方,回調(diào)網(wǎng)關(guān)都需要修改代碼,仍然會反向依賴,使用回調(diào)網(wǎng)關(guān)+ MQ 的方案。

綜上所述,兩個解耦利器的最佳實踐場景如下:

  • 配置中心是邏輯解耦,物理不解耦的微服務(wù)的利器。它可以解決配置導(dǎo)致的系統(tǒng)耦合,架構(gòu)反向依賴的問題,配置中心的演進過程,配置私藏到全局配置文件,到配置中心。

  • 消息總線是邏輯上解耦,物理上也解耦的微服務(wù)架構(gòu)利器。它非常適合數(shù)據(jù)驅(qū)動的任務(wù)依賴,調(diào)用方不關(guān)注處理結(jié)果,或者調(diào)用方關(guān)注處理結(jié)果,但是回調(diào)的時間很長的場景。不適合調(diào)用方強烈關(guān)注執(zhí)行結(jié)果的場景。

以上內(nèi)容由編輯王雪燕根據(jù)沈劍老師在 WOTA2017 “微服務(wù)架構(gòu)實踐”專場的演講內(nèi)容整理。  

 

 

 

沈劍,現(xiàn)任58到家技術(shù)委員會主席,高級技術(shù)總監(jiān),負責(zé)企業(yè)、支付、營銷和客戶關(guān)系等多個后端業(yè)務(wù)部門。本質(zhì),技術(shù)人一枚?;ヂ?lián)網(wǎng)架構(gòu)技術(shù)專家,“架構(gòu)師之路”公眾號作者。曾任百度高級工程師,58同城高級架構(gòu)師,58同城技術(shù)委員會主席,58同城C2C技術(shù)部負責(zé)人。

“架構(gòu)師之路”公眾號 

【51CTO原創(chuàng)稿件,合作站點轉(zhuǎn)載請注明原文作者和出處為51CTO.com】

責(zé)任編輯:王雪燕 來源: 51CTO
相關(guān)推薦

2024-05-16 13:13:39

微服務(wù)架構(gòu)自動化

2020-08-07 09:41:00

微服務(wù)架構(gòu)數(shù)據(jù)

2019-12-26 15:49:14

微服務(wù)架構(gòu)業(yè)務(wù)

2018-06-14 21:47:46

WOT沈劍58速運

2023-11-20 16:06:34

軟件開發(fā)微服務(wù)架構(gòu)Spring

2023-11-06 08:55:31

2018-12-17 16:44:49

Golang微服務(wù)

2018-12-17 16:39:20

Golang微服務(wù)

2018-12-17 16:48:05

Golang微服務(wù)

2023-10-24 08:00:00

單體架構(gòu)微服務(wù)

2021-09-08 10:32:29

微服務(wù)容器化Serverless

2018-04-20 10:38:25

2022-04-25 10:44:08

微服務(wù)架構(gòu)設(shè)計

2015-12-21 16:10:33

七牛

2019-11-15 14:42:00

微服務(wù)架構(gòu)數(shù)據(jù)

2015-09-15 16:01:40

混合IT私有云IT架構(gòu)

2024-01-10 21:35:29

vivo微服務(wù)架構(gòu)

2022-08-30 15:12:10

架構(gòu)實踐

2024-01-05 09:08:48

代碼服務(wù)管理

2018-10-24 23:14:23

普元微服務(wù)DevOps
點贊
收藏

51CTO技術(shù)棧公眾號