使用容器技術(shù)來(lái)建立一個(gè)微服務(wù)架構(gòu)
之前的博文中,我講解了Linux容器技術(shù)的相關(guān)實(shí)現(xiàn),比如如何使用Docker來(lái)建立流線型的開(kāi)發(fā)和測(cè)試體驗(yàn)。因?yàn)榭梢詫?shí)現(xiàn)跨不同類型基礎(chǔ)設(shè)施的兼容(比如,在AWS上,容器也可以如實(shí)體服務(wù)器上一樣輕松的運(yùn)行),容器讓代碼的部署異常便捷。在實(shí)際工作中,測(cè)試和開(kāi)發(fā)環(huán)境的細(xì)微不同很可能會(huì)導(dǎo)致應(yīng)用程序的部署失敗;因此在這種情況下,對(duì)于開(kāi)發(fā)和測(cè)試工作,容器技術(shù)可以讓開(kāi)發(fā)者豁免很多預(yù)想之外的工作和相互推脫。
在本篇文章中,我們將討論是什么特性讓容器技術(shù)如此適應(yīng)開(kāi)發(fā)和測(cè)試工作,同樣適用于在AWS平臺(tái)上構(gòu)建一個(gè)基于微服務(wù)的架構(gòu)。對(duì)于Web應(yīng)用程序來(lái)說(shuō),微服務(wù)架構(gòu)可以讓?xiě)?yīng)用程序的代碼庫(kù)更加敏捷,并且容易管理。下面,我們將介紹這個(gè)架構(gòu)為何可以大幅提升開(kāi)發(fā)者生產(chǎn)效率的原因,并了解它能夠快速迭代和擴(kuò)充一個(gè)代碼庫(kù)的原理。對(duì)于快速發(fā)展中的創(chuàng)業(yè)公司來(lái)說(shuō),微服務(wù)架構(gòu)可以讓開(kāi)發(fā)團(tuán)隊(duì)在研發(fā)過(guò)程中更加的敏捷和靈活。
Web開(kāi)發(fā)簡(jiǎn)史
首先,我們先簡(jiǎn)潔地回顧下20年內(nèi)基于Web開(kāi)發(fā)的歷史,它可以讓我們知悉微服務(wù)架構(gòu)為什么可以在Web開(kāi)發(fā)領(lǐng)域如此的盛行,同時(shí)也順便了解這個(gè)架構(gòu)可以解決的問(wèn)題。
在Web應(yīng)用程序開(kāi)發(fā)的早期,應(yīng)用程序通常使用Common Gateway Interface(CGI)建立,這個(gè)接口為網(wǎng)絡(luò)服務(wù)器提供了處理瀏覽器發(fā)來(lái)的HTTP請(qǐng)求時(shí)執(zhí)行腳本(通常情況下用Perl編寫(xiě))的能力。CGI的擴(kuò)展性非常很好,因?yàn)樗枰獮槊總€(gè)輸入請(qǐng)求都建立一個(gè)Perl進(jìn)程。為了解決這個(gè)問(wèn)題,那個(gè)時(shí)代的網(wǎng)絡(luò)服務(wù)器通常都會(huì)添加模塊化的支持。Apache,現(xiàn)下最為流行的網(wǎng)絡(luò)服務(wù)器之一,增加了“mod_perl”讓Perl代碼可以在內(nèi)部運(yùn)行,這樣一來(lái),CGI腳本就可以在更少的時(shí)間內(nèi)執(zhí)行。
即使對(duì)比傳統(tǒng)的CGI類似mod_perl這些技術(shù)有了很大的提升,但仍然存在問(wèn)題。也就是說(shuō),負(fù)責(zé)視圖層(比如,在HTML頁(yè)面上執(zhí)行一個(gè)動(dòng)態(tài)模塊)的代碼通常會(huì)被混入應(yīng)用程序邏輯代碼中。這就意味著,完成一個(gè)簡(jiǎn)單的任務(wù),比如在HTML列表中增加一列,或者在form中增加一個(gè)元素,通常需要修改一個(gè)低等級(jí)的應(yīng)用程序代碼。因此,Web程序開(kāi)發(fā)技術(shù)下一個(gè)階段中衍生了“server pages”,它允許在HTML嵌入執(zhí)行代碼。這樣一來(lái),應(yīng)用程序邏輯代碼與視圖代碼被很好的分離。在Java開(kāi)發(fā)領(lǐng)域,一個(gè)被稱為“Model 2”的設(shè)計(jì)模式得以快速演變,在這里,應(yīng)用程序代碼放到Java servlets中,數(shù)據(jù)則通過(guò)Java Beans進(jìn)行,視圖層邏輯則使用了Java server pages,詳見(jiàn)下圖:
圖1:Model 2設(shè)計(jì)模型
隨后,在Java領(lǐng)域,“Model 2”模式在很短的時(shí)間就演化成了“Model-View-Controller(MVC)”框架,比如Apache Struts。而在其他領(lǐng)域,Ruby on Rails則非常盛行。在MVC模式中,控制器類會(huì)定義方法,通過(guò)“route”類映射成URL模式被調(diào)用。 控制器方法會(huì)利用“model”類封核心應(yīng)用程序?qū)嶓w的業(yè)務(wù)邏輯和數(shù)據(jù)。最后,每個(gè)控制方法都會(huì)渲染一個(gè)“view”用于顯示,并修改相應(yīng)模式類的方法。在這種模式下,業(yè)務(wù)、應(yīng)用程序、視圖邏輯被很好的分離,如圖2:
圖2:MVC設(shè)計(jì)模型
REST協(xié)議的盛行
就在MVC被廣泛接受并成為網(wǎng)絡(luò)開(kāi)發(fā)途徑的同時(shí),進(jìn)程間通信(IPC)也開(kāi)始利用上了基于文本的序列化格式,比如XML和JSON。而在類似SOAP這些協(xié)議實(shí)現(xiàn)跨HTTP IPC的不久后,網(wǎng)絡(luò)開(kāi)發(fā)已不再限制于給瀏覽器建立交付內(nèi)容的應(yīng)用程序,為其他程序執(zhí)行操作和交付數(shù)據(jù)的網(wǎng)絡(luò)服務(wù)也逐漸走上歷史的舞臺(tái)。這種基于服務(wù)的架構(gòu)擁有非常強(qiáng)大的功能,因?yàn)樗舜a庫(kù)共享的依賴性,從而開(kāi)發(fā)者可以更進(jìn)一步的解耦應(yīng)用程序組件。而SOAP協(xié)議和相關(guān)的WS-*標(biāo)準(zhǔn)也變得越來(lái)越復(fù)雜,并更加依賴于應(yīng)用程序服務(wù)器的實(shí)現(xiàn),至此開(kāi)發(fā)者開(kāi)始投身更為輕量級(jí)的REST協(xié)議。同時(shí),隨著移動(dòng)設(shè)備的劇增,Web UX development逐漸走向AJAX和JavaScript框架,應(yīng)用程序開(kāi)發(fā)者開(kāi)始廣泛使用REST在客戶端設(shè)備和網(wǎng)絡(luò)服務(wù)器之間做數(shù)據(jù)傳輸。
后來(lái)人們發(fā)現(xiàn),MVC框架同樣非常適合開(kāi)發(fā)REST端點(diǎn)。REST面向資源的特性被很好的映射成了控制器和模型理念,如圖3所示:
圖3:MVC的REST端點(diǎn)
Monolithic架構(gòu)
因此,曾今由模型、視圖層、控制器組成,主要用于給應(yīng)用程序交付HTML內(nèi)容的MVC應(yīng)用程序發(fā)生了本質(zhì)上的變化——它們不僅可以支撐傳統(tǒng)的HTML,也可以通過(guò)REST端點(diǎn)來(lái)支撐JSON。應(yīng)用程序被部署為一個(gè)單一的文件(比如Java)或者同一個(gè)目錄下的文件合集(比如Rails)。然而不容忽視的是,所有應(yīng)用程序代碼都運(yùn)行在相同的進(jìn)程中。因此在縮放過(guò)程中,開(kāi)發(fā)者需要將應(yīng)用程序代碼的多個(gè)副本部署到多個(gè)所需的服務(wù)器上。下圖解析了Monolithic架構(gòu):
圖片4:Monolithic架構(gòu)
在Monolithic架構(gòu)中存在著很多的問(wèn)題。首先,隨著應(yīng)用程序的功能和服務(wù)越來(lái)越多,代碼將變得越來(lái)越復(fù)雜。對(duì)于新的開(kāi)發(fā)者來(lái)說(shuō),這一點(diǎn)非常頭疼。新型集成開(kāi)發(fā)環(huán)境在加載、編譯整個(gè)應(yīng)用程序代碼時(shí)也可能存在問(wèn)題,同時(shí)這個(gè)過(guò)程的耗時(shí)也可能非常長(zhǎng)。此外,因?yàn)樗谐绦虼a都運(yùn)行在服務(wù)器上的相同進(jìn)程中,導(dǎo)致應(yīng)用程序某個(gè)組成的擴(kuò)展也非常難。如果某個(gè)服務(wù)是內(nèi)存密集型的,而另一個(gè)是CPU密集型的,那么服務(wù)器必須有足夠的內(nèi)存和CPU來(lái)滿足每個(gè)服務(wù)的需求。因此,鑒于每個(gè)服務(wù)器都使用非常高的CPU和內(nèi)存,基礎(chǔ)設(shè)施的整體花費(fèi)可能會(huì)非常高,特別是在縱向擴(kuò)展策略下。最后非常微妙的是,應(yīng)用程序的組成通常也會(huì)映射到研發(fā)團(tuán)隊(duì)的結(jié)構(gòu)上。UX工程師負(fù)責(zé)UI組件的建立,中間層開(kāi)發(fā)者通常負(fù)責(zé)建立服務(wù)器端點(diǎn),而數(shù)據(jù)庫(kù)工程師和DBA們則負(fù)責(zé)數(shù)據(jù)訪問(wèn)組件和數(shù)據(jù)庫(kù)。如果某個(gè)UX工程師期望給增加一些顯示,他往往需要來(lái)自中間層和數(shù)據(jù)庫(kù)工程師的配合。就像水一樣,人們通常期望以最少的阻力執(zhí)行,每個(gè)工程師也都期望為其負(fù)責(zé)的應(yīng)用程序嵌入盡可能多的邏輯。鑒于這些問(wèn)題,隨著時(shí)間的推移,代碼將越來(lái)越難以管理。
微服務(wù)架構(gòu)
微服務(wù)架構(gòu)的發(fā)明就是用來(lái)解決這些問(wèn)題。定義在Monolithic架構(gòu)應(yīng)用程序中的服務(wù)將拆分成獨(dú)立的服務(wù),它們?cè)诓煌闹鳈C(jī)上進(jìn)行獨(dú)立的部署。
圖片5:微服務(wù)架構(gòu)
每個(gè)微服務(wù)都對(duì)應(yīng)了一個(gè)獨(dú)立的業(yè)務(wù)功能,也只定義了該功必須的一些操作。這聽(tīng)起來(lái)比較類似面向服務(wù)架構(gòu)(SOA),事實(shí)上,微服務(wù)架構(gòu)和面向服務(wù)的架構(gòu)確實(shí)有很多共同的特性。兩個(gè)架構(gòu)都使用服務(wù)的模式組織代碼,兩種架構(gòu)在不同的服務(wù)間都建立了非常明確的邊界。然而,面向服務(wù)的架構(gòu)起源于Monolithic應(yīng)用程序交互的需求,通常彼此都會(huì)提供一個(gè)API(基于SOAP)。在面向服務(wù)架構(gòu)中,集成重度依賴于中間件,特別在企業(yè)服務(wù)總線(EBS)中。微服務(wù)架構(gòu)通常會(huì)利用一個(gè)消息總線,但是無(wú)論任何情況在消息層都不會(huì)存在邏輯——它純粹的被用于服務(wù)之間的交互。這與ESB有著非常顯著的差別,ESB包含了大量邏輯——用于消息路由、模式驗(yàn)證、消息翻譯和業(yè)務(wù)規(guī)則。因此,對(duì)比傳統(tǒng)的面向服務(wù)架構(gòu),微服務(wù)架構(gòu)往往更為簡(jiǎn)單,不會(huì)包含用于定義服務(wù)間接口的同級(jí)別控制和規(guī)范化數(shù)據(jù)建模。通過(guò)使用微服務(wù),開(kāi)發(fā)將非常快速,服務(wù)的衍變也只需匹配業(yè)務(wù)的需求。
微服務(wù)架構(gòu)的另一個(gè)核心優(yōu)勢(shì)就是服務(wù)可以基于資源的需求進(jìn)行獨(dú)立擴(kuò)展。取代運(yùn)行包含大量CPU和內(nèi)存的大服務(wù)器,微服務(wù)可以被部署在更小的主機(jī)上,這些主機(jī)只需要滿足其部署服務(wù)的需求。同時(shí),開(kāi)發(fā)者可以根據(jù)業(yè)務(wù)的需求選擇開(kāi)發(fā)語(yǔ)言,比如:一個(gè)圖像處理服務(wù)可以使用類似C++這樣的高性能語(yǔ)言實(shí)現(xiàn),一個(gè)執(zhí)行數(shù)學(xué)或者靜態(tài)操作的服務(wù)可以使用Python實(shí)現(xiàn),對(duì)資源進(jìn)行增刪查改的基礎(chǔ)操作則往往通過(guò)Ruby進(jìn)行。在微服務(wù)中,開(kāi)發(fā)者并不需要考慮Monolithic架構(gòu)中使用的“一刀切”模型——比如只使用MVC框架和單一的編程語(yǔ)言。
然而,不容忽視的是,微服務(wù)同樣存在一些劣勢(shì)。因?yàn)榉?wù)通常部署在多個(gè)主機(jī)上,很難持續(xù)跟蹤指定服務(wù)究竟運(yùn)行在某臺(tái)主機(jī)上。同時(shí),因?yàn)槲⒎?wù)架構(gòu)使用的主機(jī)容量往往小于Monolithic架構(gòu),隨著微服務(wù)架構(gòu)不停的橫向擴(kuò)展,主機(jī)數(shù)量將以一個(gè)非常恐怖的速度增長(zhǎng)。在AWS環(huán)境中,微服務(wù)架構(gòu)中獨(dú)立服務(wù)需要的資源往往會(huì)小于最小的EC2實(shí)例類型。從而造成了超量配置并浪費(fèi)開(kāi)銷。此外,如果服務(wù)使用不同的編程語(yǔ)言將開(kāi)發(fā),這就意味著每個(gè)服務(wù)的部署都需要完全不同的庫(kù)和框架,從而服務(wù)的部署非常復(fù)雜。
容器的用武之地
Linux容器技術(shù)的使用可以很大程度上緩解微服務(wù)架構(gòu)所帶來(lái)的問(wèn)題。Linux容器技術(shù)使用了類似cnames和namespaces這樣的內(nèi)核接口,它允許不同容器共享相同的內(nèi)核,同時(shí)容器之間還進(jìn)行了完全的隔離。Docker執(zhí)行環(huán)境使用了一個(gè)被稱為libcontainer的模塊,它標(biāo)準(zhǔn)化了這些接口。Docker同樣為容器鏡像提供了一個(gè)類GitHub的資源庫(kù)DockerHub,讓容器的共享和發(fā)布非常簡(jiǎn)單,也正是這種相同主機(jī)上的容器隔離簡(jiǎn)易了不同語(yǔ)言開(kāi)發(fā)的微服務(wù)代碼部署。使用Docker,我們可以創(chuàng)建一個(gè)DockerFile來(lái)描述所有用到的語(yǔ)言、框架和服務(wù)間庫(kù)的依賴性。舉個(gè)例子,下面代碼中的DockerFile可以用來(lái)定義一個(gè)微服務(wù)的Docker鏡像,它使用了Ruby和Sinatra框架:
FROM ubuntu:14.04
MAINTAINER John Doe <jdoe@example.com>
RUN apt-get update && apt-get install -y curl wget default-jre git
RUN adduser --home /home/sinatra --disabled-password --gecos ''
sinatra
RUN adduser sinatra sudo
RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER sinatra
RUN curl -sSL https://get.rvm.io | bash -s stable
RUN /bin/bash -l -c "source /home/sinatra/.rvm/scripts/rvm"
RUN /bin/bash -l -c "rvm install 2.1.2"
RUN /bin/bash -l -c "gem install sinatra"
RUN /bin/bash -l -c "gem install thin"
使用這個(gè)鏡像建立的容器可以便捷地被部署到一個(gè)主機(jī)上,這個(gè)主機(jī)同時(shí)還運(yùn)行了另一個(gè)使用Java和DropWizard 定義的Docker鏡像所建立的容器。容器執(zhí)行緩解隔離了主機(jī)上運(yùn)行的不同容器,因此不存在使用不同語(yǔ)言、庫(kù)和框架容器所造成的沖突問(wèn)題。
同時(shí)值得高興的是,近期發(fā)布的Amazon EC2 Container Service(Amazon ECS)可以幫你搞定所有這些工作。使用Amazon ECS,你可以定義一個(gè)被稱為“cluster”的計(jì)算資源池,一個(gè)cluster由一個(gè)或以上的EC2實(shí)例組成。Amazon ECS負(fù)責(zé)管理集群中所有基于容器的應(yīng)用程序,提供 telemetry和logging,并管理集群的容量?jī)?yōu)化,進(jìn)行高效的任務(wù)調(diào)度。Amazon ECS提供了一個(gè)“任務(wù)內(nèi)容(task definition)”的理念,它可以定義組成一個(gè)應(yīng)用程序的一組容器。task definition中的每個(gè)容器都指定了該容器所需的資源,而Amazon ECS將基于集群中的可用資源來(lái)調(diào)度這個(gè)任務(wù)的執(zhí)行。
微服務(wù)可以非常便捷地被定義為一個(gè)任務(wù),它可以由兩個(gè)容器組成——一個(gè)負(fù)責(zé)運(yùn)行服務(wù)終端代碼,另一個(gè)負(fù)責(zé)運(yùn)行數(shù)據(jù)庫(kù)。Amazon ECS可以管理這些容器之間的依賴性,同時(shí)也可以跨集群進(jìn)行資源平衡。同時(shí),Amazon ECS還可以無(wú)縫的訪問(wèn)多個(gè)AWS重點(diǎn)服務(wù),比如Elastic Load Balancing、Amazon EBS、Elastic Network Interface和Auto Scaling。通過(guò)Amazon ECS,使用 Amazon EC2部署應(yīng)用程序的所有基本特征都對(duì)基于容器的應(yīng)用程序可用。
此外,類似Amazon ECS 這樣的容器解決方案還可以簡(jiǎn)化“service discovery(服務(wù)搜尋)”這樣的實(shí)現(xiàn)。因?yàn)槲⒎?wù)往往會(huì)跨多個(gè)主機(jī)部署,并根據(jù)負(fù)載進(jìn)行縮放,service discovery更有利于服務(wù)之間的定位。在最簡(jiǎn)單的情況下,可以使用負(fù)載均衡器來(lái)進(jìn)行,但是在更為復(fù)雜的環(huán)境中,一個(gè)真正的分布式配置服務(wù)非常有必要,比如Apache Zookeeper。使用Amazon ECS API,與類似Zookeeper這樣的第三方工具整合將非常容易。配置了Zookeeper的容器可以被添加到一個(gè)task definition中,并可以通過(guò)Amazon ECS在集群中的Amazon EC2調(diào)度執(zhí)行。
從許多方面來(lái)看,使用容器技術(shù)實(shí)施微服務(wù)架構(gòu)轉(zhuǎn)變都與過(guò)去20年Web開(kāi)發(fā)的衍變非常類似。許多這些衍變都是為了更好的利用計(jì)算資源,以及更方便的維護(hù)越來(lái)越復(fù)雜的Web應(yīng)用程序。如我們所見(jiàn),使用Linux容器技術(shù)來(lái)實(shí)現(xiàn)微服務(wù)架構(gòu)完全匹配了這兩個(gè)需求。在本文中,我們簡(jiǎn)單地接觸了使用Amazon ECS來(lái)定義一個(gè)微服務(wù)架構(gòu),但是容器在分布式系統(tǒng)中的使用已經(jīng)遠(yuǎn)超過(guò)了微服務(wù)。在分布式系統(tǒng)中,越來(lái)越多的容器成為了first class citizens,而在未來(lái)的報(bào)告中,我將討論為什么 Amazon ECS對(duì)管理給予容器的計(jì)算是至關(guān)重要的。
責(zé)任編輯:售電衡衡
-
權(quán)威發(fā)布 | 新能源汽車產(chǎn)業(yè)頂層設(shè)計(jì)落地:鼓勵(lì)“光儲(chǔ)充放”,有序推進(jìn)氫燃料供給體系建設(shè)
2020-11-03新能源,汽車,產(chǎn)業(yè),設(shè)計(jì) -
中國(guó)自主研制的“人造太陽(yáng)”重力支撐設(shè)備正式啟運(yùn)
2020-09-14核聚變,ITER,核電 -
探索 | 既耗能又可供能的數(shù)據(jù)中心 打造融合型綜合能源系統(tǒng)
2020-06-16綜合能源服務(wù),新能源消納,能源互聯(lián)網(wǎng)
-
新基建助推 數(shù)據(jù)中心建設(shè)將迎爆發(fā)期
2020-06-16數(shù)據(jù)中心,能源互聯(lián)網(wǎng),電力新基建 -
泛在電力物聯(lián)網(wǎng)建設(shè)下看電網(wǎng)企業(yè)數(shù)據(jù)變現(xiàn)之路
2019-11-12泛在電力物聯(lián)網(wǎng) -
泛在電力物聯(lián)網(wǎng)建設(shè)典型實(shí)踐案例
2019-10-15泛在電力物聯(lián)網(wǎng)案例
-
新基建之充電樁“火”了 想進(jìn)這個(gè)行業(yè)要“心里有底”
2020-06-16充電樁,充電基礎(chǔ)設(shè)施,電力新基建 -
燃料電池汽車駛?cè)雽こ0傩占疫€要多久?
-
備戰(zhàn)全面電動(dòng)化 多部委及央企“定調(diào)”充電樁配套節(jié)奏
-
權(quán)威發(fā)布 | 新能源汽車產(chǎn)業(yè)頂層設(shè)計(jì)落地:鼓勵(lì)“光儲(chǔ)充放”,有序推進(jìn)氫燃料供給體系建設(shè)
2020-11-03新能源,汽車,產(chǎn)業(yè),設(shè)計(jì) -
中國(guó)自主研制的“人造太陽(yáng)”重力支撐設(shè)備正式啟運(yùn)
2020-09-14核聚變,ITER,核電 -
能源革命和電改政策紅利將長(zhǎng)期助力儲(chǔ)能行業(yè)發(fā)展
-
探索 | 既耗能又可供能的數(shù)據(jù)中心 打造融合型綜合能源系統(tǒng)
2020-06-16綜合能源服務(wù),新能源消納,能源互聯(lián)網(wǎng) -
5G新基建助力智能電網(wǎng)發(fā)展
2020-06-125G,智能電網(wǎng),配電網(wǎng) -
從智能電網(wǎng)到智能城市
-
山西省首座電力與通信共享電力鐵塔試點(diǎn)成功
-
中國(guó)電建公司公共資源交易服務(wù)平臺(tái)摘得電力創(chuàng)新大獎(jiǎng)
-
電力系統(tǒng)對(duì)UPS的技術(shù)要求