Lucas+Carlson++Charles
當(dāng)今的應(yīng)用程序需要不斷地修改、擴(kuò)展和更新,以滿足不斷變化的業(yè)務(wù)需求。微服務(wù)讓您輕松可靠的應(yīng)對這些變化
我現(xiàn)在還在用成百上千行的老C++應(yīng)用程序。哦,我是在騙人嗎?這是數(shù)百萬行的Vectran,是IBM在上世紀(jì)70年代開發(fā)的存在時間很短的一個FORTRAN語言變種。但它還在用,對嗎?
除非它自己出問題。每當(dāng)有人想添加功能時,就會出問題。即使想要修復(fù)漏洞,也會產(chǎn)生更多的漏洞。但如果不碰它,它就會一直工作下去。
問題在于創(chuàng)新需要敏捷和速度。所有那些從未擔(dān)心過Y2K的炫酷公司,都不再使用老舊軟件。投資者要求的是創(chuàng)新突破,要讓客戶們趨之若鶩。
好消息是,您不是單打獨(dú)斗。信不信由您,即使是最炫酷的公司也面臨類似的問題。Netflix、eBay、亞馬遜、推特、PayPal,還有很多公司都還沒有開始采用架構(gòu)很容易擴(kuò)展,且快速敏捷的應(yīng)用程序。
2006年,eBay在SD論壇上做了一次報告,介紹了其體系結(jié)構(gòu)。公司承認(rèn),開發(fā)了整段的330萬行C++ ISAPI DLL,編譯成一個150MB大小的二進(jìn)制文件。eBay開發(fā)人員對每一類方法的數(shù)量進(jìn)行了編譯器限制,預(yù)計(jì)每年可以增加1200個新功能,其可用性高達(dá)99.94%。
eBay是怎樣克服其負(fù)擔(dān)過重的老架構(gòu)的?PayPal、推特、亞馬遜和Netflix也是這樣做的:廢掉了他們整段式的應(yīng)用程序。他們使用微服務(wù)重新設(shè)計(jì)自己的基礎(chǔ)設(shè)施,這一技術(shù)把大型應(yīng)用程序分解成能夠橫向擴(kuò)展的輕量級應(yīng)用程序。
打破磐石
微服務(wù)把功能分解成通過REST API松耦合在一起的獨(dú)立的應(yīng)用程序。例如,eBay開發(fā)了不同的java servlet應(yīng)用程序,用于處理用戶、項(xiàng)目、賬戶、反饋、交易,以及2006年以來就在使用的70多個其他要素。這些邏輯功能應(yīng)用程序中的每一個現(xiàn)在都被認(rèn)為是一種微服務(wù)。現(xiàn)在,eBay大概運(yùn)行著數(shù)百個微服務(wù)。
這些微服務(wù)每一個都是獨(dú)立的。它們不共享數(shù)據(jù)層。每個都有自己的數(shù)據(jù)庫和負(fù)載均衡器。隔離是微服務(wù)架構(gòu)的關(guān)鍵因素;不同的微服務(wù)需要不同的擴(kuò)展技術(shù)。例如,一些微服務(wù)可能使用關(guān)系型數(shù)據(jù)庫,而其他的可能使用NoSQL數(shù)據(jù)庫。
微服務(wù)的常見問題
隨著開發(fā)人員和管理人員涉足微服務(wù),很多同樣的問題反復(fù)出現(xiàn)。下面列出了一些最常見的問題及其回答。
如果每一服務(wù)都應(yīng)該有自己的數(shù)據(jù)庫,那么怎樣把不同數(shù)據(jù)庫之間的數(shù)據(jù)關(guān)聯(lián)起來呢?
人們在開發(fā)微服務(wù)架構(gòu)時遇到的第一個問題是,怎樣釋放連接表。如果您要開發(fā)的應(yīng)用程序比本文中簡單的博客示例更復(fù)雜,那么這個問題就變得非常明顯了。
簡單的解決方案是使用應(yīng)用程序級連接而不是數(shù)據(jù)庫級連接。這往往導(dǎo)致比單條SQL命令更多的數(shù)據(jù)庫查詢,但可以在微服務(wù)層里采用高速緩存來緩解這個問題。畢竟,每個微服務(wù)都可以有自己的高速緩存技術(shù)。從長遠(yuǎn)來看,這種方法不如直接連接數(shù)據(jù)庫簡單,但它的可擴(kuò)展性肯定要好一些。
一個更復(fù)雜的解決方案是您微服務(wù)架構(gòu)中置入一個事件驅(qū)動的發(fā)布-訂閱消息總線。消息總線支持各種微服務(wù)與應(yīng)用程序中發(fā)生的事件進(jìn)行通信。這種架構(gòu)是開發(fā)非常豐富和復(fù)雜微服務(wù)應(yīng)用的基礎(chǔ),因?yàn)椴槐卦僖揽侩S時馬上能用的服務(wù)API。
怎樣對微服務(wù)進(jìn)行流程編排?
運(yùn)行數(shù)十個或者數(shù)百個小的微服務(wù)來代替一個大的整段應(yīng)用程序的運(yùn)營開銷非常驚人。毫無疑問,持續(xù)跟蹤所有相互關(guān)聯(lián)的微服務(wù)會增加復(fù)雜性。好在這些問題的流程編排新解決方案變得越來越穩(wěn)定和可靠。
無論是Kubernetes、Mesos、Swarm,還是Nomad,這些流程編排工具基本上都做同樣的事情:他們讓您以聲明的方式來構(gòu)建DevOps平臺。
傳統(tǒng)的DevOps工具非常適合啟動、管理和監(jiān)控各個應(yīng)用程序,但DevOps工具和流程編排服務(wù)之間的區(qū)別在于流程編排服務(wù)是用于管理復(fù)雜的微服務(wù)環(huán)境,在這種環(huán)境中,運(yùn)行的服務(wù)之間會相互關(guān)聯(lián)。
其基礎(chǔ)是,所有這些流程編排工具都只是對消息總線進(jìn)行作業(yè)調(diào)度。如果您已經(jīng)在架構(gòu)中使用了消息總線,那么您可能希望在消息總線之上開發(fā)流程編排引擎。
怎樣分解現(xiàn)有的應(yīng)用程序?
您可能沒有奢望使用微服務(wù)架構(gòu)從頭開始重建您的應(yīng)用程序。關(guān)鍵是您不需要。
如果正在使用的老應(yīng)用程序仍然非常重要,您想把它分解成微服務(wù),但是希望逐步進(jìn)行,那么可以從構(gòu)建仿微服務(wù)開始。
仿微服務(wù)與普通的微服務(wù)基本一樣,只是數(shù)據(jù)存儲還沒有與應(yīng)用程序的其它部分相隔離。例如,如果有一個復(fù)雜的定制博客應(yīng)用程序,您可以創(chuàng)建一個仿Article微服務(wù),這是一個獨(dú)立的應(yīng)用程序,其唯一的功能就是完成Article REST API。然而,底層Article數(shù)據(jù)庫仍然在同一個大型關(guān)系型數(shù)據(jù)庫模型中。這樣,數(shù)據(jù)就不會被復(fù)制了。
最終,當(dāng)有足夠多的仿微服務(wù)被搭建出來后,您可以把數(shù)據(jù)存儲分解成一個個獨(dú)立的單元。
微服務(wù)不就是SOA(面向服務(wù)的架構(gòu))嗎?
微服務(wù)與SOA表面看起來大同小異,但存在明顯的不同。表面上,SOA使用的是SOAP和XML-RPC,而微服務(wù)與JSON相關(guān)聯(lián)。但在某些方面,API格式更為美觀。
同樣的,SOA使用企業(yè)服務(wù)總線,而微服務(wù)使用更輕便的發(fā)布-訂閱服務(wù)總線。同樣道理,原理是相似的,只是更輕便一些。
Bob Rhubart說過,“微服務(wù)必須獨(dú)立部署,而SOA服務(wù)往往需要整段的部署”,這是很能說明問題的。
微服務(wù)的理念在根本上就是要廢掉整段式的應(yīng)用程序和數(shù)據(jù)庫。它是要搭建高度分布的、自治的、橫向可擴(kuò)展的應(yīng)用程序。微服務(wù)的標(biāo)志是輕量級的組件和獨(dú)立可部署特性。輕量級API。輕量級服務(wù)總線。輕量級數(shù)據(jù)存儲。
后臺進(jìn)程會怎樣?
隨著大數(shù)據(jù)分析的興起,長時間運(yùn)行的后臺進(jìn)程變得越來越普遍。幸運(yùn)的是,微服務(wù)非常適合這類問題。
如果您已經(jīng)在自己的應(yīng)用程序架構(gòu)中采用了發(fā)布-訂閱消息總線,那么后臺進(jìn)程只是另一個不需要端口綁定的微服務(wù)。它們可以通過訂閱消息總線連接到總線上,然后等待,直至事件被觸發(fā)。
通過這種方式,開發(fā)團(tuán)隊(duì)能夠更靈活地構(gòu)建應(yīng)用程序。如果是整段式的代碼,您就需要有一大幫人一起處理一大段代碼,工作起來總是相互掣肘。大段的代碼會越來越長,開發(fā)速度呈指數(shù)下降。而采用微服務(wù)架構(gòu),應(yīng)用程序是由小規(guī)模、分散開的開發(fā)團(tuán)隊(duì)搭建的,他們可以相互獨(dú)立地工作,修改微服務(wù)。這樣,很容易更新服務(wù),添加功能。軟件和開發(fā)過程都變得更加敏捷。
由于所有這些原因,微服務(wù)變得越來越受歡迎。但是每種架構(gòu)都有其優(yōu)點(diǎn)和缺點(diǎn)。微服務(wù)架構(gòu)也有一系列難以解決的新問題。
本文中,在介紹這一開發(fā)應(yīng)用程序的現(xiàn)代方法時,我們將探討微服務(wù)的優(yōu)缺點(diǎn)。然后我們將介紹怎樣構(gòu)建一個基于微服務(wù)的博客應(yīng)用程序來說明微服務(wù)實(shí)際是怎樣工作的。最后,我們將解決一些關(guān)于微服務(wù)最常見的問題,回答最關(guān)鍵的問題:您應(yīng)該使用微服務(wù)嗎?
最后一個問題的答案可能會讓您大吃一驚。
微服務(wù)的優(yōu)缺點(diǎn)
微服務(wù)的理念是將內(nèi)部架構(gòu)非常復(fù)雜的大規(guī)模整段式的應(yīng)用程序分解成更小的、獨(dú)立的、可擴(kuò)展應(yīng)用程序。例如,如果您是eBay,您可能希望“用戶反饋微服務(wù)”比“招標(biāo)微服務(wù)”更小,而且不復(fù)雜。
在考慮這個問題時,為什么首先要把這些功能構(gòu)建到一個應(yīng)用程序中呢?至少在理論上,您可以想象它們可以在獨(dú)立的應(yīng)用程序和數(shù)據(jù)單元中,不會有什么大問題。例如,如果平均拍賣收到兩份投標(biāo)書,但只有四分之一的銷售收到反饋,那么在任何時候,投標(biāo)服務(wù)至少比反饋應(yīng)用程序活躍八倍。
通過這種方式,把不同的功能組分隔成單獨(dú)的應(yīng)用程序就很有意義了。然而,能夠獨(dú)立構(gòu)建和擴(kuò)展您應(yīng)用程序的不同部分雖然是優(yōu)點(diǎn),但也隨之而來一系列的新問題——特別是記錄、監(jiān)控、測試和調(diào)試您分散的、松散耦合的新應(yīng)用程序。
如果有一個漏洞,應(yīng)該由其中的哪一個微服務(wù)負(fù)責(zé)呢?微服務(wù)之間的相互依存關(guān)系使得這一問題很難回答。微服務(wù)之間一般通過輕量級JSON REST API相互通信。與以前的XML-RPC和SOAP不同,REST接口趨于更松散的定義。這些輕量級的API更靈活,更容易擴(kuò)展,但它們也增加了一個需要監(jiān)視的新接口,這可能會產(chǎn)生中斷或者導(dǎo)致漏洞。
在過去整段式的應(yīng)用程序中,您可以在代碼中添加調(diào)試鉤子,并在邏輯上逐步遍歷每個執(zhí)行層以發(fā)現(xiàn)問題區(qū)域。當(dāng)您處理由幾十個甚至數(shù)百個不同的應(yīng)用程序構(gòu)成的網(wǎng)格,而且這些應(yīng)用程序通過松散定義的API互相進(jìn)行通信,此時,您就不能這么“奢侈”了。
盡管如此,經(jīng)過周密的計(jì)劃,您還是能克服這些困難的。目前,可供選擇的貨架式微服務(wù)調(diào)試工具還不多。您可能需要根據(jù)其他的局部的情況,把自己的解決方案拼接在一起。但是當(dāng)您圍繞微服務(wù)理念進(jìn)行開發(fā)時,實(shí)際是有隱藏的好處,例如與PaaS、Docker和Linux容器等新技術(shù)相結(jié)合等。
微服務(wù)、容器和PaaS
現(xiàn)在有一個常見的誤解,如果使用微服務(wù),就需要使用PaaS或者Linux容器,或者類似的東西。這根本不是真的。您可以使用沒有微服務(wù)的PaaS和Linux容器,也可以使用沒有PaaS或者Linux容器的微服務(wù)。他們互相都不需要對方。
但在很多方面,它們確實(shí)是相輔相成的。PaaS環(huán)境,無論是Heroku等公有云,還是Cloud Foundry或者OpenShift等私有云,都非常適合運(yùn)行很多較小的應(yīng)用程序。把330百萬行C++應(yīng)用程序?qū)氲絇aaS平臺的這類事情將不會再發(fā)生。
如果您把應(yīng)用程序分解成小段的應(yīng)用程序,每一段都是相對獨(dú)立的,自己能夠獨(dú)立擴(kuò)展,那么這些小段的應(yīng)用程序就非常適合在PaaS環(huán)境中運(yùn)行。
出于這一原因,考慮采用微服務(wù)架構(gòu)有助于加速您發(fā)展路線圖中其他技術(shù)的應(yīng)用。同樣的,Linux容器更適合小規(guī)模、無狀態(tài)應(yīng)用程序,而不是整段式的大規(guī)模應(yīng)用程序。
畢竟,虛擬機(jī)和Linux容器之間最大、最明顯的區(qū)別是缺少狀態(tài)。可以配置虛擬機(jī)使其保持狀態(tài)不變,而Linux容器架構(gòu)本質(zhì)上拋棄了與基本鏡像的任何差異。采用Linux容器,您可以在其中安裝有狀態(tài)文件夾,但容器本身不會改變——除非您確認(rèn)進(jìn)行更改。
微服務(wù)架構(gòu)的橫向擴(kuò)展理念促進(jìn)了無共享、無狀態(tài)應(yīng)用程序這一概念的發(fā)展。也就是說,它們不存儲或者修改底層文件系統(tǒng)。這就是為什么人們把微服務(wù)和Linux容器合起來使用的原因:它們都不保留狀態(tài)。
微服務(wù)為應(yīng)用程序開發(fā)提供了很好的方法——只要您清楚問題和缺點(diǎn)所在。這一技術(shù)趨勢今后會持續(xù)下去。通過這種技術(shù),很多技術(shù)大腕們解決了過去10年中應(yīng)用程序大規(guī)模增長的問題。
怎樣看待微服務(wù)應(yīng)用程序的開發(fā)
如果您以前從來沒有開發(fā)過微服務(wù)架構(gòu),那首先要改變思維方式。很多開發(fā)人員從數(shù)據(jù)庫布局開始應(yīng)用程序的設(shè)計(jì)。他們建立了大量的表,包括復(fù)雜的連接表。然后在數(shù)據(jù)庫基礎(chǔ)上構(gòu)建應(yīng)用程序邏輯。最后,把用戶體驗(yàn)放在應(yīng)用程序邏輯之上。這就像一個三層蛋糕一樣,這種構(gòu)建應(yīng)用程序的方法一開始時能很好地工作。
這種架構(gòu)的問題是,當(dāng)把新功能加到應(yīng)用程序中時,新表和連接表也被加到了數(shù)據(jù)庫中。然后,把新功能嫁接到現(xiàn)有代碼中。隨著時間的推移,這變成了一個巨大的“老鼠窩”。
開發(fā)微服務(wù)應(yīng)用程序最簡單的方法是從前端開始,向后工作。徹底轉(zhuǎn)變傳統(tǒng)的架構(gòu)方法。
為了說明這種逆向的方法,讓我們考慮一個簡單的博客應(yīng)用程序。傳統(tǒng)上,您可以通過創(chuàng)建一個包含文章表、注釋表、作者表等數(shù)據(jù)庫的博客應(yīng)用程序來開始構(gòu)建博客應(yīng)用程序。文章可能會有各種作者,因此,您要為文章和作者建立一個連接表。
采用微服務(wù),您可以從博客主頁模型開始,考慮其中的各個要素。評論不在博客的主頁上,所以在這一時點(diǎn)沒有必要定義它們。您甚至不需要構(gòu)建評論數(shù)據(jù)庫,可以以后進(jìn)行。
首先,您創(chuàng)建一個名為Article的獨(dú)立的REST API微服務(wù)。通過集成Backbone、Angular或者Ember等JavaScript客戶機(jī),前端模型成為函數(shù)代碼。所有這三個JavaScript客戶機(jī)都能夠自然的與REST API協(xié)同工作,可以把數(shù)據(jù)放入到以前只是模型的設(shè)計(jì)中。
Article REST API微服務(wù)是一個輕量級的應(yīng)用程序,其重點(diǎn)放在存儲和檢索文章數(shù)據(jù)的核心功能上。在微服務(wù)應(yīng)用程序開發(fā)的這一階段,您不用擔(dān)心認(rèn)證或者安全模型。以后再對其他的微服務(wù)進(jìn)行分層處理。不要讓很多不必要的功能成為微服務(wù)的負(fù)擔(dān)——畢竟,所謂微服務(wù),“微”是重點(diǎn)。
這一階段最重要的是,由于每個微服務(wù)的功能范圍有限,最終您能夠非常靈活的選擇數(shù)據(jù)存儲方案。不采用大型的、復(fù)雜的數(shù)據(jù)庫設(shè)計(jì),關(guān)系型數(shù)據(jù)庫變得不太相關(guān),MongoDB、Couchbase、Cassandra、Redis和Riak等NoSQL數(shù)據(jù)庫可能會工作得更好一些。理論上,每個微服務(wù)可以使用一種完全適合自己、不同的底層數(shù)據(jù)存儲機(jī)制。
開發(fā)好了自己的Article REST API,并向前端客戶機(jī)提供動態(tài)數(shù)據(jù)后,您就需要處理評論了。您可以建立一個新的獨(dú)立的Comment REST API微服務(wù),專門針對評論采用垃圾信息過濾器和身份識別技術(shù)。Comment微服務(wù)完全封裝了所有各種各樣的評論代碼,您的前端客戶機(jī)現(xiàn)在可以根據(jù)需要從這個新API中獲取動態(tài)數(shù)據(jù)了。
最后,您可能想建立一個Author微服務(wù),用于處理創(chuàng)建新文章時所需的身份認(rèn)證和權(quán)限。Author服務(wù)會有一個控制面板前端,允許博客作者登錄,編寫新博客文章。Author微服務(wù)可以被集成到前端客戶機(jī)和Author微服務(wù)中。在文章創(chuàng)建過程中,Article微服務(wù)向Author微服務(wù)發(fā)起API調(diào)用,確保作者有編寫新博客文章的權(quán)限。
過去,是通過關(guān)系型數(shù)據(jù)庫中的連接表來進(jìn)行權(quán)限檢查的。輕量級服務(wù)間API調(diào)用有時可以代替連接表。
前端微服務(wù)應(yīng)用程序現(xiàn)在來自三個獨(dú)立的微服務(wù),其中兩個互相之間有通信。這一應(yīng)用程序中的所有一切都是分散的。每個微服務(wù)都有自己的數(shù)據(jù)庫,而不是一個大規(guī)模的關(guān)系型數(shù)據(jù)庫。每個微服務(wù)都可以獨(dú)立擴(kuò)展。您可以為Article微服務(wù)數(shù)十個應(yīng)用程序服務(wù)器建立一個負(fù)載平衡器,而Author微服務(wù)只需要一個例化,沒有負(fù)載平衡器。
微服務(wù)背后分散式、松散耦合的理念非常適合利用第三方服務(wù)。例如,不用開發(fā)自己的Comment微服務(wù),您可以使用Disqus。不用開發(fā)自己的認(rèn)證微服務(wù),而是使用Janrain。
這種開發(fā)應(yīng)用程序的微服務(wù)方式咋看起來有些奇怪,但微服務(wù)架構(gòu)已經(jīng)證明它是替代老的整段式大規(guī)模應(yīng)用程序可行的方案。如果您決定沿著這條路走下去,那么您就會站在巨人的肩膀上。
微服務(wù)適合您嗎?
我前面提到過,對是否應(yīng)使用微服務(wù)這一問題的答案可能會讓您大吃一驚。答案并不總是肯定的。正如微服務(wù)顧問Chris Richardson所說,“這并不簡單,而您使用微服務(wù)的原因就是要解決復(fù)雜性?!?/p>
微服務(wù)是“撞到玻璃天花板”后的反應(yīng),記住這一點(diǎn)是很重要的。在某種程度上,傳統(tǒng)的整段式應(yīng)用程序架構(gòu)無法再擴(kuò)展了。每一個成功的軟件項(xiàng)目都遇到了這種情況。要么數(shù)據(jù)庫增長得太大,要么有高達(dá)數(shù)百萬行的代碼,導(dǎo)致您根本無法快速添加功能。
如果您還沒有“撞到玻璃天花板上”——也就是說,您的老程序還能很好的工作,不需要有太大的改動,如果自己愿意主動采用微服務(wù),除了一大堆頭疼的問題,可能不會有太多收獲。
畢竟,微服務(wù)的開發(fā)過程很怪,而且很難。讓所有這些新服務(wù)運(yùn)行,有時感覺就像雜技里面把數(shù)十個球在空中拋來拋去??梢圆捎肒ubernetes等聲明流程編排工具進(jìn)行適當(dāng)?shù)恼{(diào)整。復(fù)雜的微服務(wù)架構(gòu)都有自己的詞典系統(tǒng),覆蓋了您要采用的所有新的軟件模式。
然而,微服務(wù)還沒有像SOA當(dāng)初那樣讓人感到畏縮。實(shí)際上,即使是最小的軟件項(xiàng)目也可以采用微服務(wù)——您不必扔掉所有的老代碼從新開始,可以從建立仿微服務(wù)開始。
如果您的大規(guī)模應(yīng)用程序已經(jīng)很難掌控,其軟件生命周期非常長,創(chuàng)新的步伐陷于停頓,那么微服務(wù)可能就是您所需要的。或者,如果您是剛剛開始,一開始就考慮開發(fā)基于微服務(wù)的應(yīng)用程序是非常明智的。
eBay曾說過,采用微服務(wù)架構(gòu),公司能夠很好地進(jìn)行擴(kuò)展,提高了代碼的可擴(kuò)展性和可維護(hù)性,促使業(yè)務(wù)快速創(chuàng)新,產(chǎn)品交付更快,甚至增強(qiáng)了安全性。谷歌、亞馬遜、推特,PayPal和Netflix都有類似的體驗(yàn)。很多這類公司還開發(fā)了工具,更方便的采用微服務(wù)。
不論您正困擾于怎樣維護(hù)老代碼的問題,不知道該怎樣辦,還是開始一個全新的應(yīng)用,現(xiàn)在都是嘗試采用微服務(wù)方法來開發(fā)應(yīng)用的好時機(jī)。
Lucas Carlson是一名企業(yè)家、作者和開源工程師。如果需要了解詳細(xì)信息,請?jiān)L問lucascarlson.net。
原文網(wǎng)址:
http://www.infoworld.com/article/3200034/application-development/why-you-should-use-microservices.html