微服務是一種架構風格,一個大型複雜軟件應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是鬆耦合的。每一個微服務僅關注於完成一件任務並很好地完成該任務。在全部狀況下,每一個任務表明着一個小的業務能力。javascript
微服務的概念源於2014年3月Martin Fowler所寫的一篇文章「Microservices」(martinfowler.com/articles/mi…)。html
儘管「微服務」這種架構風格沒有精確的定義,但其具備一些共同的特性,如圍繞業務能力組織服務、自動化部署、智能端點、對語言及數據的「去集中化」控制等等。微服務架構的思考是從與總體應用對比而產生的。java
一般,在一家公司隨着業務需求的增加爲逐步發展(天然增加)的過程當中,前期每每是以單塊架構的方式來組織系統的。由於對於軟件的初期構建來講,單塊架構的方式是最容易且最高效的。可是若干年(甚至是幾個月)後,受限於前期既有單塊軟件系統內部耦合性,再向該系統加新功能變得愈來愈艱難。數據庫
企業應用,由於服務於衆多業務需求,所以會有些特定的軟件應用提供許多功能,而通常慣例是把這些功能都堆在單個單片應用中。例如,ERP,CRM和其餘各類軟件系統被規劃構建爲具備數百個功能的總體。這種帶坑應用一經部署,在日後的故障排除、擴展和升級場景中就是一場接一場的惡夢了。express
面向服務架構(SOA)旨在經過引入「服務」的概念來克服以上的限制,「服務」是從應用程序提供的相似功能中提取出來的聚合和分組。所以,使用SOA,軟件應用程序就會被設計爲「粗粒度」服務的組合。然而,SOA中服務的範圍很是普遍,這又引出了複雜而龐大的服務與一大堆操做(功能)以及複雜無比的消息格式和標準(如WS *標準)。npm
多數狀況下,SOA中的服務彼此獨立,只不過它們與全部其餘服務一塊兒部署在相同的運行時間裏(只需考慮將部署到同一個Tomcat實例中的多個Web應用)。和單片軟件應用相似,這些服務經過積累各類功而具備隨時間推移的習慣。圖1是一個很是好的一個單片架構的例子,顯示了包括多個服務的零售軟件應用,全部這些服務都能部署到同一應用程序。編程
說了那麼多,你們是否是有點不明因此?我總結了一些重點,如下就是基於單快軟件架構的應用程序的一些特性概括:服務器
面向微服務的架構擁有一些特質。任意規模的大中型公司若是想讓自身IT系統保持彈性,並但願隨時均可以對系統規模進行伸縮的話,一定會對這些特質趨之若鶩。網絡
微服務架構(MSA)的基礎是將單片應用做爲一套小型和獨立服務來開發,這些服務都在本身的空間獨立開發、部署和運行。在微服務體系結構的大多數定義中,它廣泛被解釋爲將巨大的可用服務隔離成一套獨立服務的過程。架構
可是面向微服務的架構並是不工程的聖盃。彈性、可組合性以及靈活性是面向微服務架構設計的關鍵原則。若是不遵照你將失去一個完美的解決方案,並最終在單塊應用分拆多臺機器上時遇到大量的問題。
事無絕對,微服務也會有幾下問題:
通常來講,咱們能夠肯定一下設計原則:
如今咱們看幾項關鍵的好處。
維基百科將彈性定義爲系統處理變化的能力
。我對彈性的理解是在問題被解決後系統從異常狀態或者壓力期中優雅的恢復,同時又不會影響系統性能的能力。
這雖然看上去很簡單,可是在構建面向微服務軟件的時候,問題源會因爲系統的分佈式特性而被放大,有時很難防止全部的異常狀況。
彈性是從錯誤中優雅回覆的能力。可是一樣也爲系統帶來了新的複雜度:若是一個微服務出現了問題,咱們可否防止系統的常規故障?理想狀況下,咱們應該以這樣一種方式來構建服務:僅對服務響應進行降級而非讓系統出現常規故障,即便這樣作也並不容易。
現在各大公司的一個通病是系統存在可伸縮性的問題。一般,這些問題並不涉及應用的每一層次或全部子系統。每每只有個別子系統或服務會明顯鰻魚其他部分,一旦沒有處理好容量問題就會致使整個應用發生故障。
下圖描述瞭如何對微服務進行擴展(擴展成兩個郵件服務)的,同時又不牽扯系統的其他部分:
軟件世界每幾個月就出更新系統。新語言進入業界成爲某類系統事實標準的節奏片刻位停。
那麼,將這些語言的技術棧結合起來會有什麼問題嗎?平心而論,這是一個優點:咱們能夠選擇合適的工具來作相對應的工做
。只要待集成的技術是標準化的,面向微服務的架構即可以幫你實現這一點。
下圖展現了微服務是如何隱藏數據的存取邏輯的,兩個服務在存取數據方面共用同一個通訊點,從而能很好地互相解耦:
Node.js 並非一門適合執行並行任務的語言。針對那些處於壓力之下的微服務來講,咱們能夠選擇一門更適合的語言來進行開發,好比 Erlang,從而能夠以一種更加優雅的方式來管理併發。
可替換性是指替換系統中某個組件而不影響系統行爲的一種能力。 當咱們在討論軟件的時候,可替換性每每是與低耦合密不可分的。在編寫微服務的時候不能講內部邏輯暴露給調用服務,服務實現對客戶端來講是透明的,客戶端只須要了解的只有接口。
全部服務應該都是獨立的,他們經過接口進行交互。除了協定確認接口這一環節以外,不一樣的工程師團隊能夠在無需交流的狀況下完成對服務的開發。
微服務應當易於部署,緣由以下:
面向微服務架構(SOA)與微服務架構很是想象的。那麼他們之間的區別究竟是什麼呢?
微服務是細粒度的 SOA 組件。換句話說,某個單個SOA組件能夠拆成多個微服務,而這些微服務經過分工協做,能夠提供與原SOA組件相同級別的功能,以下圖:
微服務與 SOA 之間的另外一個不一樣之處是服務互聯和編寫服務時所使用的技術。而另外一方面,微服務推崇執行的標準(例如 HTTP)倒是人民普遍瞭解並共同使用的。咱們能夠經過選擇合適的語言或者工做來構建某個組件(微服務),進而得到 技術多樣性 提到的關鍵好處。
除了技術棧和服務規模以外,在SOA於微服務之間還有一個更大的區別:領域模型。在一個機遇微服務的軟件中,每一個微服務應該在本地存儲自身管理數據,並將領域模型分別隔離到單個服務中。而在面向SOA的軟件中,數據每每存儲在單個大型的數據庫中,服務之間會共享領域模型。
Node.js 是一門新型技術棧,對於不少人而言,它僅僅只是一個趨勢,離做爲解決問題的實際工具還欠點火候。
讓咱們來看重點看看 Node.js 。 Node.js 是用來構建面向微服務的架構的絕佳選擇,緣由以下:
API 聚合是一項用於將不一樣功能(插件、方法等)組合成一個接口的高級技術。例子:
const express = require('express');
const app = express();
app.get('/sayhello', function (req, res) {
res.send('Hello World!');
});
app.get('/saygoodbye', function(req, res) {
res.send('Bye bye!');
}
const server = app.listen(3000, function () {
let host = server.address().address;
let port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
複製代碼
前面的例子使用了 Express, 這是一個在Node.js技術棧中廣爲流行的 Web 框架。該框架一樣也是圍繞API聚合來構建的。
讓咱們來看下 第四行和第七行。在這些代碼裏,開發者註冊了兩個方法。當某人以 GET 請求的方式分別請求 URL:/sayhello 和 /saygoodbye 時,這兩個對應的方法將被執行。在該例子中,該接口就是一個在3000端口上監聽的app。
在本文中你瞭解一些面向微服務的架構的關鍵好處,好比能夠爲相應的服務選擇合適的語言(語言多樣性);以及一些可能會加劇咱們負擔的誤區,好比如何有面向微服務的架構分佈式特性而帶來的運維方面開銷。
最後,咱們討論了 Node.js 是用來構建微服務的強大工具,以及如何經過利用像 API 聚合這樣的技術來從 JavaScript 獲益,從而構建出高質量的軟件組件。