如今,微服務(wù)“Microservices”已經(jīng)成為軟件架構(gòu)領(lǐng)域最流行的熱詞之一。市面上也有很多與微服務(wù)的基礎(chǔ)知識(shí)以及優(yōu)點(diǎn)相關(guān)的學(xué)習(xí)資料,但是關(guān)于如何在真實(shí)的企業(yè)場(chǎng)景中應(yīng)用微服務(wù)的資料還是不多。
在這篇文章里, 我計(jì)劃涵蓋微服務(wù)架構(gòu)(MSA)的核心架構(gòu)概念,以及你如何在實(shí)踐中使用這些架構(gòu)理論。
單體架構(gòu)
企業(yè)軟件設(shè)計(jì)需要滿(mǎn)足多種多樣的業(yè)務(wù)需求。因此,一個(gè)特定的應(yīng)用軟件會(huì)包括有幾百個(gè)功能項(xiàng),而所有這些功能項(xiàng)都打包進(jìn)了一個(gè)單體的應(yīng)用中。典型的例子有,ERP、CRM等其他各種各樣的軟件。對(duì)于這種野獸級(jí)別的軟件應(yīng)用、部署、排錯(cuò)、擴(kuò)展和升級(jí)工作都是一個(gè)個(gè)噩夢(mèng)。
面向服務(wù)架構(gòu)(SOA)設(shè)計(jì)是針對(duì)上述問(wèn)題的一個(gè)解決方案, SOA引入了服務(wù)的概念,用來(lái)將軟件中相似的功能進(jìn)行分組聚合在一起。因此,有了SOA,軟件就被設(shè)計(jì)為一組粗粒度服務(wù)的組合。 但是SOA并沒(méi)有解決所有的問(wèn)題。在SOA里,一個(gè)服務(wù)的范圍是非常廣的。由此帶來(lái)的弊端是服務(wù)本身龐大而復(fù)雜,數(shù)十個(gè)功能點(diǎn),以及復(fù)雜的消息格式和標(biāo)準(zhǔn)(例如所有的WS規(guī)范)。
在大多數(shù)情況下,SOA里面的服是互相獨(dú)立的,而且是與其他所有的服務(wù)部署在同一個(gè)運(yùn)行時(shí)上面。(可以想象一下多個(gè)Web應(yīng)用部署到同一個(gè)Tomcat實(shí)例當(dāng)中)。而且與單體軟件類(lèi)似,這些服務(wù)會(huì)隨時(shí)間越長(zhǎng)越大,因?yàn)槔奂拥墓δ茉絹?lái)越多。最后,這些應(yīng)用本身已變成了單體軟件,與傳統(tǒng)的單體軟件(比如ERP)也沒(méi)啥兩樣。圖1描述了一個(gè)零售業(yè)的軟件,它包含有多個(gè)服務(wù),所有這些服務(wù)都部署在同一個(gè)運(yùn)行時(shí)上。 這是一個(gè)很好的單體架構(gòu)的例子。這里我列出這種基于單體架構(gòu)軟件的一些特點(diǎn):
單獨(dú)應(yīng)用是作為一個(gè)整體單元來(lái)設(shè)計(jì)、開(kāi)發(fā)、部署的;
單體應(yīng)用非常復(fù)雜,導(dǎo)致的結(jié)果就是維護(hù),升級(jí)和增加新功能都非常困難;
在單體架構(gòu)下,非常難實(shí)踐敏捷的開(kāi)發(fā)和部署方法;
如果要更新它的某個(gè)部署,則需要重新部署整個(gè)應(yīng)用;
擴(kuò)展:必須作為單個(gè)軟件來(lái)擴(kuò)展,當(dāng)有資源需求沖突時(shí)擴(kuò)展就變得非常困難(比如一個(gè)服務(wù)需要更多的CPU但是其他的服務(wù)要更多內(nèi)存);
可靠性:一個(gè)不穩(wěn)定的服務(wù)可能會(huì)導(dǎo)致整個(gè)應(yīng)用不可用;
阻礙創(chuàng)新: 由于所有的功能都基于同一套技術(shù)框架來(lái)夠構(gòu)建,想加入新的技術(shù)或者框架就非常困難。
微服務(wù)架構(gòu)
微服務(wù)架構(gòu)的基礎(chǔ)是開(kāi)發(fā)一個(gè)應(yīng)用由一組小但是獨(dú)立的服務(wù)來(lái)組成,這些服務(wù)運(yùn)行在自己的進(jìn)程中,可以被獨(dú)立開(kāi)發(fā),獨(dú)立部署。
在大多數(shù)的微服務(wù)架構(gòu)的定義里,這被解釋為將一個(gè)單體應(yīng)用里面的服務(wù)拆分為一組獨(dú)立的服務(wù)。但是,我覺(jué)得,這不是微服務(wù)的全部。
核心的觀點(diǎn)是通過(guò)查看單體服務(wù)提供的功能項(xiàng)目,來(lái)識(shí)別出必須的業(yè)務(wù)能力。然后這些業(yè)務(wù)能力可以作為一個(gè)完全獨(dú)立的,細(xì)粒度的,自包含的服務(wù)來(lái)實(shí)現(xiàn)(微服務(wù))。他們的實(shí)現(xiàn)可以是基于不同的技術(shù)棧,而且每個(gè)服務(wù)描述的是一個(gè)明確的特定的有限的業(yè)務(wù)范圍。
因此,我們上文中提到的在線(xiàn)零售系統(tǒng)可以用圖2里面的微服務(wù)架構(gòu)來(lái)實(shí)現(xiàn)。 在微服務(wù)架構(gòu)下,零售軟件應(yīng)用通過(guò)一組微服務(wù)來(lái)實(shí)現(xiàn)。所以你看到圖2中,我們?cè)黾釉谠瓉?lái)單體應(yīng)用里面的一組服務(wù)的基礎(chǔ)上新增加了一個(gè)服務(wù)。所以很明顯,使用微服務(wù)架構(gòu)不是僅僅將單體應(yīng)用里面的服務(wù)拆分那么簡(jiǎn)單。
接下來(lái),讓我們更加深入了解微服務(wù)的核心架構(gòu)原則。更重要的是,讓我們關(guān)注如何將他們應(yīng)用到實(shí)踐中。
設(shè)計(jì)微服務(wù): 大小、范圍和能力
你可能在使用微服務(wù)架構(gòu)從頭構(gòu)建一個(gè)軟件,也可能是要把已有的應(yīng)用服務(wù)轉(zhuǎn)換為微服務(wù)。無(wú)論哪種,非常重要的一點(diǎn)都是你必須合理的決定微服務(wù)的大小、范圍和能力。這極有可能是在實(shí)踐微服務(wù)架構(gòu)初期碰到的最難的事情。
接下來(lái)我們來(lái)討論與微服務(wù)的大小、范圍、能力相關(guān)的一些實(shí)際的考慮點(diǎn)和錯(cuò)誤觀點(diǎn)。
代碼行數(shù)和團(tuán)隊(duì)大小是很糟糕的度量指標(biāo):基于代碼行數(shù)或者團(tuán)隊(duì)大小來(lái)決定微服務(wù)的大小已經(jīng)有多個(gè)討論了。(比如兩個(gè)pizza的團(tuán)隊(duì):http://blog.idonethis.com/two-pizza-team/)。 但是,這些都是非常不切實(shí)際而且非常糟糕的度量值,因?yàn)槲覀冇酶俚拇a或者兩個(gè)pizza的團(tuán)隊(duì)開(kāi)發(fā)出來(lái)的服務(wù)仍然可能完全違背微服務(wù)的架構(gòu)原則。
微“micro”這個(gè)詞會(huì)導(dǎo)致誤解:大多數(shù)開(kāi)發(fā)人員傾向于認(rèn)為們應(yīng)該將服務(wù)做的越小越好。但是這完全是錯(cuò)誤的解釋。
在SOA的上下文里面,服務(wù)通常被實(shí)現(xiàn)為包括很多功能的和運(yùn)營(yíng)支持的單體結(jié)構(gòu)。所以如果僅僅是將SOA那種服務(wù)重新打上微服務(wù)的標(biāo)簽不會(huì)給你帶來(lái)微服務(wù)架構(gòu)的如何好處。
那么,我們?cè)撊绾魏系卦O(shè)計(jì)微服務(wù)架構(gòu)下的服務(wù)呢?
微服務(wù)設(shè)計(jì)原則
單一責(zé)任原則(Single Responsibility Principle,SRP): 對(duì)于一個(gè)微服務(wù)而言具有有限的和關(guān)注的業(yè)務(wù)范圍可以幫助我們滿(mǎn)足服務(wù)開(kāi)發(fā)和交付的敏捷性;
在微服務(wù)的設(shè)計(jì)階段, 我們應(yīng)該找到他們的邊界,并將它們與業(yè)務(wù)能力相關(guān)聯(lián)(在領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)里這叫有邊界的上下文);
必須保證微服務(wù)設(shè)計(jì)能支持服務(wù)的敏捷/獨(dú)立地開(kāi)發(fā)和部署;
我們應(yīng)該關(guān)注微服務(wù)的范圍,而不是一味的把服務(wù)做小。一個(gè)服務(wù)的(正確的)大小應(yīng)該等于滿(mǎn)足某個(gè)特定業(yè)務(wù)能力所需要的大??;
與SOA里面的服務(wù)不同,一個(gè)給定的微服務(wù)應(yīng)該有相當(dāng)少的運(yùn)營(yíng)和功能點(diǎn),以及簡(jiǎn)單的消息格式;
通常一個(gè)好的實(shí)踐是先從一個(gè)比較大的服務(wù)邊界開(kāi)始,然后隨著時(shí)間推移基于業(yè)務(wù)需求來(lái)重構(gòu)成更小的。
在我們的零售系統(tǒng)的案例中,你可以發(fā)現(xiàn)我們將原來(lái)單體應(yīng)用的功能分割到了4個(gè)不同的微服務(wù)中, ‘invenory”、”accountng”、”shipping”、”store”。 它們描述的是一個(gè)有限但關(guān)注的業(yè)務(wù)范圍,而且服務(wù)之間互相完全解耦,保證了開(kāi)發(fā)和部署的敏捷性。
微服務(wù)里的消息
在單體應(yīng)用里面,不同組件的業(yè)務(wù)功能通過(guò)函數(shù)調(diào)用或者語(yǔ)言級(jí)別的方法調(diào)用來(lái)實(shí)現(xiàn)。在SOA中,這轉(zhuǎn)變?yōu)楦铀神詈系腤eb Service級(jí)別的消息,主要是基于HTTP、JMS等不同協(xié)議的SOAP。Webservice 包含的幾十種操作以及復(fù)雜的消息機(jī)制是阻礙Web Services流行的一個(gè)重要因素。對(duì)于微服務(wù)架構(gòu)而言,必須要有一個(gè)簡(jiǎn)單且輕量級(jí)的消息機(jī)制。
同步消息——REST、Thrift
對(duì)于微服務(wù)領(lǐng)域的同步消息機(jī)制而言(可獲得需要服務(wù)給一個(gè)及時(shí)的響應(yīng)否則一直等待), REST是公認(rèn)的選擇。它提供了一種簡(jiǎn)單的消息風(fēng)格,具體實(shí)現(xiàn)是HTTP的請(qǐng)求-響應(yīng),基于資源的API風(fēng)格。因此大多數(shù)的微服務(wù)實(shí)現(xiàn)是使用HTTP和基于資源API風(fēng)格的。(每一個(gè)功能都是通過(guò)一個(gè)資源以及在它之上執(zhí)行的操作來(lái)實(shí)現(xiàn))
Thrift(https://thrift.apache.org/)是REST/HTTP同步消息之外的另一個(gè)選項(xiàng)。使用它你可以給你的微服務(wù)定義一個(gè)接口定義。
異步消息——AMQP、STOMP、MQTT
在某些微服務(wù)場(chǎng)景下,需要使用異步消息技術(shù)(可獲得不需要立即得到回復(fù),甚至完全不要回復(fù))。在這種場(chǎng)景下, 異步消息AMPQ、STOMP、MQTT等被廣泛使用
消息格式——jSON、XML、Thrift、ProtoBuf、Avro
為微服務(wù)來(lái)決定最適合的消息格式是另一個(gè)關(guān)鍵要素。傳統(tǒng)的單體的軟件使用復(fù)雜的二進(jìn)制的格式,SOA/Web services的應(yīng)用使用基于復(fù)雜消息格式(SOAP)和schema(xsd)的文本消息。在大多數(shù)的微服務(wù)里面,它們使用簡(jiǎn)單的基于文本的消息格式,例如基于HTTP資源API風(fēng)格之上的JSON/XML等。在某些情況下它們需要二進(jìn)制的格式時(shí)(文本消息在某些場(chǎng)景下顯得啰嗦),可以使用二進(jìn)制的協(xié)議例如二進(jìn)制的Thrift、Protobuf、Arvo。
服務(wù)協(xié)議-定義服務(wù)的接口——Swagger、RAML、Thrift IDL
當(dāng)你已經(jīng)有一個(gè)業(yè)務(wù)能力以服務(wù)的形式實(shí)現(xiàn)之后, 你需要定義和發(fā)布服務(wù)協(xié)議。 在傳統(tǒng)單體應(yīng)用中, 我們很少找到這個(gè)功能來(lái)定義某個(gè)應(yīng)用的業(yè)務(wù)能力。 在SOA/Web services的世界里面, WSDL用來(lái)描述服務(wù)協(xié)議,但是,我們都知道,WSDL并不是描述微服務(wù)的理想方案,因?yàn)樗珡?fù)雜了而且與SOAP高度耦合。
既然我們是基于REST架構(gòu)風(fēng)格來(lái)構(gòu)建的微服務(wù),我們可以使用同樣的REST API定義的技術(shù)來(lái)定義服務(wù)協(xié)議。因此,微服務(wù)使用標(biāo)準(zhǔn)的REST API定義語(yǔ)言來(lái)定義服務(wù)協(xié)議, 比如Swagger和RAML。
對(duì)于其他一些不是基于HTTP/REST的微服務(wù)實(shí)現(xiàn)(例如Thrift),我們可以協(xié)議級(jí)別的接口定義語(yǔ)言(比如Thrift IDL)。
集成微服務(wù)(跨服務(wù)/進(jìn)程通訊)
在微服務(wù)架構(gòu)里,一個(gè)軟件應(yīng)用是基于一組獨(dú)立的服務(wù)構(gòu)建的。 因此為了實(shí)現(xiàn)某個(gè)應(yīng)用場(chǎng)景,需要不同微服務(wù)、進(jìn)程之間的通訊機(jī)制。這也是微服務(wù)之間跨服務(wù)、進(jìn)程通訊這么重要的原因。
在SOA的實(shí)現(xiàn)中,服務(wù)之間的跨服務(wù)通訊是通過(guò)企業(yè)服務(wù)總線(xiàn)ESB來(lái)實(shí)現(xiàn)的,并且大部分的業(yè)務(wù)邏輯在中間層中(消息路由、傳送、編排)。但是微服務(wù)架構(gòu)推崇去掉中央消息總線(xiàn)將業(yè)務(wù)邏輯放到服務(wù)和客戶(hù)端去(也稱(chēng)之為smart endpoints)。
因?yàn)槲⒎?wù)使用HTTP、 JSON等標(biāo)準(zhǔn)協(xié)議,當(dāng)做跨微服務(wù)之間的通訊時(shí),需要跟一個(gè)不同的協(xié)議做集成的需求很少。在微服務(wù)里面的另一個(gè)可選方案是使用一個(gè)輕量級(jí)的消息總線(xiàn)或者網(wǎng)關(guān),網(wǎng)關(guān)上帶最少的路由功能,不帶任何業(yè)務(wù)邏輯實(shí)現(xiàn)而僅僅是一個(gè)啞管道。基于這些方式,在微服務(wù)架構(gòu)里面就有了如下幾種通訊模式。
點(diǎn)對(duì)點(diǎn)風(fēng)格——直接調(diào)用服務(wù)
在點(diǎn)對(duì)點(diǎn)風(fēng)格里,整個(gè)的消息路由邏輯在端點(diǎn)上,服務(wù)之間直接通訊。每個(gè)服務(wù)暴露一組REST API,外部的服務(wù)或者客戶(hù)端通過(guò)REST API來(lái)調(diào)用。
明顯的,這種模型對(duì)于簡(jiǎn)單的微服務(wù)架構(gòu)應(yīng)用有效。但是隨著服務(wù)數(shù)量的增加,它會(huì)慢慢變得復(fù)雜。這也是為什么在SOA里面要用ESB來(lái)避免雜亂的點(diǎn)對(duì)點(diǎn)的連接。讓我們?cè)囍偨Y(jié)一下點(diǎn)對(duì)點(diǎn)模式的弊端。
非功能需求,比如用戶(hù)認(rèn)證、流控、監(jiān)控等必須在每個(gè)微服務(wù)里實(shí)現(xiàn);
由于通用功能的重復(fù),每個(gè)微服務(wù)的實(shí)現(xiàn)變得復(fù)雜;
在服務(wù)和客戶(hù)端之間沒(méi)有通訊控制(甚至對(duì)于監(jiān)控、跟蹤、過(guò)濾等都沒(méi)有);
對(duì)于大的微服務(wù)實(shí)現(xiàn)來(lái)說(shuō)直接的通訊形式通常被認(rèn)為是反模式(http://www.infoq.com/articles/seven-uservices-antipatterns)。
因此, 在復(fù)雜的微服務(wù)應(yīng)用場(chǎng)景下,不要使用點(diǎn)對(duì)點(diǎn)直連或者中央的ESB,我們可以使用一個(gè)輕量級(jí)的中央消息總線(xiàn)給所有微服務(wù)提供一個(gè)抽象層,而且可以用來(lái)實(shí)現(xiàn)各種非功能的能力。這種風(fēng)格也叫做API Gateway風(fēng)格。
API Gateway風(fēng)格
API Gateway風(fēng)格的核心理念是使用一個(gè)輕量級(jí)的消息網(wǎng)關(guān)作為所有客戶(hù)端、消費(fèi)者的主入口并且在網(wǎng)關(guān)層面上實(shí)現(xiàn)通用的非功能性需求。 通常,一個(gè)API網(wǎng)關(guān)允許你通過(guò)REST來(lái)消費(fèi)一個(gè)受管理的API。 因此我們可以使用它來(lái)暴露微服務(wù)所實(shí)現(xiàn)的業(yè)務(wù)功能, 以受管理的API的形式。 實(shí)際上, 這是微服務(wù)架構(gòu)與API管理的組合,給你帶來(lái)兩種技術(shù)的優(yōu)點(diǎn)。
在我們零售的例子中,如圖5所描述的, 所有的服務(wù)通過(guò)API 網(wǎng)關(guān)來(lái)暴露,這是所有客戶(hù)端訪問(wèn)的唯一入口。 如果一個(gè)微服務(wù)要訪問(wèn)另一個(gè)微服務(wù),也要通過(guò)這個(gè)網(wǎng)關(guān)。
API網(wǎng)關(guān)帶來(lái)以下優(yōu)點(diǎn):
在網(wǎng)關(guān)層面對(duì)存在的微服務(wù)提供必要的抽象。例如,網(wǎng)關(guān)可以選擇不提供一個(gè)適用所有的API, 而選擇對(duì)不同的用戶(hù)暴露不同的API;
在網(wǎng)關(guān)層面的輕量級(jí)消息路由和轉(zhuǎn)換;
一個(gè)中心的地方提供非功能性的能力, 比如安全、監(jiān)控、限流等;
通過(guò)適用API網(wǎng)關(guān)模式,微服務(wù)可以變得更加輕量,因?yàn)榉枪δ苄孕枨蠖荚诰W(wǎng)關(guān)上實(shí)現(xiàn)了。
API網(wǎng)關(guān)風(fēng)格可能是大多數(shù)微服務(wù)實(shí)現(xiàn)里最被普遍采用的形式。
消息代理風(fēng)格
微服務(wù)可以與異步消息場(chǎng)景集成,比如單向的請(qǐng)求和使用隊(duì)列或者主題的發(fā)布訂閱消息機(jī)制。某個(gè)微服務(wù)可以是一個(gè)消息的制造者,它能將消息異步的發(fā)送到一個(gè)隊(duì)列或者主題里面。消費(fèi)型的微服務(wù)可以消費(fèi)隊(duì)列或者主題里來(lái)的消息。這種方式將消息的制造者和消費(fèi)者解耦,而且中間的消息代理會(huì)緩存消息直到消費(fèi)者處理它們。 制造消息的微服務(wù)對(duì)消費(fèi)消息的微服務(wù)完全未知。
生產(chǎn)者與消費(fèi)者直接的通訊由消息代理來(lái)完成,基于的是異步消息標(biāo)準(zhǔn), 比如AMQP、MQTT,等等。
去中心化的數(shù)據(jù)管理
在單體架構(gòu)中,應(yīng)用將數(shù)據(jù)存在一個(gè)集中化的數(shù)據(jù)庫(kù)中來(lái)實(shí)現(xiàn)各種的功能和業(yè)務(wù)能力。
在微服務(wù)架構(gòu)里,功能是跨多個(gè)微服務(wù)來(lái)提供的,這樣一來(lái),如果我們繼續(xù)使用集中化的數(shù)據(jù)庫(kù),那么微服務(wù)之間就不是互相獨(dú)立了(例如數(shù)據(jù)庫(kù)的某個(gè)schema為了某個(gè)服務(wù)要更改,那么極有可能會(huì)破壞其他的服務(wù))。 因此每個(gè)微服務(wù)必須有自己的數(shù)據(jù)庫(kù)。
要實(shí)現(xiàn)微服務(wù)架構(gòu)下的去中心化數(shù)據(jù)庫(kù)管理有如下幾個(gè)核心關(guān)注點(diǎn):
每個(gè)微服務(wù)都有一個(gè)私有的數(shù)據(jù)庫(kù), 存放的數(shù)據(jù)用來(lái)實(shí)現(xiàn)它所要提供的業(yè)務(wù)功能;
一個(gè)特定的微服務(wù)自己能訪問(wèn)自己的私有專(zhuān)用的數(shù)據(jù)庫(kù),而不能直接訪問(wèn)其他微服務(wù)的數(shù)據(jù)庫(kù);
在某些業(yè)務(wù)場(chǎng)景下,為了事務(wù)性要求你可能需要一次更新多個(gè)數(shù)據(jù)庫(kù)。在這種情況下,其他微服務(wù)的數(shù)據(jù)庫(kù)更新應(yīng)該通過(guò)它的API調(diào)用來(lái)完成(不允許直接訪問(wèn)它的數(shù)據(jù)庫(kù))。
去中心化的數(shù)據(jù)管理讓你可以得到完全解耦的數(shù)據(jù)庫(kù), 并且也有了自由選擇各種數(shù)據(jù)庫(kù)技術(shù)的能力(比如SQL 或者NOSQL,每個(gè)服務(wù)都可以有不同的數(shù)據(jù)庫(kù)管理系統(tǒng))。 但是, 對(duì)于復(fù)雜的涉及多個(gè)微服務(wù)的事務(wù)型應(yīng)用場(chǎng)景下,事務(wù)操作應(yīng)該使用各個(gè)微服務(wù)提供的API實(shí)現(xiàn),具體邏輯應(yīng)該在客戶(hù)端或者中間層(網(wǎng)關(guān))中實(shí)現(xiàn)。
去中心化治理
微服務(wù)架構(gòu)適用微服務(wù)治理。
總的來(lái)說(shuō),“治理”的意思是建立和實(shí)施“如何讓人員和解決方案為了組織目標(biāo)而一起工作”。在SOA的上下文中,SOA治理指導(dǎo)可重用服務(wù)的開(kāi)發(fā),指導(dǎo)服務(wù)該如何設(shè)計(jì)和開(kāi)發(fā),以及服務(wù)如何隨時(shí)間演進(jìn)。它在服務(wù)的提供者與服務(wù)消費(fèi)者之間建立協(xié)議,告訴消費(fèi)者它們可以期望得到什么;告訴提供者它們有義務(wù)提供什么。在SOA治理中,有兩種普通采用的治理模型:
設(shè)計(jì)時(shí)治理——定義和控制服務(wù)的生成,設(shè)計(jì)以及服務(wù)策略的實(shí)現(xiàn);
運(yùn)行時(shí)治理——在運(yùn)行時(shí)實(shí)施服務(wù)策略的能力。
那么,微服務(wù)上下文中的治理到底是什么意思?在微服務(wù)架構(gòu)下,服務(wù)是以完全獨(dú)立解耦的方式構(gòu)建的,用的技術(shù)棧可以完全不同。因此,定義一個(gè)通用的服務(wù)設(shè)計(jì)和開(kāi)發(fā)標(biāo)準(zhǔn)沒(méi)有太大必要。 我們可以將微服務(wù)場(chǎng)景下的去中心化的治理能力總結(jié)如下:
在微服務(wù)架構(gòu)下, 沒(méi)有必要擁有一個(gè)中心化的設(shè)計(jì)時(shí)治理;
微服務(wù)可以自己決策自己的設(shè)計(jì)實(shí)現(xiàn);
微服務(wù)架構(gòu)可以共享通用/可重用的服務(wù);
某些運(yùn)行時(shí)治理, 比如SLA、限流、監(jiān)控、通用的安全需求以及服務(wù)發(fā)現(xiàn)可以在API網(wǎng)關(guān)級(jí)別實(shí)現(xiàn)。
服務(wù)注冊(cè)與服務(wù)發(fā)現(xiàn)
在微服務(wù)架構(gòu)下, 你需要管理的微服務(wù)數(shù)量相當(dāng)之高。而且,由于微服務(wù)本身的快速敏捷的開(kāi)發(fā)部署特性,它們的運(yùn)行地點(diǎn)會(huì)動(dòng)態(tài)變化。因此,你需要能夠在運(yùn)行時(shí)找到一個(gè)微服務(wù)運(yùn)行的位置。這個(gè)問(wèn)題的解決方案是使用一個(gè)服務(wù)注冊(cè)表。
服務(wù)注冊(cè)表
服務(wù)注冊(cè)表保持微服務(wù)實(shí)例以及它們的位置。微服務(wù)實(shí)例在服務(wù)啟動(dòng)時(shí)在注冊(cè)表里面注冊(cè),在關(guān)閉時(shí)注銷(xiāo)。消費(fèi)者可以通過(guò)注冊(cè)表找到可用的微服務(wù)以及它們的位置。
服務(wù)發(fā)現(xiàn)
要找到可用的微服務(wù)以及它們的位置,我們需要有一個(gè)服務(wù)發(fā)現(xiàn)機(jī)制。 有2種服務(wù)發(fā)現(xiàn)機(jī)制,客戶(hù)端發(fā)現(xiàn)和服務(wù)端發(fā)現(xiàn)。
客戶(hù)端發(fā)現(xiàn)——這種方式下,客戶(hù)端或者API-GW通過(guò)查詢(xún)服務(wù)注冊(cè)表來(lái)得到服務(wù)實(shí)例的位置。
這里,客戶(hù)端/API-GW通過(guò)調(diào)用服務(wù)注冊(cè)組件來(lái)實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)邏輯。
服務(wù)端發(fā)現(xiàn)——這種方式下,客戶(hù)端/API-GW向運(yùn)行在某個(gè)公知位置的組件發(fā)送請(qǐng)求(例如負(fù)載均衡器)。 這個(gè)組件調(diào)用服務(wù)注冊(cè)表然后得到這個(gè)微服務(wù)的絕對(duì)位置。
微服務(wù)部署方案如Kubernetes提供的就是服務(wù)端解決方案。
部署
提到微服務(wù)架構(gòu)時(shí),微服務(wù)的部署扮演著一個(gè)核心角色而且有如下核心要求:
有能力在不依賴(lài)其他服務(wù)的情況下部署/撤銷(xiāo);
能在每個(gè)微服務(wù)的級(jí)別進(jìn)行擴(kuò)展(某個(gè)服務(wù)可能比其他服務(wù)有更多的流量);
快速構(gòu)建和部署微服務(wù);
一個(gè)微服務(wù)的失效不能影響其他服務(wù)。
Docker(一個(gè)開(kāi)源引擎可以讓開(kāi)發(fā)者和系統(tǒng)管理員部署自包含的應(yīng)用容器到Linux環(huán)境中)提供了一個(gè)滿(mǎn)足上述需求的部署方案。里面涉及的核心步驟有:
將微服務(wù)打包為Docker鏡像;
將每個(gè)服務(wù)實(shí)例部署為容器;
通過(guò)改變?nèi)萜鞯臄?shù)量來(lái)實(shí)現(xiàn)服務(wù)的擴(kuò)展;
使用Docker容器時(shí)服務(wù)的構(gòu)建,部署和啟動(dòng)都相當(dāng)快(通常比虛擬機(jī)快的多)。
Kubernetes擴(kuò)展了Docker的能力:可以像管理一個(gè)系統(tǒng)那樣管理一個(gè)Linux容器的集群,跨主機(jī)運(yùn)行和管理Docker容器, 提供容器的多地部署、服務(wù)發(fā)現(xiàn)和復(fù)制控制。正如你看到的,這些特性中的大多數(shù)在微服務(wù)場(chǎng)景下也是特別核心的。因此使用Kubernetes(基于Docker)來(lái)做微服務(wù)部署已成為一種相當(dāng)強(qiáng)大的方法,特別對(duì)于大型的微服務(wù)部署而言。
每個(gè)微服務(wù)實(shí)例部署為一個(gè)容器,每個(gè)主機(jī)上跑了兩個(gè)容器。 在任意一臺(tái)主機(jī)上你都可以指定跑的容器的數(shù)量。
安全
微服務(wù)安全是在實(shí)際場(chǎng)景中應(yīng)用微服務(wù)的一個(gè)普遍要求。在講微服務(wù)安全之前,我們先看看在單體應(yīng)用下我們通常是如何實(shí)現(xiàn)安全的。
在一個(gè)單體應(yīng)用中,安全主要關(guān)心‘調(diào)用者是誰(shuí)’, ‘調(diào)用者能干什么’, 以及‘我們?nèi)绾蝹鞑ミ@個(gè)信息’;
這通常在一個(gè)公用的安全組件上實(shí)現(xiàn),它部署在請(qǐng)求處理鏈的首部,通過(guò)一個(gè)底層的用戶(hù)數(shù)據(jù)庫(kù)來(lái)填充必要的信息。
這樣, 我們可以將這個(gè)模型應(yīng)用到微服務(wù)架構(gòu)中嗎? 可以,但是要求在每個(gè)微服務(wù)級(jí)別實(shí)現(xiàn)一個(gè)安全組件,查詢(xún)中心共享的用戶(hù)庫(kù)來(lái)獲得必要的信息。這是一個(gè)非常繁瑣的方式來(lái)解決微服務(wù)場(chǎng)景下的安全問(wèn)題。我們可以利用廣泛使用的API-安全標(biāo)準(zhǔn)來(lái)做,例如OAuth2、OpeniD Connect, 這是解決微服務(wù)安全問(wèn)題的更好方式。在我們深入之前,我先總結(jié)一下每種標(biāo)準(zhǔn)的目的以及我們?cè)撊绾问褂谩?/div>
OAuth2——是一個(gè)訪問(wèn)授權(quán)協(xié)議??蛻?hù)端相授權(quán)服務(wù)器認(rèn)證得到一個(gè)‘訪問(wèn)令牌’,訪問(wèn)令牌里面不包含關(guān)于用戶(hù)或者客戶(hù)端的任何信息。它僅僅包含一個(gè)對(duì)客戶(hù)信息的應(yīng)用,而且僅僅能被授權(quán)服務(wù)器查詢(xún)。因此,也常被稱(chēng)為’引用型令牌,即使在公網(wǎng)、互聯(lián)網(wǎng)上使用也是安全的。
OpenID Connect與OAuth2行為類(lèi)似,但是除了訪問(wèn)令牌之外,授權(quán)訪問(wèn)也會(huì)發(fā)出一個(gè)ID令牌,其中包含有用戶(hù)的信息。這常通過(guò)JWT(JSON WEB TOKEN)實(shí)現(xiàn),由授權(quán)服務(wù)器簽名。這樣保證了授權(quán)服務(wù)器與客戶(hù)端的互相信任。JWT令牌因此也稱(chēng)為“值型令牌”,因?yàn)樗锩姘杏脩?hù)信息,通過(guò)不適于在公共網(wǎng)絡(luò)使用。
現(xiàn)在,我們看看如何在零售的案例中使用這些安全標(biāo)準(zhǔn)來(lái)實(shí)現(xiàn)微服務(wù)的安全:
實(shí)現(xiàn)微服務(wù)安全時(shí)有如下關(guān)雎步驟:
將認(rèn)證交給OAuth2和OpenID Connect服務(wù)器(授權(quán)服務(wù)器),如此一來(lái)用戶(hù)只要有權(quán)使用這些數(shù)據(jù)微服務(wù)就可以提供訪問(wèn);
使用API-GW方式,對(duì)于所有的客戶(hù)請(qǐng)求有單一入口;
客戶(hù)連接到授權(quán)服務(wù)器得到訪問(wèn)令牌(引用型令牌),然后將令牌和請(qǐng)求一起發(fā)給API-GW;
網(wǎng)關(guān)做令牌翻譯 – API-GW提出訪問(wèn)令牌,發(fā)送到授權(quán)服務(wù)器得到JWT(值型令牌);
網(wǎng)關(guān)將JWT和請(qǐng)求一起發(fā)給微服務(wù)層;
JWT含有必要的信息來(lái)做用戶(hù)會(huì)話(huà)保存等。如果每個(gè)服務(wù)都可以理解JSON web token,那么你就擁有了可以分發(fā)身份信息到整個(gè)系統(tǒng)中的機(jī)制;
在每個(gè)微服務(wù)層,我們可以有一個(gè)組件來(lái)處理JWT,這個(gè)實(shí)現(xiàn)通常非常簡(jiǎn)單。
事務(wù)
如何在微服務(wù)中支持事務(wù)? 實(shí)際上, 跨多個(gè)微服務(wù)來(lái)實(shí)現(xiàn)分布式事務(wù)是一個(gè)相當(dāng)復(fù)雜的工作。微服務(wù)架構(gòu)本身鼓勵(lì)的是服務(wù)之間非事務(wù)的協(xié)調(diào)。
這個(gè)意思是基于每個(gè)服務(wù)完全自包含且單一責(zé)任的原則。需要跨多個(gè)服務(wù)之間的分布式事務(wù)通常是微服務(wù)設(shè)計(jì)上的缺陷,通常應(yīng)該通過(guò)重構(gòu)微服務(wù)的范圍來(lái)解決。盡管如此,如果必須要有這種跨服務(wù)的分布式事務(wù), 這種場(chǎng)景可以通過(guò)在每個(gè)微服務(wù)層引入‘修正操作’來(lái)實(shí)現(xiàn)。 核心思想是,某個(gè)特定的微服務(wù)是根據(jù)單一責(zé)任設(shè)計(jì)的,如果它無(wú)法完成某個(gè)特定操作時(shí),我們可以認(rèn)為整個(gè)微服務(wù)都失敗了。 這時(shí)上游其他的微服務(wù)就要起到用它們各自的修正操作來(lái)回滾。
為“失效”設(shè)計(jì)
微服務(wù)架構(gòu)引入了一組離散的服務(wù)集合,與單體架構(gòu)相比,這增加了在每一個(gè)微服務(wù)級(jí)別失敗的可能性。一個(gè)微服務(wù)的失效可能由于網(wǎng)絡(luò)問(wèn)題,底層資源不可用等等因素。單個(gè)微服務(wù)的不可用或者沒(méi)響應(yīng)不應(yīng)該讓整個(gè)應(yīng)用失敗。這樣,微服務(wù)應(yīng)該是容錯(cuò)的,可能的話(huà)有能力自動(dòng)恢復(fù),客戶(hù)端也要能優(yōu)雅處理。
另外,因?yàn)榉?wù)可能隨時(shí)失敗,快速發(fā)現(xiàn)失敗(實(shí)時(shí)監(jiān)控),可能的話(huà)自動(dòng)恢復(fù)服務(wù)也十分重要。
在微服務(wù)場(chǎng)景下,有幾種處理錯(cuò)誤的通用模式:
鏈路斷開(kāi)器
當(dāng)你對(duì)一個(gè)微服務(wù)做外部調(diào)用時(shí),你可以給每一個(gè)調(diào)用配置一個(gè)錯(cuò)誤監(jiān)控組件。當(dāng)失敗達(dá)到某個(gè)閾值時(shí),組件會(huì)停止對(duì)那個(gè)服務(wù)的調(diào)用(斷開(kāi)鏈路)。 在特定數(shù)目的請(qǐng)求是open狀態(tài)之后(可以自己定義),將鏈路閉合回去。
這個(gè)模式對(duì)避免無(wú)謂的資源消耗特別有用, 請(qǐng)求因?yàn)槌瑫r(shí)被推遲,也讓我們有機(jī)會(huì)監(jiān)控系統(tǒng)狀態(tài)(基于活躍的open的鏈路狀態(tài))。
隔離墻
由于應(yīng)用由相當(dāng)數(shù)量的微服務(wù)組成,應(yīng)用的某一部分的微服務(wù)失效不應(yīng)影響應(yīng)用的其他部分。隔離墻模式就是將應(yīng)用的不同部分隔離,這樣一來(lái),應(yīng)用的某個(gè)部分的某個(gè)服務(wù)的失敗不會(huì)影響其他服務(wù)。
超時(shí)
超時(shí)模型是這樣一種機(jī)制,它允許在當(dāng)你覺(jué)得服務(wù)的響應(yīng)不會(huì)回來(lái)時(shí)停止等待。這樣你就可以配置等待的時(shí)間間隔。
那么,我們應(yīng)該在服務(wù)中哪里使用及如何使用這些模式呢? 在大多數(shù)時(shí)候,大多數(shù)的模式適用于網(wǎng)關(guān)層。也就是說(shuō)當(dāng)服務(wù)不可用或者沒(méi)響應(yīng)時(shí),我們可以在網(wǎng)關(guān)級(jí)別決定使用鏈路斷開(kāi)或者超時(shí)的模式來(lái)給服務(wù)發(fā)請(qǐng)求。同樣的, 在網(wǎng)關(guān)級(jí)別實(shí)現(xiàn)隔離墻的模式也十分重要,因?yàn)樗撬姓?qǐng)求的唯一入口,所以某個(gè)服務(wù)的失敗不會(huì)影響其他服務(wù)的調(diào)用。
另外,網(wǎng)關(guān)也可以用作我們監(jiān)控每個(gè)服務(wù)狀態(tài)的中心點(diǎn),因?yàn)槊總€(gè)服務(wù)都是通過(guò)網(wǎng)關(guān)來(lái)調(diào)用的。
微服務(wù)、企業(yè)級(jí)集成、 API管理以及其他
我們已經(jīng)討論了微服務(wù)架構(gòu)的各種特性,以及如何在現(xiàn)代的企業(yè)IT里實(shí)現(xiàn)它們。盡管如此,我們必須知道微服務(wù)不是包治百病的靈丹妙藥。盲目的吸收流行概念并不會(huì)真正解決企業(yè)it的實(shí)際問(wèn)題。你通篇讀下來(lái)會(huì)覺(jué)得,微服務(wù)確實(shí)有很多優(yōu)點(diǎn)我們應(yīng)該利用。但是,我們也必須意識(shí)到使用微服務(wù)來(lái)解決所有的IT問(wèn)題是不切實(shí)際的。 例如,微服務(wù)架構(gòu)推崇去除作為中央總線(xiàn)的ESB,但是在實(shí)際的IT場(chǎng)景下,我們已經(jīng)有相當(dāng)數(shù)量的線(xiàn)上應(yīng)用和服務(wù)并不是基于微服務(wù)的。因此,為了集成它們,我們必須使用某種集成總線(xiàn)。所以, 理想情況是,一個(gè)融合了微服務(wù)和其他企業(yè)架構(gòu)理念(例如集成)的方法顯然更切合實(shí)際。
注:本文轉(zhuǎn)自微信公眾號(hào):Docker
第三十四屆CIO班招生
北達(dá)軟EXIN網(wǎng)絡(luò)空間與IT安全基礎(chǔ)認(rèn)證培訓(xùn)
北達(dá)軟EXIN DevOps Professional認(rèn)證培訓(xùn)
責(zé)編:yangjun
免責(zé)聲明:本網(wǎng)站(http://www.www.gypb.net/)內(nèi)容主要來(lái)自原創(chuàng)、合作媒體供稿和第三方投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請(qǐng)進(jìn)一步核實(shí),并對(duì)任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對(duì)有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。
本網(wǎng)站刊載的所有內(nèi)容(包括但不僅限文字、圖片、LOGO、音頻、視頻、軟件、程序等)版權(quán)歸原作者所有。任何單位或個(gè)人認(rèn)為本網(wǎng)站中的內(nèi)容可能涉嫌侵犯其知識(shí)產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),請(qǐng)及時(shí)通知本站,予以刪除。