新聞中心
在微服務(wù)架構(gòu)的世界中,我們通過一系列服務(wù)構(gòu)建應(yīng)用。集合中的每項服務(wù)都符合以下標(biāo)準(zhǔn):

站在用戶的角度思考問題,與客戶深入溝通,找到貴定網(wǎng)站設(shè)計與貴定網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:做網(wǎng)站、成都網(wǎng)站設(shè)計、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、空間域名、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋貴定地區(qū)。
- 松散耦合
- 可維護(hù)和可測試
- 可以獨(dú)立部署
微服務(wù)架構(gòu)中的每個服務(wù)都解決了應(yīng)用中的業(yè)務(wù)問題,或至少支持一個。一個團(tuán)隊對應(yīng)用中的一個或多個服務(wù)負(fù)責(zé)。
微服務(wù)架構(gòu)可以解鎖許多好處。
- 它們通常更容易構(gòu)建和維護(hù)
- 服務(wù)是圍繞業(yè)務(wù)問題組織的
- 它們可以提高生產(chǎn)力和速度
- 它們鼓勵自主、獨(dú)立的團(tuán)隊
這些好處是微服務(wù)越來越受歡迎的一個重要原因。但有一些可能會破壞這些好處的坑。如果不小心掉進(jìn)去了,你將得到一個不斷產(chǎn)生技術(shù)債的架構(gòu)。
微服務(wù)之間的通信就是一個坑,假如不提前考慮就會造成嚴(yán)重的破壞。
該體系結(jié)構(gòu)的目標(biāo)是創(chuàng)建松散耦合的服務(wù),并且通信在實現(xiàn)這一目標(biāo)中起著關(guān)鍵作用。在本文中,我們將重點(diǎn)關(guān)注在微服務(wù)架構(gòu)中進(jìn)行通信的三種方式,每一種都有其自己的利弊和權(quán)衡。
HTTP通信
選擇服務(wù)如何相互通信時,最直接的方式往往是 HTTP。事實上,我們可以提出一個案例,即所有通信渠道都來自這個渠道。但是除此之外,服務(wù)之間的 HTTP 調(diào)用是服務(wù)到服務(wù)通信的可行選擇。
如果我們的架構(gòu)中有兩個服務(wù),它可能看起來像這樣: ServiceA 可以請求并調(diào)用 ServiceB 來獲取另一條信息。
- function process(name: string): Promise
{ - /** do some ServiceA business logic
- ....
- ....
- */
- /**
- * call ServiceB to run some different business logic
- */
- return fetch('https://service-b.com/api/endpoint')
- .then((response) => {
- if (!response.ok) {
- throw new Error(response.statusText)
- } else {
- return response.json().then(({saved}) => {
- return saved
- })
- }
- })
- }
這是一段很容易理解的適合微服務(wù)架構(gòu)的代碼。 ServiceA 提供了一個業(yè)務(wù)邏輯。它運(yùn)行其代碼然后調(diào)用 ServiceB 來運(yùn)行另一個業(yè)務(wù)邏輯。在這段代碼中,第一個服務(wù)在返回之前完成等待第二個服務(wù)完成。
這里有兩個服務(wù)之間進(jìn)行同步的 HTTP 調(diào)用。這是一種可行的通信模式,但它確實在兩種服務(wù)之間建立了耦合。
另一個選擇是異步 HTTP。這可能是這樣的:
- function asyncProcess(name: string): Promise
{ - /** do some ServiceA business logic
- ....
- ....
- */
- /**
- * call ServiceB to run some different business logic
- */
- return fetch('https://service-b.com/api/endpoint')
- .then((response) => {
- if (!response.ok) {
- throw new Error(response.statusText)
- } else {
- return response.json().then(({statusUrl}) => {
- return statusUrl
- })
- }
- })
- }
這種變化是微妙的?,F(xiàn)在, ServiceB 不返回 saved 屬性,而是返回一個 statusUrl。這意味著此服務(wù)現(xiàn)在正在接收來自第一個服務(wù)的請求,并且立即返回一個URL。此 URL 可用來檢查請求的進(jìn)度。
將兩種服務(wù)之間的通信從同步轉(zhuǎn)換為異步,第一個服務(wù)不再停留等待第二個服務(wù)完成,然后再返回其工作。
通過這種方法可以使服務(wù)彼此隔離,并且耦合松散。
缺點(diǎn)是需要在第二個服務(wù)上創(chuàng)建額外的 HTTP 請求,它從外部進(jìn)行輪詢,直到請求完成。這也引入了客戶端的復(fù)雜性,因為必須檢查請求的進(jìn)度。
但是,異步通信允許服務(wù)直接保持松散耦合。
消息通信
另一種通信模式是基于消息的通信。
與HTTP通信不同,所涉及的服務(wù)不直接相互通信。相反,服務(wù)將消息推送到其他服務(wù)訂閱的消息代理。這消除了許多與 HTTP 通信相關(guān)的復(fù)雜性。
它不需要服務(wù)知道該如何相互交流,它消除了直接相互調(diào)用的服務(wù)需求。相反,所有服務(wù)都知道消息代理,并且它們將消息推送到該代理。其他服務(wù)可以訂閱代理中自己關(guān)心的消息。
如果我們的應(yīng)用在 Amazon Web Services 中,可以用簡單通知服務(wù)(SNS)作為消息代理?,F(xiàn)在 ServiceA 可以將消息推送到 ServiceB 監(jiān)聽的 SNS 主題。
- function asyncProcessMessage(name: string): Promise
{ - /** do some ServiceA business logic
- ....
- ....
- */
- /**
- * send message to SNS that ServiceB is listening on
- */
- let snsClient = new AWS.SNS()
- let params = {
- Message: JSON.stringify({
- 'data': 'our message data'
- }),
- TopicArn: 'our-sns-topic-message-broker'
- }
- return snsClient.publish(params)
- .then((response) => {
- return response.MessageId
- })
- }
ServiceB 偵聽 SNS 主題上的消息,當(dāng)收到一個關(guān)心的消息時,就會執(zhí)行它的業(yè)務(wù)邏輯。
這引入了它自己的復(fù)雜性。請注意,ServiceA 不再接收狀態(tài) URL 檢查進(jìn)度。這是因為我們只知道消息已經(jīng)被發(fā)??送,而不知道 ServiceB 是否已經(jīng)收到了它。
這可以通過許多不同的方式解決。一種方法是將 MessageId 返回給調(diào)用者。可以用它來查詢 ServiceB,它將存儲它收到的消息的 MessageId。
注意,使用此模式的兩個服務(wù)之間仍然存在一些耦合。例如,ServiceB 和 ServiceA 必須就消息結(jié)構(gòu)的定義以及其中包含什么達(dá)成一致。
事件驅(qū)動的通信
最后一種模式是事件驅(qū)動模式。這是另一種異步方法,它看起來完全消除了服務(wù)之間的耦合。
與消息傳遞模式不同,事件驅(qū)動方法不需要服務(wù)必須知道公共消息結(jié)構(gòu)。服務(wù)之間的通信通過各個服務(wù)產(chǎn)生的事件進(jìn)行。
此處仍然需要消息代理,因為各個服務(wù)會將其事件寫入其中。但是與消息方法不同,消費(fèi)服務(wù)不需要知道事件的細(xì)節(jié),它們對事件的發(fā)生做出反應(yīng),而不是產(chǎn)生能會或可能不會傳遞的信息。
在形式上,這通常被稱為“僅事件驅(qū)動的通信”。下面的代碼和消息傳遞方法類似,但推送到SNS的事件是通用的。
- function asyncProcessEvent(name: string): Promise
{ - /** do some ServiceA business logic
- ....
- ....
- */
- /**
- * call ServiceB to run some different business logic
- */
- let snsClient = new AWS.SNS()
- let params = {
- Message: JSON.stringify({
- 'event': 'service-a-event'
- }),
- TopicArn: 'our-sns-topic-message-broker'
- }
- return snsClient.publish(params)
- .then((response) => {
- return response.MessageId
- })
- }
注意,我們的 SNS 主題消息是一個簡單的 event 屬性。每個服務(wù)都同意以這種格式將事件推送到代理,這使得通信松散耦合。服務(wù)可以監(jiān)聽他們關(guān)心的事件,并且提供為響應(yīng)它們而需要運(yùn)行的邏輯。
此模式使服務(wù)的耦合松散,因為事件中不包含任何有效負(fù)載。此方法中的每個服務(wù)都會響應(yīng)事件的發(fā)生并運(yùn)行其業(yè)務(wù)邏輯。在這里,我們通過 SNS 主題發(fā)送事件。也可以使用其他事件,例如文件上傳或數(shù)據(jù)庫行更新。
結(jié)論
這些是基于微服務(wù)的架構(gòu)中所有可能的通信模式嗎?當(dāng)然不是?;谕胶彤惒侥J竭M(jìn)行通信的方式還有很多種。
但是這三個突出了支持同步與異步的優(yōu)缺點(diǎn)。在選擇時要考慮耦合因素,但也需要考慮開發(fā)和調(diào)試的具體情況與注意事項。
網(wǎng)站題目:微服務(wù)的三種通信方法
網(wǎng)站地址:http://www.5511xx.com/article/dphispj.html


咨詢
建站咨詢
