SFDC 微服務實踐之路 2016.12.10 杭州(整理)--轉

原文地址:http://mp.weixin.qq.com/s/8cC4Ewt6yPjnxdYxuNZlFQhtml

微服務是什麼?前端

 

微服務是一種細粒度(Fine-Grain)的SOAjava

 

 

    或許在座的高朋瞭解過其概念。我的認爲,與其說微服務是一種技術,不如將其定義爲一種架構,而架構則是「技」的實現與「術」的策略相輔相成。「術」的策略須要分析使用場景,進行合理地劃分業務邊界,實現「業以類聚」,然而「技」的實現則經過特定的技術在實現業務邏輯之時,更多的考慮實現過程當中的效率性、測試的便利性、維護的可持續性,達到「技以羣分」的目的。web

 

    由此而論,我我的偏好將其定義爲:「微服務是一種細粒度的SOA」。算法

 

    這樣定義的好處在於,不必去重複地「抹黑」「單體應用」(Monolithic,也有人翻譯成「巨石應用」),緣於SOA技術的衍化過程當中早已說起。那麼,細粒度更多的體如今「取其精華,去其糟粕」。spring

 

SOA又是什麼?數據庫

 

    SOA = Service-Oriented Architectureapache

 

    SOA 中文定義是面向服務架構,它並不是是今日的重點,請原諒我不能花大篇幅來加以闡述。我用「點到爲止」的方式描述SOA具有哪些特徵,以及相關的技術。編程

 

SOA有什麼?bootstrap

 

    特徵

 

  • 面向服務( Service-Oriented )

  • 鬆耦合(Loose-Coupling)

  • 模塊化(Modular)

  • 分佈式計算(Distributed Computing)

  • 平臺無關性(Independent Platform)

  • 集中管理(Center Government)

 

   技術

 

  • Web Services

 

    Web Services 技術演進的目的在於解決分佈式計算中,統一異構系統的服務調用的通信協議。前期的Web Services有XML-PRC、WSDL、SOAP等技術,不但解決了Windows平臺COM+以及Java 平臺RMI沒法跨平臺的問題,並且使用了可讀性強的本文協議替代了複雜的二進制協議,如CORBA技術。現代的WebServices 技術主要表明有REST等。

 

  • Message Queue

 

    Message Queue 技術設計的目的主要有兩個方面,從架構上來講,消息隊列服務幫助系統之間依賴關係解耦;從技術上來看,消息隊列爲系統提供異步處理的能力,解決了併發同步調用致使資源消耗過集中和過快等問題,將上下游系統的數據結構提供了統一的傳輸介質。

 

  • ESB


    ESB 則是 SOA 集大成實現。

 

 

SOA不是什麼?

 

SOA ≠ Monolithic

 

    SOA 不但不是Monolithic,並且是要解決Monolithic,Monolithic 我的偏好翻譯成「單體應用」,也被翻譯成「巨石應用」。

 

Monolithic是什麼?

 

    

故宮

 

    朋友可能以爲奇怪,故宮與「單體應用」有什麼關係?故宮是帝王居住和辦公的場所,她象徵着「最高權利」和「中央集權」。華夏民族,自秦朝的「三公九卿制」,仍是隋朝的「三省六部制」,以及明清的「內閣制度」,無一例外地致力於鞏固「中央集權」。

 

    近兩千年來,雖然王朝不斷更迭,這個制度一直被沿用,而且沒有出現大的詬病。但是,1793年,英國勳爵馬戛爾尼出使中國,表明英皇爲乾隆皇帝祝壽,也負有促成中英通商的使命。雖然當時的中國籠罩在「乾隆盛世」的光環下,不過在馬戛爾尼看來中國不管從科技仍是社會制度上,均處於相對落後的階段。《左傳》有言:「民之多幸,國之不幸」,當時的大多數國民視英國爲「蠻夷」,不與商貿往來。五十年後,中英鴉片戰爭爆發,1840年,中華帝國第一個不平等條約《南京條約》被迫簽定,它不但打擊中華名族,並且「打醒」了大和民族。明治維新後的日本,屢屢挑戰中國的東亞地位,直到中日甲午戰爭失利。1895年《馬關條約》簽定,割臺灣,賠鉅款。但仍有康有爲等不肯放棄,聯名千人「公車上書」,認爲「中央集權」並非問題所在。「中央集權」職責臃腫,行政不力,中央政策想要對地方面面俱到是不可能的,沒法作到「因地制宜」。

 

    我想說的是,單體應用不正像一個「中央集權」的政府嗎?而微服務應用則更像「多權分立」的「自治」政府,各個「自治」政府之間在「聯邦」的架構下「分工」和「協做」。 

 

 

Why?

 

「學而不思則罔」

 

爲何要微服務?

 

 

  • 效率的須要

 

    應用進行微服務化後,規模和體積變得更加輕量級,在編譯、打包、分發、部署等環節節約了時間,開發上效率提高。

 

  • 質量的須要

 

    微服務應用面向持續集成友好,自動化編譯、單元和集成測試用例執行和迴歸,提升應用總體質量。

 

  • 穩定的須要

 

    當應用大而全時,每每牽一髮而動全身,其中一個服務出現問題,總體受到牽動效應。總體穩定性得不到保證,所以,通過微服務化後,應用由原來的服務內部組裝到服務自由組合,一旦關聯服務存在問題,總體應用能夠選擇性地降級或熔斷等措施,待問題服務恢復,一切照常執行。

 

  • 運維的須要

 

    微服務應用具有自動化編譯、打包、分發、部署和運維的能力。傳統的應用不但須要開發、還須要測試和運維人員,微服務應用實現後,將理想化的全棧(Full-Stack)工程師變爲可能。

 

  • 成長的須要

 

    微服務可以更好,更快地適配新技術,好比目前流行的Apache Kafka。而工程人員須要接觸新的技術,爲將來可能的技術選型作好準備。個人建議在一些不那麼重要的微服務應用中,能夠嘗試一些新的技術,在其提供的功能與實際須要之間,找到一些本身的理解,也是自我成長的須要。


爲何沒必要微服務?

 

    論語有言:「子絕四:‘毋意、毋必、毋固、毋我’。」,簡單地說,不要臆斷,不要執拗,不要自我感受良好,也有什麼是一定的。那麼,在微服務實踐過程當中,哪些因素能夠沒必要微服務呢?請注意用詞,這裏說的是「沒必要」,不是「不要」。 

 

 

  • 場景單一

 

    當應用的場景單一時,沒有必要非得微服務,由於它自己就是微服務,例如一些靜態的通告頁面。

 

  • 邏輯簡單

 

    當應用邏輯簡單時,一樣也違背了微服務的初衷,由於微服務是爲了解決複雜業務邏輯而衍生,所以這種狀況下也沒必要實施微服務。

 

  • 業務漸逝

 

    首先,我解釋一下「漸逝」,也就是逐漸消逝的意思。當應用所關注的業務趨於消逝狀態時,儘管有實施的空間,但無實施的必要。由於這樣的應用隨時可能不復存在,比如沒有必要去對BB機或者短信業務大張旗鼓的重構通常。

 

  • 「老成持重」

 

    老成持重的原意是形容人作事情老練和沉穩。這裏我引用了這個成語,是爲了方便記憶,須要將其拆開,單獨解釋。

 

    「老」是指年老的應用,多久算得上年老呢?我的經驗,應用服役年齡超過三年以上。

 

    「成」則表示應用的規模已成形,業務上幾乎再也不變化,好比通知應用。

 

    「持」說明應用的場景還將持續較長時間。

 

    「重」表示應用所處的位置舉足輕重,不能隨時重構,好比交易應用。

 

    當應用符合其中一條以上的特徵時,該應用沒必要實行微服務。

 

  • 技術盲從

 

    這一點是我最爲關注,也是最擔憂朋友觸犯的。咱們同爲工程人員,對技術的追求毋容置疑,但是千萬不能由於技術而技術,新的技術推出或是解決現有問題,或是提供便利性,但是也有誇大其詞的成分。理性地評估和謹慎地實施,更是咱們更要關注的地方。技術困難挑戰聰明才智,理智對待則考驗情緒控制。

 

進階閱讀

 

網絡

http://microservices.io/

http://martinfowler.com/articles/microservices.html

 

書籍

《Microservice Architecture》, Irakli Nadareishvili

 

文稿

《2016.11.19 微服務實踐之路(廈門) 演講稿》 , 小馬哥 (本微信公衆號內)

 

    以上推薦的網絡資源以及書籍可能你們已閱,不過我主要是推薦我上月去廈門的演講稿,之因此把它放在最後,目的確實想突出,「後其身而身先」(老子)嘛。: D

 

 

How

 

    前面提到的部分是「What」和「Why」,接下來,進入「How」的部分,顧名思義,就是怎麼作,如何作的意思。

 

「多見闕殆,慎行其他」


    以上兩句處於孔子的學生子張請教孔子關於如何幹好工,孔子的回答是:「多聞闕疑,慎言其他,則寡尤。多見闕殆,慎行其他,則寡悔。言寡尤,行寡悔,祿在其中矣」。儒家經典總在告誡咱們,言行需謹慎,如臨深淵、如履薄冰,戰戰兢兢。我的認爲將此等思想放諸四海而皆準,在微服務的實踐過程當中,一樣須要謹慎因應。

 

怎麼實現微服務

 

    怎麼樣實現微服務,我想從如下三個方面來講明:

 

  • 心態

  • 技術

  • 思想

 

心態

 

  • 「子路有聞,未之能行,惟恐有聞」

 

    句中的開頭二字「子路」,是一我的名。孔子門徒三千,七十二賢,最著名的是「孔門十哲」,其中就包括子路。子路,也就是仲由,字子路。整句話的意思是說,子路聽到新的知識或者道理,沒有付諸於實踐,又擔憂新的知識或道理的出現。這句話能很好地反應當今這個浮躁的互聯網時代,看似科技日新月異,新的技術層出不窮,而實踐不力,致使首鼠兩端的心態。凡是他人掌握了新的技術,本身卻沒有,就以爲不如人,反之亦然。我想告訴你們的是,微服務並非新的技術,而是新的思路,只不過諮詢發達,加上基礎的沉澱,讓老的技術或理論在新的時代可以「飛入尋常百姓家」。

 

  • 「不患無位,患因此立」

 

    當微服務被普遍地被業界承認和接受時,或許你總會擔憂在何處實踐,所以,在心態上,須要作到不要擔憂它花落誰家,更要放平心態,思考它爲何存在的理由。

 

  • 「攻乎異端,斯害也已」

 

    當你或你的團隊在推廣微服務過程當中,你得首先作好被挑戰甚至是攻擊的準備,據不徹底統計,世界上有5%的人,是由於反對而反對的人。可是反對負面情緒可能會印象其餘50%的人。由此前提以後,還需具有攻擊「異端邪說」的能力,這樣就能達到「斯害也已」(這種危害也能夠被消滅)。

 

  • 「過則勿憚改」

 

    最後一種心態則是不要怕犯錯,錯了不要忌憚改正。做爲工程人員,實施的過程當中不出錯是不可能的,除非不去作。不要畏懼犯錯,犯錯也是更好地縮小心裏指望和現實狀況的鴻溝,不犯錯就沒有成長的空間,所以,不怕錯,也不忌改正。

 

    前面的部分用了很多詩詞,接下來就不會那麼「詩」了,來點「幹」的,也是今天的技術重頭戲。立刻進入技術的部分。

 

技術  

 

    技術上,在阿里微服務的實踐過程當中也不能免俗,基本上也是如下三個套路:

  • Docker

  • DDD

  • Middleware(Java)

 

    

Docker

 

    在阿里巴巴集團技術體系中,自行研發與Docker兼容的AliDocker,而且提供了一些其餘能力和輔助工具。本人相對這塊不是特別熟悉,若是你們須要進一步的瞭解,能夠考慮後續加入「微服務技術交流」羣中,與個人同事一同討論和交流,這裏只能作一些簡單地介紹。

 

  • 測試環境:AliDocker + ECS(阿里雲)

 

  • 生成環境:AliDocker + 物理機

 

DDD


    DDD是Domain Driven Design(領域驅動設計)的簡寫,該技術源於Eric Evans 在其名著《Domain Driven Design》。從年代來看,已經是至關老的設計方法論了。它做爲微服務重要的理論依據,現在又如「鳳凰涅槃」通常,從新進入軟件領域的視野。DDD的三大實施策略在具體微服務實踐過程當中,取二舍一。固然,整個DDD的理論並不限於此,我的理解,DDD好像是一個傳說,你們都據說過,可是誰也沒有見到過。而是實現這種理想就如同烏托邦式的「共產主義」,目前仍未到時候。

 

  • 有界上下文(Bounded Context)

 

    有界上下文的思想,我的認爲是在《設計模式》中的「單職責原則」進一步發展而言。其實也體現了東西方文化的差別,東方是以古代中國爲表明的「中央集權」思想,和古希臘城邦的「三權分立」的民治思想。微服務則屬於「權力分立」思想的範疇。在微服務實踐過程當中,肯定應用邊界是必要的,也是困難的。必要性反應在系統職責劃分,要簡約、清晰,不耦合。困難性則體如今重構過程不是一蹴而就,而是按部就班,同時,應用還伴隨着業務發展而同步開發,其間的困難是可預知的。雖然過程是痛苦的,可是也不得不去作。

 

  • 持續集成(Continuous integration)

    持續集成是繼承了TDD(Test Driven Development,測試驅動開發)的思想,對應造成規模的公司而言,基本上都部署了持續集成的環境,在阿里則是Aone 系統來統籌。一些流行的開源軟件,如GitLab、Jenkins(Hudson)等。

 

  • 上下文映射(Context Map)


    以上兩個策略均在實踐中被採納,那麼上下文映射(Context Map)則被捨棄,捨棄的緣由並不在於其不合理,而是難以駕馭。例如,用戶服務提供用戶的模型,其中包括了姓名、生日、電話等。但是下游系統,須要僅僅須要用戶的姓名信息,而實際狀況,用戶服務沒法提供這麼細粒度的服務,那麼不得不在中間作一層上下文映射,將二者再也不直接關聯。這種狀況貌似還看不出端倪,但是爲服務化後,服務數量衆多,其映射環節基本上不可控制,下游系統配合改動也是代價頗高,所以,在實踐過程當中,仍是保持原有的調用關係。儘可能作到改造過程當中,減低錯誤率。

 

Middleware

 

    中間件是微服務實施過程當中不可或缺的一個環節,實現中間件的編程語言能夠任意,不過目前市場上最爲流行還屬Java。經剛纔粗略的統計,在座的朋友們從事Java居多,本人剛好也相對熟悉這個領域。接下來,咱們一同來探討,Java 中間件在微服務實踐過程當中的措施。因爲時間的關係,沒法作到一一列舉,所以,如下每一個小節均有實例說明。

 

  • Spring

  • Spring Boot

  • Spring Cloud

  • Spring Cloud Stream

  • Spring Boot DevOps

 

 

Spring

 

  • Annotation驅動


    在微服務實踐的過程當中,中間件部門向各條業務線的開發推廣,用Annotation驅動的方式替代過去XML配置的方式:

 

Annotation驅動方式

   

    在Spring 3.1 以及更好的版本中,提供了大量的Annotation做爲XML配置的替代一下方式(現場統計,基本上沒有人知道這種方式):


XML配置方式

 

    工程人員相對XML的方式更爲熟悉,以上XML配置了是Spring WebMVC的一些組件Bean。實際上,除了@EnableWebMvc之外,還提供了不少@EnableXXX的替代方式,例如@EnableAsync、@EnableAspectJAutoProxy等。在實施過程當中,不少開發人員錯誤的認爲這些是Spring Boot的帶來的便利,其實否則。

 

 

Spring Boot

 

    在Spring Boot 推廣實施過程當中,除了以上Annotation重構方式之外,我想在前端渲染引擎選型評估方面談談本身的心得和體會,建議你們時刻保持懷疑的態度,一家之言,僅供參考。

 

  • 渲染引擎

Thymeleaf(Spring 推薦)

    • 優勢:HTML結構化、UI友好,表達式功能強大

      • HTML結構化、UI友好

     Thymeleaf 設計初衷就是針對UI友好,讓開發人員在編輯模板頁面時,遵循標準HTML結構。

      • 表達式功能強大

    不但兼容標準 OGNL 表達式,並且也支持Spring 表達。Spring 表達式爲Spring 3 以後推出的重要功能提供動態的執行程序的能力。

    • 缺點:編碼略微繁瑣、性能通常、擴展複雜

 

      • 編碼略微繁瑣

 

 

     沒有比較不存在優劣,Thymeleaf 在編輯過程當中相對繁瑣,相比較於Velocity和JSP而言。

 

      • 性能通常    

 

    最明顯的缺點是,性能着實通常,所以,不建議用在訪問過頻繁的頁面,好比寶貝詳情頁面。

 

      • 擴展複雜

 

    Thymeleaf 元素標籤相對比較複雜。

 

    如下爲 Thymeleaf 模板頁面的內容,其中「th」爲Thymeleaf 標籤(tag)的命名空間(namespace):

 

Thymeleaf 模板頁面

 

Velocity(普遍應用)

 

  • 優勢:性能良好、易於擴展、事件處理、配置靈活

 

    • 性能良好

 

    相比較於 Thymeleaf 而言,Velocity的性能良好。

 

    • 易於擴展

 

    在擴展性方面,Velocity提供宏(Marco)擴展,實現代碼複用。

 

    • 事件處理

 

    開發人員可能對於事件處理上相對陌生,我簡單地介紹如下,Velocity 提"org.apache.velocity.app.event.EventHandler"接口,其中典型表明爲:"org.apache.velocity.app.event.ReferenceInsertionEventHandler」接口,主要用於攔截引用插入前的事件。

 

    • 配置靈活

    

    也是Velocity顯著特色,提供了大量靈活的配置項,方便開發人員設置,例如配置模板位置、字符編碼等。

 

  • 缺點:HTML結構化不友好、發展停滯

 

    • HTML結構化不友好

 

    因爲Velocity模板的語法特色並不是HTML結構化友好,指令(Directive)以及宏(Marco)均直接在頁面非標籤區域植入,好比 #set 這種寫法。

 

    • 發展停滯

 

    Velocity 1.7 版本自2010年以來,再也不更新,所以,Spring 4.3 版本(或者Spring Boot 1.4)開始,將Velocity支持標記爲Deprecated。 

 

常規Velocity模板

 

Velocity宏(Marco)

 

Velocity 指令(Directive)

 

 

 JSP(Java EE標準)

 

  •     優勢:編碼靈活、兼容性好、性能優秀、多種頁面結構化

 

    • 編碼靈活

    較以上兩種模板引擎,JSP編碼方式更爲靈活,其中包括:

 

      • Scriptlets

    

    早期類PHP腳本語法,即在JSP頁面中直接添加 Java 代碼,這種編程模式稱爲 Scriptlets ,其對應的J2EE(當時還稱做J2EE,即如今的Java EE)設計模型爲Model 1。

 

  • EL(Express Language)

   

    因爲Scriptlets編程模式在頁面上植入太多的 Java 代碼,代碼既難以複用,維護成本又至關巨大。JSP 2.0 規範引入了EL(Express Language)1.0 規範,隨後該能力被用在J2EE設計模式中,逐步發展成 Model 2 以及 MVC ,JSP頁面再也不負責數據組裝等邏輯,而是僅承載頁面渲染的做用(固然仍是具有 Scriptlets 能力,只是不推薦使用這種方式)。

 

  •     兼容性好

    

    JSP屬於Java EE規範,所以Java EE均提供了實現,好比 Tomcat、Jetty、WebLogic 等等。所以,JSP 具有自然性兼容,不須要額外引入其餘資源。

 

  • 性能優秀

    

    JSP屬於解釋編譯型模板語言,不管是 Scriptlets 仍是 EL 都可以翻譯成 Java 源文件,而後將 Java 源文件編譯成 Java Class 文件,再通過容器加載而且執行相關方法調用(可參考org.apache.jasper.servlet.JspServlet)。

 

  •     多種頁面結構化

   

    這個特色是不少國內 Java 工程人員不太關注的特性,一般將JSP頁面結構定格在HTML,實際上,它的頁面結構格式能夠設置成更爲嚴格的XHTML,甚至是XML。順便提一句,Thymeleaf 也具有該能力,而 Velocity 不具有。所以,在我看來,JSP 並非太落伍,而是太超前。

    

  • 缺點:限制表達式(EL)、擴展繁瑣、規約較多、Servlet強依賴

 

    • 限制表達式(EL)

   

    EL 的實現是OGNL 表達式的子集,僅實現了簡單地數據讀取和邏輯運行。相似於 Bean 方法調用這樣的高級語法,須要配合 JSF 這樣的Web技術來配合( JSF 叫座不叫好的 Web 框架 )。

 

    • 擴展繁瑣

   

    JSP 擴展主要是JSP 標籤擴展,JSP 標籤擴展被不少人視爲反模式,我倒不怎麼認爲,可是對其配置上卻是頗爲複雜,舉個例子,每一個 Tag 的屬性須要綁定一個對應的實現類屬性,而且類型複雜,功能各異,好比 IterationTag 和 BodyTag 的做用存在必定的區別。

 

    • 規約較多

   

    JSP 除了tag lib的規約之外,還有jsp-property-group 等,我用一段web.xml中的配置爲例:

 

    <jsp-config>

        <taglib>

            <taglib-uri>http://tae-sdk.taobao.com/taglibs/sdk</taglib-uri>

            <taglib-location>/META-INF/config/taglibs/sdk-web-1.0.tld</taglib-location>

        </taglib>

        <jsp-property-group>

            <url-pattern>*.jsp</url-pattern>

            <page-encoding>GBK</page-encoding>

            <include-coda>/WEB-INF/jsp/coda/footer.jspf</include-coda>

            <trim-directive-whitespaces>true</trim-directive-whitespaces>

        </jsp-property-group>

    </jsp-config> 

 

 

  • Servlet強依賴

 

    JSP 對於 Servlet API 是強依賴的,主要執行邏輯與Servlet 相同( init 方法、service 方法以及 destroy 方法 ),在現代化的Java Web 編程模式中,基本上屏蔽了Servlet API接口,好比 Spring WebMVC 中的@RequestParam 用於獲取請求參數,去取代Servlet API中的 javax.servlet.http.HttpServletRequest#getParameter(String) 方法,由於該方法僅返回 String 類型,如要轉化成 Integer 類型,不得不調用 Integer#valueOf(String) 方法進行轉化。再則,目前流行的HTTP 2 Web服務器 - Undertow 並不兼容 Servlet API 方案,所以 Spring Boot 官方文檔說明有一段特別說明:

 

Spring Boot 官方文檔說明

   

    Spring Boot 部分點到爲止,會後能夠進一步交流,接下來,進入Spring Cloud的部分。

 

Spring Cloud

    Spring Cloud 官方提供了基本功能描述,其中包括:分佈式/版本化配置(Distributed/versioned configuration)、註冊與發現(Registry and Discovery)、路由(Routing)、服務調用(Service-to-service calls)、負載均衡(Load balancing)、短路( Circuit Break )以及分佈式消息(Distributed messaging)。技術點很多,這裏我選取了分佈式配置爲例。詳細描述,我已在《2016.11.19 微服務實踐之路(廈門) 演講稿》(本微信公衆號內)中提到,請你們會後參考。 

 

  • 分佈式配置

   

    Spring Framework 3.1 開始,提供了一個新的接口:org.springframework.core.env.Environment,該接口的標準實現中組合了 org.springframework.core.env.PropertySources 對象(組合了多個org.springframework.core.env.PropertySource 對象),利用這個對象能夠方便地 resolve Property。同時,PropertySources 能夠追加新的 org.springframework.core.env.PropertySource 對象。所以,Spring Cloud 提供了一個定位器 org.springframework.cloud.bootstrap.config.PropertySourceLocator 可以便利地追加org.springframework.core.env.PropertySource 對象到org.springframework.core.env.PropertySources 對象中。

 

    結合Alibaba 內部分佈式配置管理中間件 Diamond(相似於ZooKeeper),部分實現邏輯以下:

 

部分實現邏輯

 

    具體使用則是經過@Value的方式獲取配置內容中的Property,將其關聯到對象字段中,以下圖:

 

字段與配置項映射代碼

 

    在ArchimedesProperties上方,有一個@RefreshScope的註解,這個註解的用途是通知 Spring Cloud,若是配置項發生變動後,變動後的屬性值將會同步到對象的字段值上。

 

    下一張圖所示,配置內容監聽器的實現,符合現代Annotation 驅動的方式,將配置項的內容轉化成須要的類型:

 

監聽配置內容類型裝換

 

    Spring Cloud 部分完結,下一個環節進入 Spring Cloud Stream。

 

 

Spring Cloud Stream

 

    在Martin Fowler的名著《Enterprise Integration Patterns》(企業整合模式 )中提到過(Channel)的概念,Spring Cloud Stream 付諸於實踐,提供抽象實現。這種抽象實現的好處在於對應用透明,應用再也不強制綁定在某種具體技術上,對它而言,Spring Cloud Stream 爲其創建管道(Channel),其中有兩個概念被涉及:Source(發送端)和Sink(接收端)。

 

    相似於 Kafka 消息中間件,Alibaba 也自主研發了一套Message Queue,名叫 MetaQ ,早一陣子提交到開源社區 Apache 上,與 Kalfa 爲同級的項目,很了不得。不管是 Kafka 仍是 MetaQ 都有自帶的API,爲了增長應用依賴透明性,針對 MetaQ 作了Spring Cloud Stream 的適配,以下圖所示:

 

Source(發送端)發送消息實例代碼

 

 

    Source(發送端)發送消息實例代碼:

 

Sink(接收器)消費消息實例代碼

 

 

    以上代碼至關簡單,與JMS中的消息訂閱模式相似。

 

    前面三小節均爲實現部分,最後一個技術小節,繼續討論一下針對 Spring Boot 的 DevOps。

 

Spring Boot DevOps

 

  • 總體架構

 

Archimedes總體架構圖

 

    每一個微服務應用均有一個應用名,經過接入 Eureka Client ,向註冊中心 Eureka Server 註冊。Eureka Server保存全部註冊應用的信息,這些信息被 Archimedes 經過Eureka Client 提供 REST 接口獲取,將獲取的應用列表併發地獲取他們的Endpoint 和 Metrics信息。同時 Archimedes 也提供了REST API 接口,暴露應用元信息給 Archimedes Dashboard 提供頁面展現。將須要的Metrics信息存放時序數據庫,好比OpenTSDB。再經過OpenTSDB的HTTP API進行查詢,最後將查詢結果顯示在監控頁面中。

 

  • 線程管理

 

    Archimedes Dashboard 提供了圖形化的線程管理,以下單實例線程總數時序圖所示: 

 

單實例線程總數時序圖

 

    下圖所示,其功能相似於JStack,將具體線程運行的狀態以及堆棧詳細列出:

 

活動線程堆棧信息

 

 

  • 內存管理

 

    JVM 的內存管理相對比較複雜,不但包括內存部分,內存池、和相關垃圾回收的算法。其中JVM 內存有包括:Jjava 內存使用、堆使用、以及非堆使用。

 

    在 Archimedes Dashboard 中,將幾者結合起來,集中展現。

 

總體內存使用狀況以及垃圾回收

 

垃圾回收先後對比

 

內存池使用詳情

 

 

  • 日誌管理

 

    我的認爲日誌管理是首創,雖然Spring Admin 也提供了日誌切換的能力,不過它不具有多種日誌實現一同切換的能力,其中適配了四種流行的日誌框架:Java Logging、Log4j、Log4j2 以及 Logback。

 

log4j 日誌調控

 

Logback 日誌調控

 

    Archimedes 中會自動識別應用所使用的日誌框架,雖然不推薦一個應用中使用多套日誌框架,但是現實狀況不得不一併思考,好比有些二方jar包中存在的獨立的日誌處理。

 

 

思想

 

    聊完了技術,下面來談談思想方面的實現,我總結爲三大點:

 

  • 少談」敏捷」

 

    國外不少流派在「吹噓」,敏捷已死。很差我以爲有些誇張的成分,可是也無需過分的實施,借鑑一點便可。

 

  • 推崇」簡潔」

 

    簡潔很重要,牢記「Simple is beautiful」。微服務系統設計越簡潔越好,這裏簡潔不是簡單。

        

  • 學習「狄仁傑」


    這點可能不少朋友以爲很是突兀,和狄仁傑有什麼關係。這裏這麼描述主要是狄閣老總問李元芳:「元芳,你怎麼看?」。這種不恥下問的精神,知道咱們來學習。狄仁傑並不是事事明察,也須要李元芳這樣的武夫分析和提點,可以達到破案的目的,有爲什麼不可呢?

 

 

朋友們,大家怎麼看?

 

(全篇完)

相關文章
相關標籤/搜索