亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.430618.com 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線(xiàn)咨詢(xún)客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

 

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

作者:人月神話(huà),新浪博客同名

簡(jiǎn)介:多年SOA規(guī)劃建設(shè),私有云PaaS平臺(tái)架構(gòu)設(shè)計(jì)經(jīng)驗(yàn),長(zhǎng)期從事一線(xiàn)項(xiàng)目實(shí)踐

今天準(zhǔn)備談下微服務(wù)架構(gòu)下各個(gè)微服務(wù)間如何解耦,以及對(duì)于已經(jīng)緊耦合的微服務(wù)如何進(jìn)行重構(gòu)。在談這個(gè)內(nèi)容前,可以先看下我前兩天發(fā)布的微服務(wù)模塊和粒度如何劃分才更加合理的一篇文章,這篇文章對(duì)于微服務(wù)拆分有比較詳細(xì)的描述。

可以參考:中臺(tái)規(guī)劃中微服務(wù)粒度究竟應(yīng)該如何劃分?你可以從以下幾點(diǎn)考慮

要明白實(shí)際上微服務(wù)后續(xù)出現(xiàn)的諸多問(wèn)題往往都是一開(kāi)始微服務(wù)模塊劃分就不合理導(dǎo)致,對(duì)于具體的模塊劃分方法和原則,我在上面文章里面給出了以下幾點(diǎn)。

  • 原則1:劃分為<10個(gè)微服務(wù)模塊
  • 原則2:強(qiáng)數(shù)據(jù)關(guān)聯(lián)模塊不要拆分
  • 原則3:以數(shù)據(jù)聚合驅(qū)動(dòng)業(yè)務(wù)功能聚合
  • 原則4:從縱向功能劃分思路到橫向分層思路轉(zhuǎn)變
  • 原則5:高內(nèi)聚,松耦合的基礎(chǔ)原則

對(duì)于具體的內(nèi)容在這篇文章不再重復(fù)給出。可以看到對(duì)于微服務(wù)模塊拆分更多的是屬于業(yè)務(wù)建模和系統(tǒng)分析方面的內(nèi)容,而今天談的微服務(wù)解耦重點(diǎn)是想從可用的技術(shù)手段入手來(lái)談下可用的以下解耦方法和策略。

問(wèn)題綜述

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

最近幾年對(duì)于微服務(wù)架構(gòu),企業(yè)中臺(tái)構(gòu)建,組件化和服務(wù)化,平臺(tái)+應(yīng)用構(gòu)建模式,包括Docker容器化,DevOps等都越來(lái)越受到傳統(tǒng)企業(yè)的關(guān)注,也可以看到很多企業(yè)傳統(tǒng)架構(gòu)也在朝這個(gè)目標(biāo)進(jìn)行演進(jìn)和轉(zhuǎn)型。對(duì)于微服務(wù)架構(gòu)本身的優(yōu)點(diǎn)和缺點(diǎn),包括傳統(tǒng)企業(yè)實(shí)施微服務(wù)架構(gòu)的演進(jìn)路線(xiàn)等,在我前面很多微服務(wù)架構(gòu)相關(guān)的文章中都有所介紹,今天主要談下在微服務(wù)架構(gòu)下的解耦問(wèn)題。

要明白,企業(yè)實(shí)施微服務(wù)架構(gòu)后,原來(lái)所有內(nèi)部的接口調(diào)用,內(nèi)部的完整事務(wù)都會(huì)變成微服務(wù)模塊間的跨域的接口服務(wù)調(diào)用,傳統(tǒng)事務(wù)也變成了分布式事務(wù),這些本身是增加了系統(tǒng)復(fù)雜度。

原來(lái)一個(gè)系統(tǒng)就能夠完成的事情,現(xiàn)在要依賴(lài)底層技術(shù)組件服務(wù),其它業(yè)務(wù)微服務(wù)模塊多個(gè)Http Rest API接口調(diào)用往往才能夠完成。只要其中任何一個(gè)API接口出現(xiàn)問(wèn)題,都會(huì)直接影響到前端的業(yè)務(wù)功能使用。

微服務(wù)間的雪崩效應(yīng):在采用微服務(wù)架構(gòu)后,各個(gè)微服務(wù)間存在大量的API接口服務(wù)調(diào)用,相互之間還形成了服務(wù)調(diào)用鏈,比如A-》B-》C,那么如果C服務(wù)出現(xiàn)故障就將直接影響到B服務(wù)無(wú)法正常訪(fǎng)問(wèn)和服務(wù)阻塞,同時(shí)B的故障又將進(jìn)一步傳導(dǎo)到A服務(wù)的消費(fèi)和使用。

對(duì)于互聯(lián)網(wǎng)企業(yè)實(shí)施微服務(wù)架構(gòu),其中有幾個(gè)關(guān)鍵點(diǎn)。

  • 其一就是微服務(wù)架構(gòu)可以更好的進(jìn)行平臺(tái)的性能擴(kuò)展和高伸縮要求。
  • 其二就是互聯(lián)網(wǎng)應(yīng)用本身業(yè)務(wù)規(guī)則相對(duì)簡(jiǎn)單,模塊間容易解耦。
  • 其三就是大的互聯(lián)網(wǎng)企業(yè)IT技術(shù)積累更強(qiáng),有更好的技術(shù)能夠搭建高可用的技術(shù)平臺(tái),也有更好的技術(shù)能夠?qū)崿F(xiàn)微服務(wù)架構(gòu)實(shí)施后的自動(dòng)化運(yùn)維和監(jiān)控。

而這些往往都是傳統(tǒng)企業(yè)在實(shí)施微服務(wù)架構(gòu)所欠缺的,比如有些企業(yè)一開(kāi)始實(shí)施微服務(wù)架構(gòu)沒(méi)發(fā)現(xiàn)問(wèn)題,結(jié)果最終上線(xiàn)后卻發(fā)現(xiàn)后續(xù)的系統(tǒng)運(yùn)維和性能監(jiān)控,故障問(wèn)題分析和排查等能力跟不上,無(wú)法及時(shí)響應(yīng)客戶(hù)需求并快速的定位和解決問(wèn)題。

即前面經(jīng)常說(shuō)到的,傳統(tǒng)企業(yè)的IT治理和團(tuán)隊(duì)技術(shù)能力跟不上,直接影響到微服務(wù)架構(gòu)實(shí)施成敗。

那么回到正題,今天希望討論和分析下,企業(yè)實(shí)施微服務(wù)架構(gòu)后,如何盡量減少微服務(wù)模塊的耦合導(dǎo)致的單個(gè)微服務(wù)模塊功能實(shí)現(xiàn)和運(yùn)行故障,簡(jiǎn)單來(lái)說(shuō)就是一個(gè)微服務(wù)模塊中業(yè)務(wù)功能的運(yùn)行,如何做到最小化的依賴(lài)外部微服務(wù)模塊Http API服務(wù)接口的可用性。即使外部模塊掛點(diǎn),當(dāng)前模塊也能夠正常使用,或者說(shuō)能夠不影響到當(dāng)前模塊核心功能的使用。

對(duì)于該問(wèn)題,我們可以分開(kāi)從幾個(gè)方面進(jìn)行討論。

同步調(diào)用轉(zhuǎn)為異步調(diào)用

一說(shuō)到解耦,我們一定會(huì)首先想到消息中間件來(lái)實(shí)現(xiàn)異步,即將同步轉(zhuǎn)為異步,通過(guò)異步來(lái)實(shí)現(xiàn)解耦。我們可以先想消息發(fā)送給消息中間件,只要消息中間件是高可用性的沒(méi)有宕機(jī),整個(gè)接口集成過(guò)程就是OK的,而消息中間件再異步方式分發(fā)消息給目標(biāo)系統(tǒng),同時(shí)支持重試。

消息中間件的采用

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

消息中間件(message oriented middleware)是指支持與保障分布式應(yīng)用程序之間同步/異步收發(fā)消息的中間件。消息是分布式應(yīng)用之間進(jìn)行數(shù)據(jù)交換的基本信息單位,分布式應(yīng)用程序之間的通信接口由消息中間件提供。其中,異步方式指消息發(fā)送方在發(fā)送消息時(shí)不必知道接收方的狀態(tài),更無(wú)需等待接收方的回復(fù),而接收方在收到消息時(shí)也不必知道發(fā)送方的目前狀態(tài),更無(wú)需進(jìn)行同步的消息處理,它們之間的連接完全是松耦合的,通信是非阻塞的,這種異步通信方式是由消息中間件中的消息隊(duì)列及其服務(wù)機(jī)制保障的。

消息中間件實(shí)現(xiàn)了發(fā)布者和訂閱者在時(shí)間、空間和流程三個(gè)方面的解耦:

  • 時(shí)間解耦—-發(fā)布方和訂閱方無(wú)需同時(shí)在線(xiàn)就能夠進(jìn)行消息傳輸,消息中間件通過(guò)存儲(chǔ)轉(zhuǎn)發(fā)提供了這種異步傳輸?shù)哪芰Γ?/strong>
  • 空間解耦——發(fā)布方和訂閱方都無(wú)需知道對(duì)方的物理地址、端口,甚至無(wú)需知道對(duì)方的邏輯名字和個(gè)數(shù);
  • 流程解耦——發(fā)布方和訂閱方在發(fā)送和接收數(shù)據(jù)時(shí)并不阻塞各自的控制流程。

從消息中間件的基本功能來(lái)看,無(wú)論是點(diǎn)對(duì)點(diǎn)消息中間件還是消息代理,其體系結(jié)構(gòu)都是非常清晰簡(jiǎn)單的。但由于分布式應(yīng)用及其環(huán)境的多樣性和復(fù)雜性,導(dǎo)致了消息中間件的復(fù)雜性。

當(dāng)前的消息中間件仍然分為兩類(lèi),一類(lèi)是基于AMQP高級(jí)消息協(xié)議的,一類(lèi)是基于JMS消息協(xié)議的。對(duì)于互聯(lián)網(wǎng)使用較多的RabbitMQ,Kafka等基本都基于AMQP高級(jí)消息協(xié)議。而對(duì)于Weblogic JMS,IBM MQ則是基于JMS消息協(xié)議的消息中間件產(chǎn)品。

對(duì)于Weblogic而言是一個(gè)企業(yè)級(jí)的應(yīng)用服務(wù)器中間件,同時(shí)Weblogic JMS也是企業(yè)級(jí)的消息中間件產(chǎn)品,該產(chǎn)品是一個(gè)企業(yè)級(jí)消息中間件產(chǎn)品,具備了高可靠,高可用,高擴(kuò)展,高性能基礎(chǔ)特性。支持主流的各種消息模型,消息發(fā)布訂閱,消息持久化,事務(wù)處理,集群等核心特性。

消息中間件的使用場(chǎng)景,具體包括了如下幾個(gè)方面:

  • 1.消息通知:?jiǎn)螕?jù)狀態(tài)變化后的事件通知,數(shù)據(jù)傳輸完成后的事件通知
  • 2.異步集成:服務(wù)消費(fèi)方只需要將數(shù)據(jù)送到OSB即實(shí)時(shí)返回,通過(guò)異步集成實(shí)現(xiàn)徹底解耦
  • 3.目標(biāo)系統(tǒng)削峰:大并發(fā)數(shù)據(jù)導(dǎo)入而目標(biāo)系統(tǒng)處理性能受限的場(chǎng)景
  • 4.消息發(fā)布訂閱:基礎(chǔ)主數(shù)據(jù)通過(guò)JMS實(shí)現(xiàn)1對(duì)多的實(shí)時(shí)數(shù)據(jù)分發(fā)
  • 5.高可靠性場(chǎng)景:確保在數(shù)據(jù)集成中不出現(xiàn)任何丟失的情況

對(duì)于采用Weblogic JMS來(lái)實(shí)現(xiàn)消息集成,具體過(guò)程如下圖:

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

基于事件驅(qū)動(dòng)的業(yè)務(wù)分析

而要做到同步轉(zhuǎn)異步,我們必須從業(yè)務(wù)需求分析開(kāi)始就轉(zhuǎn)變思維,即從傳統(tǒng)的業(yè)務(wù)流程需求分析方法轉(zhuǎn)到事件驅(qū)動(dòng)分析方法,這個(gè)在我很早的EDA事件驅(qū)動(dòng)架構(gòu)內(nèi)容整理的時(shí)候?qū)iT(mén)談到過(guò),今天摘錄部分內(nèi)容供大家參考。

事件驅(qū)動(dòng)框架(EDA)里事件可傳輸于松散耦合的組件和服務(wù)之間。一個(gè)事件驅(qū)動(dòng)系統(tǒng)典型地由事件消費(fèi)者和事件產(chǎn)生者組成。事件消費(fèi)者向事件管理器訂閱事件,事件產(chǎn)生者向事件管理器發(fā)布事件。當(dāng)事件管理器從事件產(chǎn)生者那接收到一個(gè)事件時(shí),事件管理把這個(gè)事件轉(zhuǎn)送給相應(yīng)的事件消費(fèi)者。如果這個(gè)事件消費(fèi)者是不可用的,事件管理者將保留這個(gè)事件,一段間隔之后再次轉(zhuǎn)送該事件消費(fèi)者。

EDA架構(gòu)往往具備如下特征:

  • 廣播通信:參與通信的系統(tǒng)將事件廣播給任何對(duì)該事件感興趣的參與者。
  • 實(shí)時(shí)性:在業(yè)務(wù)事件發(fā)生時(shí)候,EDA架構(gòu)下可以實(shí)時(shí)的發(fā)送事件給消費(fèi)方,而無(wú)需等待
  • 異步:事件發(fā)布系統(tǒng)不用等待事件接收系統(tǒng)來(lái)處理事件,發(fā)送到EDA模塊即可返回。
  • 細(xì)粒度:只要具備獨(dú)立的業(yè)務(wù)價(jià)值,即可以發(fā)布為細(xì)粒度的事件,而不是傳統(tǒng)服務(wù)下的粗粒度。
  • 復(fù)雜事件處理:根據(jù)業(yè)務(wù)流程需求,事件間可以聚合和組裝,形成事件鏈滿(mǎn)足復(fù)雜事件處理。
  • 并行運(yùn)行:多個(gè)事件可以同時(shí)運(yùn)行,單個(gè)事件可以同時(shí)分發(fā)給多個(gè)訂閱方。
  • 非阻塞:EDA本身提供MQ等消息持久化機(jī)制,不會(huì)在事件大并發(fā)下出現(xiàn)事件阻塞情況。

簡(jiǎn)單來(lái)講,消息集成,異步,徹底解耦,消息發(fā)布訂閱,事件鏈?zhǔn)荅DA整個(gè)架構(gòu)的核心。但是在EDA包括CEP復(fù)雜事件處理,在使用的時(shí)候首先還是應(yīng)該了解清楚其和傳統(tǒng)流程驅(qū)動(dòng)在業(yè)務(wù)分析方法上的區(qū)別。簡(jiǎn)單來(lái)說(shuō),流程驅(qū)動(dòng)和事件驅(qū)動(dòng)的一個(gè)簡(jiǎn)單比較可以用下圖描述:

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

基于EDA的核心業(yè)務(wù)分析思路說(shuō)明

在事件驅(qū)動(dòng)架構(gòu)下,業(yè)務(wù)分析的核心就是事件的識(shí)別。而對(duì)于傳統(tǒng)方法往往則是關(guān)鍵流程和活動(dòng)即可。在總體分析思路上的變化來(lái)說(shuō),傳統(tǒng)分析方法只分析到第2-3級(jí)業(yè)務(wù)流程,識(shí)別業(yè)務(wù)活動(dòng)和交互點(diǎn),而EDA需要業(yè)務(wù)分析時(shí)候分析到L4級(jí)的最底層EPC事件流程圖,并識(shí)別關(guān)鍵業(yè)務(wù)事件和事件分解,聚合關(guān)系。

在具體分析內(nèi)容上的變化來(lái)說(shuō),傳統(tǒng)方法只關(guān)心業(yè)務(wù)活動(dòng),而不關(guān)系業(yè)務(wù)活動(dòng)具體的啟動(dòng)機(jī)制,業(yè)務(wù)活動(dòng)完成后產(chǎn)生的業(yè)務(wù)事件。基于EDA業(yè)務(wù)分析方法,需要打開(kāi)業(yè)務(wù)活動(dòng),識(shí)別業(yè)務(wù)活動(dòng)的前者觸發(fā)條件和業(yè)務(wù)活動(dòng)引起的業(yè)務(wù)對(duì)象狀態(tài)的變化,往往狀態(tài)變化點(diǎn)都是關(guān)鍵的事件識(shí)別點(diǎn)。

具體可以用下圖進(jìn)行描述:

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

簡(jiǎn)單事件-基于業(yè)務(wù)需求用例分析和識(shí)別

業(yè)務(wù)事件的識(shí)別可以從業(yè)務(wù)需求用例入手,分析業(yè)務(wù)用例中的業(yè)務(wù)前置觸發(fā)條件,分析業(yè)務(wù)對(duì)象的狀態(tài)流轉(zhuǎn)過(guò)程和后續(xù)操作,以找尋業(yè)務(wù)活動(dòng)的事件輸入和事件產(chǎn)生。

從下圖里面也可以看到,對(duì)于事件的識(shí)別往往比用例的識(shí)別更加細(xì)化,需要詳細(xì)的分析業(yè)務(wù)用例中的基本流,擴(kuò)展流,業(yè)務(wù)規(guī)則,特別是關(guān)注其中核心的業(yè)務(wù)對(duì)象和單據(jù)狀態(tài)的變化。同時(shí)對(duì)于用例分析中的觸發(fā)條件也需要重點(diǎn)分析,這些觸發(fā)條件往往是事件鏈形成,或者說(shuō)觸發(fā)消息事件訂閱的來(lái)源。

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

復(fù)雜事件-基于事件識(shí)別形成事件鏈

傳統(tǒng)的基于流程的業(yè)務(wù)分析方法往往只會(huì)分析到業(yè)務(wù)流程,具體的業(yè)務(wù)活動(dòng),而不關(guān)心具體業(yè)務(wù)活動(dòng)執(zhí)行前或執(zhí)行后產(chǎn)生的業(yè)務(wù)事件,這和接口平臺(tái)前期重點(diǎn)關(guān)注數(shù)據(jù)集成有關(guān)系。而為了保證業(yè)務(wù)實(shí)時(shí)響應(yīng)需求,必須準(zhǔn)確的識(shí)別業(yè)務(wù)事件,才能進(jìn)一步設(shè)計(jì)基于業(yè)務(wù)事件的處理和響應(yīng)機(jī)制。

基于EPC事件流程鏈分析思路,需要對(duì)傳統(tǒng)分析流程進(jìn)行細(xì)化,增加紅色事件識(shí)別點(diǎn)和事件分解聚合關(guān)系。在事件鏈的形成過(guò)程中往往存在一些復(fù)雜場(chǎng)景需要分析,包括了事件的一對(duì)多分發(fā)和訂閱,也包括了多個(gè)事件聚合,在滿(mǎn)足某個(gè)特定的業(yè)務(wù)規(guī)則后才觸發(fā)下一個(gè)新的業(yè)務(wù)活動(dòng)和新事件。這些都是在復(fù)雜事件分析中必須考慮的內(nèi)容之一。

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

從EDA事件驅(qū)動(dòng)到CQRS

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

顧名思義,CQRS即命令查詢(xún)職責(zé)分離,將CUD操作和R查詢(xún)操作分離,對(duì)于CUD操作仍然參考傳統(tǒng)的領(lǐng)域模型建模思路來(lái)實(shí)現(xiàn),但是在命令中增加了消息事件機(jī)制,實(shí)現(xiàn)CUD操作變更通過(guò)消息事件異步寫(xiě)入到數(shù)據(jù)庫(kù)。

在CQRS中,查詢(xún)方面,直接通過(guò)方法查詢(xún)數(shù)據(jù)庫(kù),然后通過(guò)DTO將數(shù)據(jù)返回,這個(gè)方面的操作相對(duì)比較簡(jiǎn)單。而命令方面,是通過(guò)發(fā)送具體Command,接著由CommandBus來(lái)分發(fā)到具體的CommandHandle來(lái)進(jìn)行處理,CommandHandle在進(jìn)行處理時(shí),并沒(méi)有直接將對(duì)象的狀態(tài)保存到外部持久化結(jié)構(gòu)中,而僅僅是從領(lǐng)域?qū)ο笾蝎@得產(chǎn)生的一系列領(lǐng)域事件,并將這些事件保存到Event Store中,同時(shí)將事件發(fā)布到事件總線(xiàn)Event Bus進(jìn)行下一步處理;接著Event Bus同樣進(jìn)行協(xié)調(diào),將具體的事件交給具體的Event Handle進(jìn)行處理,最后Event Handler把對(duì)象的狀態(tài)保存到對(duì)應(yīng)Query數(shù)據(jù)庫(kù)中。

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

對(duì)于CQRS,最容易想到的還是在數(shù)據(jù)庫(kù)層面做的讀寫(xiě)分離模式,可以看到CQRS本身和數(shù)據(jù)庫(kù)的讀寫(xiě)分離模式可以更好的匹配,由于采用事件驅(qū)動(dòng)和消息訂閱模式,對(duì)于R讀庫(kù)我們可以更加容易對(duì)數(shù)據(jù)變更信息進(jìn)行更新,達(dá)到讀庫(kù)數(shù)據(jù)的及時(shí)同步更新。同時(shí)讀庫(kù)既可以采用讀寫(xiě)分離數(shù)據(jù)庫(kù),也可以采用類(lèi)似Solr,Nosql等分布式,非結(jié)構(gòu)化數(shù)據(jù)來(lái)實(shí)現(xiàn)彈性水平擴(kuò)展能力。

在命令查詢(xún)職責(zé)沒(méi)有分離的時(shí)候,可以看到一方面是模型本身的擴(kuò)展性受到影響,另外一方面是原有的領(lǐng)域模型本身偏重,而且Entity實(shí)體本身也通過(guò)完整的DTO對(duì)象進(jìn)行傳輸,這樣在一些特殊的只需要更新或查詢(xún)個(gè)別字段的時(shí)候,整個(gè)模型仍然偏重。

通過(guò)命令查詢(xún)職責(zé)的解耦,不僅僅是提升整個(gè)框架模型的擴(kuò)展性,更加重要是將兩類(lèi)業(yè)務(wù)規(guī)則和實(shí)現(xiàn)徹底的解耦開(kāi),方便后續(xù)的功能開(kāi)發(fā)和運(yùn)維,特別是在整個(gè)業(yè)務(wù)場(chǎng)景和邏輯實(shí)現(xiàn)復(fù)雜的情況下,這種解耦會(huì)使整個(gè)開(kāi)發(fā)架構(gòu)更加清晰簡(jiǎn)單。

同時(shí)也可以看到有一Command命令都是采用異步事件的方式進(jìn)行寫(xiě)入,因此不存在同步和長(zhǎng)連接占用的問(wèn)題,有利于提升整個(gè)平臺(tái)在大并發(fā)下的整體響應(yīng)性能。

當(dāng)然,采用CQRS模式最大的一個(gè)問(wèn)題點(diǎn)就是無(wú)法實(shí)現(xiàn)命令和查詢(xún)兩部分內(nèi)容的強(qiáng)一致性保障,即很可能你界面上查詢(xún)到的數(shù)據(jù)不是最新的持久化數(shù)據(jù)庫(kù)里面的數(shù)據(jù),這個(gè)本身和消息管道異步寫(xiě)入的實(shí)時(shí)性有關(guān)系。

其次在使用CQRS模式的時(shí)候,有一個(gè)重要假設(shè)就是,在事件和命令發(fā)出后,無(wú)特殊情況在事件接收方都必須要能夠接收事件成功處理,否則就存在大量的異常錯(cuò)誤消息的異步回寫(xiě),反而增加系統(tǒng)的復(fù)雜度。舉個(gè)簡(jiǎn)單例子來(lái)說(shuō):

當(dāng)我們?cè)陔娚唐脚_(tái)購(gòu)買(mǎi)一個(gè)商品的時(shí)候,只要訂單提交成功,那么這個(gè)訂單就一定能夠生效,也一定有庫(kù)存能夠發(fā)運(yùn)和配送,而不是在后續(xù)到了配送環(huán)節(jié)的時(shí)才發(fā)現(xiàn)沒(méi)有庫(kù)存而導(dǎo)致訂單取消。如果這樣的話(huà)就極大的降低了系統(tǒng)本身的易用性。

即在異步命令和事件發(fā)送場(chǎng)景,當(dāng)命令發(fā)送成功時(shí)候,雖然我們沒(méi)有及時(shí)接收到處理方的事件處理結(jié)果信息,但是我們默認(rèn)是接收方能夠成功處理事件。但是我們也看到在CQRS場(chǎng)景框架下,只要命令事件發(fā)出,我們并不需要等待任何反饋信息。

另外還有一種CQRS實(shí)現(xiàn)場(chǎng)景,即雖然在內(nèi)部對(duì)Command命令處理的時(shí)候是基于事件機(jī)制,異步響應(yīng),但是客戶(hù)在前端的操作是同步等待返回。在這種情況下我們就可以保持前端連接,但是是否后端的類(lèi)似DB連接等。

在CQRS模型下,由于職責(zé)分離,可以看到我們通過(guò)事件和消息的訂閱,可以實(shí)現(xiàn)多個(gè)讀庫(kù)的訂閱,這些讀庫(kù)既可以是結(jié)構(gòu)化數(shù)據(jù)庫(kù),也可以是非結(jié)構(gòu)化數(shù)據(jù)庫(kù);既可以用來(lái)實(shí)現(xiàn)業(yè)務(wù)功能本身的查詢(xún)讀,也可以用來(lái)做海量數(shù)據(jù)本身的分布式全文檢索。

對(duì)于CQRS框架的實(shí)施,不是簡(jiǎn)單的設(shè)計(jì)模式使用問(wèn)題,更加重要的仍然是是否能夠接受最終一致性要求,同時(shí)在該要求下將傳統(tǒng)的同步請(qǐng)求下業(yè)務(wù)功能和邏輯處理機(jī)制轉(zhuǎn)變?yōu)楫惒绞录r(jià)值下的事件鏈驅(qū)動(dòng)模式。要實(shí)現(xiàn)這種轉(zhuǎn)變就必須能夠拆分出獨(dú)立,自治的命令和事件,同時(shí)確保這些事件在朝后端業(yè)務(wù)功能和邏輯模塊發(fā)送的時(shí)候能夠處理成功(即該做的校驗(yàn)必須提前做完)。

將同步接口調(diào)用轉(zhuǎn)為本地消息緩存

這個(gè)類(lèi)似消息中間件的功能,舉例來(lái)說(shuō)我們?cè)O(shè)計(jì)了一個(gè)同步發(fā)送訂單到ERP系統(tǒng)的接口,如果在同步實(shí)時(shí)調(diào)用這個(gè)接口服務(wù)的時(shí)候出現(xiàn)異常,那么我們可以首先將消息存儲(chǔ)到本地,然后設(shè)置定時(shí)任務(wù)和重試機(jī)制,通過(guò)重試方式將消息發(fā)送到目標(biāo)系統(tǒng)。

即對(duì)于業(yè)務(wù)功能來(lái)說(shuō)不用關(guān)心實(shí)時(shí)是否發(fā)送成功,而由業(yè)務(wù)系統(tǒng)自身機(jī)制來(lái)完成消息發(fā)送的重試。

而要做到這點(diǎn),在接口功能設(shè)計(jì)時(shí)候,最好要做到單據(jù)業(yè)務(wù)完整性校驗(yàn)接口和實(shí)際的數(shù)據(jù)發(fā)送接口分離,即先調(diào)用接口進(jìn)行完整性校驗(yàn),在校驗(yàn)沒(méi)有問(wèn)題后再進(jìn)行消息發(fā)送。以確保最終發(fā)送的消息不會(huì)因?yàn)閿?shù)據(jù)完整性的原因?qū)е聼o(wú)法發(fā)送成功。

查詢(xún)數(shù)據(jù)的本地化緩存或落地

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

memcached是一套分布式的高速緩存系統(tǒng),由LiveJournal的Brad Fitzpatrick開(kāi)發(fā),但被許多網(wǎng)站使用。這是一套開(kāi)放源代碼軟件,以BSD license授權(quán)發(fā)布。

memcached的API使用三十二比特的循環(huán)冗余校驗(yàn)(CRC-32)計(jì)算鍵值后,將數(shù)據(jù)分散在不同的機(jī)器上。當(dāng)表格滿(mǎn)了以后,接下來(lái)新增的數(shù)據(jù)會(huì)以L(fǎng)RU機(jī)制替換掉。由于memcached通常只是當(dāng)作緩存系統(tǒng)使用,所以使用memcached的應(yīng)用程序在寫(xiě)回較慢的系統(tǒng)時(shí)(像是后端的數(shù)據(jù)庫(kù))需要額外的代碼更新memcached內(nèi)的數(shù)據(jù)。

對(duì)于實(shí)時(shí)查詢(xún)類(lèi)接口,將查詢(xún)的基礎(chǔ)數(shù)據(jù)進(jìn)行本地化緩存,即如果在實(shí)時(shí)查詢(xún)出現(xiàn)異常的時(shí)候,我們可以直接查詢(xún)本地緩存的數(shù)據(jù),減少對(duì)業(yè)務(wù)功能使用的影響。

比如查詢(xún)供應(yīng)商接口服務(wù),如果主數(shù)據(jù)系統(tǒng)提供的接口出現(xiàn)異常,我們可以直接查詢(xún)本地緩存的供應(yīng)商數(shù)據(jù)。這種模式對(duì)于變更不頻繁的數(shù)據(jù)基本都適應(yīng),同時(shí)本身也減少實(shí)時(shí)調(diào)用接口帶來(lái)的性能損耗。

如果是接口服務(wù)注冊(cè)在API網(wǎng)關(guān)或ESB服務(wù)總線(xiàn)上面,我們還可以考慮在ESB服務(wù)總線(xiàn)上啟用緩存能力,即對(duì)于調(diào)用過(guò)的接口,在同樣參數(shù)重復(fù)調(diào)用的時(shí)候能夠通過(guò)緩存數(shù)據(jù)獲取,這樣即使在源端業(yè)務(wù)系統(tǒng)不可用的情況下,也不好影響到當(dāng)前接口服務(wù)的成功調(diào)用。

可以適度考慮數(shù)據(jù)落地

在微服務(wù)架構(gòu)里面,我們一直在強(qiáng)調(diào)一點(diǎn),即數(shù)據(jù)實(shí)時(shí)需要實(shí)時(shí)訪(fǎng)問(wèn),不進(jìn)行底層數(shù)據(jù)庫(kù)的數(shù)據(jù)集成和同步,這既滿(mǎn)足了數(shù)據(jù)的高一致性,也滿(mǎn)足了數(shù)據(jù)實(shí)時(shí)性的要求。

但是帶來(lái)的問(wèn)題就是強(qiáng)耦合,如果數(shù)據(jù)提供方出現(xiàn)異常,那么導(dǎo)致消費(fèi)方業(yè)務(wù)功能也無(wú)法使用。

因?yàn)槲覀兛梢赃m量考慮數(shù)據(jù)落地方式的數(shù)據(jù)集成在整體微服務(wù)架構(gòu)實(shí)施過(guò)程中,對(duì)于變化不頻繁的數(shù)據(jù)適度落地到微服務(wù)模塊本地。這樣本身可以減少實(shí)時(shí)的業(yè)務(wù)接口服務(wù)調(diào)用,增加單個(gè)微服務(wù)模塊的可用性和可靠性。

對(duì)于已經(jīng)出現(xiàn)強(qiáng)耦合如何重構(gòu)

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

如果微服務(wù)已經(jīng)實(shí)施完成并出現(xiàn)了大量緊耦合的情況,那么我們就需要在后期考慮對(duì)微服務(wù)架構(gòu)進(jìn)行重構(gòu),具體重構(gòu)的方法可以從如下幾點(diǎn)考慮。

兩個(gè)微服務(wù)本身緊耦合

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

如果兩個(gè)微服務(wù)間出現(xiàn)大量接口相互調(diào)用,即可以認(rèn)為緊耦合。

或者我原來(lái)的判斷標(biāo)準(zhǔn),即兩個(gè)微服務(wù)對(duì)應(yīng)的后臺(tái)數(shù)據(jù)表,其中30%以上都需要兩個(gè)微服務(wù)交叉訪(fǎng)問(wèn),那么就認(rèn)為兩個(gè)微服務(wù)本身耦合性極強(qiáng)。

在這種情況下處理措施就是原來(lái)微服務(wù)劃分的太細(xì)了,需要對(duì)兩個(gè)微服務(wù)進(jìn)行合并。

交叉依賴(lài)變?yōu)楣残砸蕾?lài)

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

要知道在傳統(tǒng)軟件開(kāi)發(fā)里面往往是不允許兩個(gè)組件交叉依賴(lài)的。

但是在新的IOC和微服務(wù)開(kāi)發(fā)里面,大量都是反射調(diào)用,兩個(gè)組件相互依賴(lài)不會(huì)有問(wèn)題。但是這本身也不是一種很好的設(shè)計(jì)方法。

如果兩個(gè)微服務(wù)或多個(gè)微服務(wù)相互依賴(lài)內(nèi)容本身具備共性。那么最好的做法就是將共性?xún)?nèi)容全部移出,下沉為一個(gè)共性基礎(chǔ)微服務(wù)模塊再朝上提供服務(wù)。

即交叉依賴(lài)轉(zhuǎn)變?yōu)閷?duì)底層的共性依賴(lài)。

對(duì)某個(gè)微服務(wù)實(shí)現(xiàn)單元進(jìn)行遷移

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

為什么出現(xiàn)這種場(chǎng)景?

簡(jiǎn)單來(lái)說(shuō)就是原來(lái)的微服務(wù)模塊劃分和業(yè)務(wù)功能劃分不合理。比如上圖中的微服務(wù)A中的A1部分。這個(gè)部分內(nèi)容需要大量被微服務(wù)B調(diào)用,但是A1實(shí)際依賴(lài)微服務(wù)A中其它部分的內(nèi)容卻很少。

這種就是典型的A1部分功能劃分位置不合理。

最好的做法就是將A1功能從微服務(wù)A遷移到微服務(wù)B,實(shí)現(xiàn)對(duì)原有業(yè)務(wù)劃分不合理的糾正。

將細(xì)粒度服務(wù)轉(zhuǎn)變?yōu)榇至6确?wù)

微服務(wù)架構(gòu)下如何解耦,對(duì)于已經(jīng)緊耦合下如何重構(gòu)?

 

服務(wù)本身應(yīng)該具備粗粒度屬性,暴露僅僅需要暴露的內(nèi)容。

比如微服務(wù)A實(shí)現(xiàn)客戶(hù)信用檢查和評(píng)級(jí)。微服務(wù)B需要客戶(hù)信用。有兩種做法

第一種是B調(diào)用A多個(gè)接口,把客戶(hù)基本信息,客戶(hù)交易信息,客戶(hù)違約信息全部查詢(xún)過(guò)來(lái),然后自己計(jì)算客戶(hù)信用。

第二種即是只需要輸入客戶(hù)編碼,微服務(wù)A返回最早的信用評(píng)級(jí)。

對(duì)于后者就是我們常說(shuō)的粗粒度接口或領(lǐng)域服務(wù),服務(wù)間的交互應(yīng)該以領(lǐng)域服務(wù)和粗粒度服務(wù)為主,避免掉完全的數(shù)據(jù)庫(kù)表的CRUD類(lèi)服務(wù)接口。

 

分享到:
標(biāo)簽:微服 架構(gòu)
用戶(hù)無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過(guò)答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定