金琦 邱元陽 劉宗凡 倪俊杰 楊磊



編者按:隨著互聯網、云計算的高速發展,人們對數據信息化服務依賴程度越來越深。以往的單體應用架構和面向服務化應用的架構逐漸不能滿足業務的需求。而微服務這種分布式架構的興起,是云計算應用快速發展的必然產物,也將是未來整個軟件應用架構向靈活多變、低耦合、高擴展性、動態伸縮發展的方向之一。與此同時,以Docker為代表的容器虛擬化技術將極大減少微服務應用實現大規模部署、落地的成本。
在上一期的文章中,我們介紹了Docker的概念、基本使用方法、基本使用體驗,可能有的讀者嘗試過搭建Docker環境,拉取把程序和環境合在一起的鏡像來運行容器,開發環境、測試環境、業務使用環境就能非常方便地保持一致。甚至你會想到既然使用容器技術能帶來這么多方便.是否能把更多的學校業務進行容器化,這樣的想法很好,現在我們耳熟能詳的“微服務”就是將一個大系統拆分拆解為多個容器,將每一個微服務單獨部署在云平臺的一個容器中,把多個接口用常用HTTP API進行封裝,對外提供一個簡單明了的接口,實現多個個體應用服務部署上的獨立和統一,從而使服務有更高的可靠性。
金琦:經過一個周期的教育信息化建設,當前教育信息化又衍生和積累了一些新現象和新問題.教育信息化發展呈現出智能化、開放化,個性化與社交化等特征。“智慧校園”逐漸取代“數字校園”,而云服務是智慧校園的主要技術載體。在云服務模式中,各類資源和應用以不同的形式動態地、碎片化地、按需地提供給師生及管理者,實現對教學.學習、管理的無縫服務,從而使學校從龐雜的信息化系統建設中解放出來,更多地關注教學和學習本身。云服務具有低成本部署、高效資源應用、受客戶端訪問等特征,可大大降低學校信息化建設的門檻。《教育信息化2.0行動計劃》明確提出,“充分利用云計算、大數據、人工智能等新技術,構建全方位、全過程、全天候的支撐體系,助力教育教學、管理和服務的改革發展”。
邱元陽:云服務是目前各行業包括教育行業廣泛應用的一種信息化服務模式。它采用虛擬化技術調配資源(網絡,服務器、存儲、應用和服務等),允許用戶根據需求通過網絡申請資源,而這些資源以最小化的管理和交互成本來快速供應和釋放。云服務主要分為三種服務模式(如圖1),這個分法主要是從用戶體驗的角度出發的。
(1)基礎設施即服務(laaS.Infrastructure as aService),是指用戶通過網絡可以獲得計算機基礎設施的服務。目前主要通過虛擬化技術采用模塊化建設,對計算、存儲、網絡、安全等基礎IT設施進行資源池化,通過統一的云平臺管理系統實現自動化、智能化、集中化的業務編排和調度管理。目前對學校來說,關心的是由各類大數據采集器、傳感器、網絡設備等構成能夠識別學生不同訴求并提供個性化學習模式的物聯網環境。
(2)平臺即服務(PaaS,Platform as a Service).是指把軟件開發的平臺作為一種可以獲得的服務,交給用戶使用。主要實現平臺核心組件,包括設備管理,通信協議互聯、流媒體處理、安全管理、移動服務管理等。目前對學校來說,關心的是為師生建立起統一的便捷的資源獲取途徑及資源平臺。
(3)軟件即服務(saaS,Software as a Service),是指用戶不需要購買并安裝軟件,直接使用服務商云端提供的軟件,只需管理自己的業務數據就可以了。對學校來說,關心的是覆蓋校園各類管理、教務教學、個性學習和評測、云盤和云桌面等功能,能夠隨時隨地為學生、教師、家長、公眾等不同用戶提供全方位、個性化的全流程應用與服務。
劉宗凡:上面講的云服務體系架構從用戶體驗角度的確容易理解,因為從這個角度而言,它們之間關系是獨立的,畢竟它們面對不同類型的用戶。另外,我們也可以從技術角度理解,就這個角度而言.它們并不是簡單的繼承關系(PaaS基于Iaa.而SaaS基于PaaS).因為首先SaaS可以是基于PaaS或者直接部署于laaS之上,其次PaaS可以構建于laaS之上,也可以直接構建在物理資源之上。有了Docker的加入,PaaS將有更大的發揮空間,甚至在云計算的基礎領域部分取代laaS。目前的laaS只是取代了傳統的服務器,其環境和應用的部署與傳統相比差異很小,只是在運維上有很大的改變。PaaS這種開關式的環境搭建顯然比laaS要方便很多,符合技術發展的趨勢。如果只是為部署一般應用,PaaS就可以勝任,但laaS大行其道的原因就是,每個應用方都有不同的需求,而有些獨特的需求在公有云模板化的運行環境中無法支撐.這樣超出模板外的需求可用Web API來實現,如果對資源有需求則用單獨的laaS來實現,這樣就可以覆蓋多數需求。
在PaaS層中,以前都是服務商提供應用開發框架和部署工具,大多數PaaS解決方案都用容器來定義應用單元,隔離和管理應用運行。但是,在一個傳統的PaaS中,應用容器是被平臺控制的,對用戶是不可見的。一個叫DotCloud的PaaS服務商認識到用戶對底層的容器技術更感興趣,于是在2013年將其容器技術開源,這就是后來的Docker,將應用容器的控制權從平臺服務商交到用戶手中,是一個明智的選擇。現在應用容器可以被用做一個可插拔的應用交付和運維單元,這樣應用方的信息化建設就可以不再被鎖定到一個平臺上了。在Docker的體系中,關鍵的有兩個——Docker Register和Docker Engine,前者負責構建和分發應用鏡像,后者負責構建容器。這樣的組合方式.符合云服務中的軟件即服務(SaaS)理念,用戶可以在各自的數據中心內建立私有的Docker Register,形成屬于自己的私有集群,以應對大規模的應用擴展需求。Docker很像一個集裝箱,通過LXC技術先進行整合鏡像,再集中匯總進行分發。特點體現在,具有標準的鏡像結構既實現了對不同資源實行不同存儲的功能,也能滿足大規模的托管服務,對于有主機集群的云服務平臺,通過分解應用構建。發布等方式實現對云計算技術的開發,在實現云服務平臺的構建的同時,還可以進行優化和自動化維護環境,使得工作效率能夠得到有效提升,在降低成本的同時,滿足了接下來我們要重點討論的微服務架構所需要的資源。
金琦:以前教育行業的軟件架構多為單體架構,信息化業務單一,系統構建并不復雜,所有的代碼、數據庫、業務文件都部署在一臺機器上,即使碰到類似閱卷、選課并發訪問量大的情況.應對也就是對硬件軟件進行改造(如增加緩存,把應用服務和數據服務進行分離、單機改為集群),這依然是單體架構的思想。但隨著學校信息化的進一步發展,對軟件的依賴也逐漸加深,需要信息化部門為學校加速業務處理效率和提高數據挖掘能力的時候,通常就會遇到“信息孤島”,即學校的業務數據沉淀在應用內部,無法被其他應用有效使用。應用程序孤島效應主要集中在業務和數據的兩個方面。業務模塊只能在應用程序的邊界內使用,無法突破邊界提供外部的調用。數據也同樣被應用程序看作是程序的一部分,數據的產生、讀取、寫入,定義解釋都強依賴于應用程序的代碼,甚至于脫離應用程序代碼,數據就會變成一堆無法讀懂的垃圾數據。此時的學校信息化服務就逐漸成為業務信息流動的阻礙,進而成為學校業務進一步發展的阻礙.但是此時的學校又沒有足夠的資源去突破“孤島”。
倪俊杰:其實業界對單體系統并不是沒有解決方案,而且解決方案很早就提出來了,就是SOA(面向服務架構),其大致的意思就是在不破壞應用程序獨立性的前提下,由應用程序把功能以服務的形式暴露,提供給外部通過標準協議進行調用,實現需求方各個應用之間的交互和協作,達到打破應用“孤島”效應的效果。但SOA事實上是針對大型企業的特點,如遵從企業服務總線對項目模塊化,而非學校比較需要的服務模塊化,所以從部分學校的SOA實踐來看,其實施效果并不理想。主要的原因在于不同應用的服務之間協作涉及到大量和各自業務相關的數據操作,各應用缺乏統一業務處理流程,難以統一。所以從學校的角度來看,為了實現SOA需要對應用進行大量的定制化開發,實施難度和代價都比較高:平臺升級需要重新構建、編譯、打包部署,學校應用整個服務層是有多少個服務實例就必須要有多少個配套的虛擬機工作才能把這套系統支撐起來,總體看運維成本也比較高,制約了SOA在學校的推廣和落地的速度。但是通過應用之間的聯通來打破“孤島效應”,實現學校應用之間的高效協作,是提高學校業務運轉效率的一種正確的方式。我們不能簡單地說一種架構比另一種架構更好,這主要取決于正在構建的應用程序的目的。SOA更適合需要與許多其他應用程序集成的大型復雜企業應用程序環境。也就是說,小型應用程序不適合SOA架構,因為它們不需要消息中間件組件。而微服務架構可以為開發人員提供更大的控制權,所以更適合于學校這樣可以較小和良好地分割并有基于Web系統和移動應用的使用場景,所以SOA和微服務這兩種不同類型的體系結構是根據不同的場景需求來選擇的。
邱元陽:關于微服務.本刊2017年第7期《弱水三千,只需一腦殼足矣——容器與微服務》一文做了簡單且形象的類比說明,接下來我們對微服務做個深入闡述,微服務可以看作是SOA服務化的升級版,微服務是一種架構風格.其概念源于Martin Fowler在2014年寫的—篇博文Micro services,他提出微服務是一種架構風格,提倡將應用系統按照一定的原則將大系統拆分成一系列小型服務,每個服務只需要專注于單一的業務功能即可,并且服務之間可以互相獨立運行,采用輕量級HTTP API進行通信,來滿足業務和用戶的需求。其強調服務的獨立性、無狀態、功能職責單一化,強調通過多個微服務的組合實現復雜業務,強調通過服務的替換和升級實現對企業業務的敏捷支持。通過將服務細分,微服務有望解決SOA過程中的“大”和“笨重”的問題,真正實王見IT對業務支持的“隨需而動”。
在傳統經典分層架構模式下(如表現層、業務層、數據層),業務雖然在邏輯劃分上有模塊和組件,但常作為一個整體進行編譯、打包、部署、運維,因此在物理部署層面依然是一個“單塊”。圍繞這種架構模式,我們可以看到很多常用的IDE集成開發環境和編程框架(如eclipse、spring等),它們為開發者提供便捷的開發、調試、測試、部署等體驗,讓開發者可以通過工具、框架快速生成應用原型而不必將大量精力花在服務分解和分布式設計上。但是伴隨著業務和功能的累積擴張,應用體積也隨機迅速擴大,單塊架構難以適應這種快速變化的需求,并且面臨開發效率低、交付周期長、技術轉型難等一系列的挑戰。
微服務架構則是從架構層面出發,將應用系統按照一定的邊界分解成一系列的獨立微服務(如圖2),每個微服務與傳統應用中的邏輯模塊或組件相當.但是可以獨立地進行編譯、部署、運行,具有獨立部署、復雜度可控、技術選型靈活和高擴展性的特征。微服務的主要優點有:職責單一,每個服務只做一件事情,并通過定義良好的接口清晰表述服務邊界:業務粒度微小,由于體積小、復雜度低,每個微服務可由一個小規模開發團隊完全掌控,易于保持高可維護性和開發效率:隔離性好,每個微服務都可以獨立部署,互相隔離,互不影響,一個服務停機不會影響其他服務:管理容易,每個服務可以獨立地進行開發部署,可以針對業務特點使用不同的開發語言,系統不會長期限制在某個技術上:微服務的系統架構還讓微服務與微服務之間在結構上“松耦合”,而在功能上則表現為一個統一的整體。這種所謂的“統一的整體”表現出來的是統一風格的界面、統一的權限管理、統一的安全策略、統一的上線過程、統一的日志和審計方法、統一的調度方式、統一的訪問入口等。
當然.像任何其他技術一樣,微服務架構也存在不足,主要表現在:
(1)通信成本高。在單體應用中的一個函數或進程調用在微服務架構下可能變成了一個HTTP遠程調用,網絡延遲會帶來更長的耗時.造成更高的通信成本。
(2)數據一致性問題。在單體應用中數據通常存儲在一個數據庫中,保證數據的—致性很容易,而在微服務架構下,通常不同的微服務有不同的數據庫,但往往一個操作可能會涉及多個微服務的互相調用,當服務很多時整個調用鏈路變長,調用失敗的風險高,在這種分布式架構下更難保證數據的一致性和可靠性。
(3)部署復雜。微服務化后服務實例變多,造成更多需要部署、配置和監控的部分,此外,一個應用的改變可能會波及多個服務.擴展和監控難度更大。微服務架構在容器云中的實踐
金琦:將業務系統組件化和服務化的“微服務技術”,為系統建設者提供了一個更好的選擇,讓系統建設者更專注于解決業務問題本身。通過前面的討論,我們已經了解了單體應用、SOA和微服務應用的優點和缺點。在實際的業務場景中,我們應該怎么去規劃和構建屬于學校自己的微服務呢?

楊磊:對于“微服務”的概念以及特點相信大家已經有一定的了解了,其實單從概念來說.是比較容易理解的。那應該如何把一個單體應用拆分成多個微服務呢?下面我以“課堂考勤辦公業務”為例,通過對該單體應用的拆分,一起來了解一下微服務體系應該有哪些構成。
首先,我們從學校集成門戶界面中訪問課堂考勤辦公業務,可以將這個業務拆分成三個獨立的子微服務:學校排課微服務.學生選課微服務、數據中心微服務。
(1)學校排課微服務。包含根據時間點全校所有教學班排課的XML表,建立對應排課Javabean對象,然后利用JDK自帶的JAXB解析包,可以方便地將該XML表解析轉換成排課對象,并對外暴露接口/courseschedule,提供排課列表Json數據。
(2)學生選課微服務。該模塊依賴數據中心微服務,完成學生選課功能,并公布選課情況接口/report/t class_selection/{class_selection}。
(3)數據中心微服務。公布教師信息接口/report/teacherlD/{teacherlD}和公布學生信息接口/report/studentlD/{studentlD}。
其次.我們結合開發框架Spring cloud來闡述一下“微服務”在技術層面的實現和架構。Spring Cloud是一系列框架、組件的有序集合,擁有功能完善的、輕量級的微服務實現組件,如服務發現治理、服務容錯、服務網關、服務配置,負載均衡、消息總線、服務跟蹤等方面均有經過實踐檢驗的成熟組件。系統采用Eureka做服務注冊與發現,Zuul做路由API網關,Ribbon做負載均衡,Hystrix做服務熔斷,Spring Cloud Config做統一管理微服務配置。

這樣,微服務的基礎組件就都有了,結合上一步拆分出的微服務,可做出如圖3所示的架構圖。
從圖3中可以看到一所學校有諸如“學校排課…數據中心”等多個業務,拆分多個模塊后,就會出現多樣的問題,而springCloud提供了一整套的解決方案,從而可以統一管理各服務中心的配置,并且在運行期間可以動態修改配置文件。
CAS解決學校的師生在多個微服務之間切換時,需要重復登錄的問題完成統一認證。
ZUUL網關根據URL轉發請求到不同的微服務。例如,教師用戶請求訪問課堂考勤微服務接口,網關再把所有請求轉發到具體的學校排課。學生選課、數據中心相關微服務中,其中的映射關系如下:
Eureka專門給各種服務提供注冊登記,配置服務注冊中心的URL地址。一個微服務就是一個節點,是一個完整的應用程序,并且可獨立運行部署。系統除了前面和業務相關的微服務外,還有API網關節點、配置中心Config—Server節點,Turbine的Hystrix監控節點等。這些節點都是以Eureka客戶端形式注冊在Eureka服務端,然后各個節點間采用輕量級Feign組件就可以實現相互調用通信了,同時也實現了對各種服務可用性的監控。
Ribbon是支持負載均衡,默認的負載均衡策略是輪詢,我們也可以根據自己實際的需求自定義負載均衡策略。
Hystrix通過添加延遲容忍和容錯邏輯,幫助控制這些分布式服務之間的交互。Hystrix通過隔離服務之間的訪問點、停止級聯失敗和提供回退選項來實現這一點,這些都可以提高系統的整體彈性。
金琦:我們做了服務的拆分,也完成了單個微服務的技術實現,為了讓微服務可以為學生和教師提供服務,需要將完成的微服務進行部署上線。針對微服務的部署,有什么最佳的實踐呢?

劉宗凡:基于微服務的思想是可以不用容器技術的.但由于微服務應用由數十甚至上百個服務組成,服務使用不同的語言和框架編寫。每個服務都是一個迷你應用,有自己特定的部署.資源、擴展和監視要求。例如,需要根據服務的需求為每個服務運行一定數量的實例。此外.必須為每個服務實例提供相應的CPU、內存和I/O資源。更有挑戰性的是.盡管如此復雜.部署服務也必須要快速、可靠和具有成本效益。所以我們只是利用容器化技術簡化微服務創建、集成、部署、運維的整個流程,推動微服務在云端的大規模實踐,下面以一個容器云平臺為例,說明各個流程的實踐(如圖4)。
(1)在容器云平臺,用戶可以很方便地創建微服務項目,并在項目中與代碼倉庫進行關聯,輕松選擇代碼項目進行構建。每當開發人員提交代碼時,系統可以自動將存于代碼倉庫的微服務程序快速構建成新的容器鏡像,經過持續集成自動化驗證后轉化為隨時可以部署的容器鏡像.用戶可以將這個微服務一鍵部署到容器云平臺上。

(2)在鏡像倉庫支持加入平臺以外的任意鏡像源.如可以加入Docker官方和社區的優質鏡像,用戶可以根據自己的業務需要.像搭積木一樣自由組合、復用各種容器化微服務,輕松集成應用。例如,用戶需要一個通用的tomcat網站服務或者MySQL數據庫,可以直接在鏡像中選擇適合的數據庫服務鏡像,并與其業務連接起來。可以一次部署多個鏡像并為每個鏡像的容器設定CPU和內存占用。從配置部署到啟動只需要幾分鐘。
(3)平臺支持升級回滾。平臺部署有完整的版本管理,每次升級會生成一個部署版本,可以隨意選擇一個舊版本進行回滾,部署出現異常時可以指定版本恢復。
我們用Docker容器快速編排所有節點,其中這三個示例的微服務節點都要啟動三個實例以作負載均衡。系統運行在阿里云服務器上,不同節點采用不同的端口,如學校排課微服務microservice-classschedules-report提供面向用戶接口/report/classscheduleslD/{classscheduleslD},供用戶查詢學校最新的排課數據。同時訪問Turbine聚合節點,可以監控多個微服務運行狀態。
雖然微服務架構帶來了諸多優勢,但構建、部署、維護分布式的微服務系統并不容易。而容器所提供的輕量級的、面向應用的虛擬化運行環境為微服務提供了理想的載體。同樣,基于容器技術的云服務將極大地簡化容器化微服務創建、集成、部署、運維的整個流程,從而推動微服務在云端的大規模實踐。
構建復雜的應用確實非常困難,而微服務架構模式可以使構建復雜應用變得簡單化。微服務架構的誕生和容器技術的流行幾乎是同時發生的,是互聯網時代倒逼傳統技術和架構而產生的變革,基于容器技術的PaaS平臺給開發者提供了一個部署和管理微服務的簡單方法,它把所有這些問題都打包內置解決了。