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