日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

溯源微服務:企業(yè)分布式應用的一次回顧

 黃爸爸好 2019-05-08

微服務作為架構(gòu)風格幾乎成為云時代企業(yè)級應用的事實標準,構(gòu)成微服務的技術元素本身卻并非革命性??缙脚_的分布式通信框架、地址無關的服務注冊與發(fā)現(xiàn)、智能路由與編排等技術早已在CORBA、SOA時代實現(xiàn)了一遍又一遍,我們不禁好奇,微服務有什么不同?本文是對企業(yè)分布式應用的一次回顧,與前微服務時代相比,我們究竟在哪些領域吸取了教訓,哪些方面持續(xù)搞砸。

我們在重新界定抽象邊界上取得了進展...

架構(gòu)的關鍵在于構(gòu)造合理的封裝抽象。良好的抽象構(gòu)造如進程,由操作系統(tǒng)接管CPU調(diào)度、內(nèi)存地址空間分配和I/O,程序員的心智從此解放,得以聚焦在業(yè)務邏輯上。糟糕的抽象往往引向萬丈深淵,大量精力被浪費在抽象泄露帶來的問題上。

在分布式系統(tǒng)中我們關注組件、組件間的通信以及伴隨的工程實踐,微服務在企業(yè)應用的上下文中就技術約束和業(yè)務價值間達成了更好的平衡點。


RPC?不,是API!

讓我們從組件間的通信開始,最初人們認為這只是需要被解決的技術要素。

(圖片來自:維基百科)

關于如何實現(xiàn)跨平臺的分布式通信,30年前誕生的CORBA架構(gòu)在今天來看仍然非常漂亮:通過定義IDL/ORB/API我們可以將內(nèi)存對象任意分布于網(wǎng)絡中。只要共享IDL,對象可以由C++/Java等不同的語言實現(xiàn),其互相調(diào)用就像本地方法一樣簡單。然而實踐經(jīng)驗告訴我們,分布式系統(tǒng)總是會出現(xiàn)本地調(diào)用不會發(fā)生的各種問題:網(wǎng)絡的開銷、傳輸?shù)难舆t、消息的超時和丟包、遠端系統(tǒng)的崩潰……物理世界的技術約束是無法被忽略的,我們沒有辦法把分布式調(diào)用抽象成簡單的本地方法。因此Martin Fowler在他的<企業(yè)應用架構(gòu)模式>里提出了著名分布式對象第一定律:“不要分布式你的對象”。相反,你應該把盡可能多的操作置于進程之內(nèi),通過replicate整個應用的方式來實現(xiàn)系統(tǒng)的scale。

由分析師們發(fā)起的SOA運動從另一個角度看待這個問題,Web Service應該是對企業(yè)資產(chǎn)和業(yè)務能力的封裝。我們開始站在更高的維度,遠過程調(diào)用不再只是技術意義上的集成。WSDL不僅是通信調(diào)用的接口,更是服務間的契約;UDDI不僅是服務描述、發(fā)現(xiàn)、集成的中心,更是企業(yè)業(yè)務與服務的黃頁。WS-*在廠商的裹挾下發(fā)展成包羅萬象,卻也沒幾個人能掌握。開發(fā)者們抱怨花了太多時間寫冗余的XML制定所謂的規(guī)范,WSDL生成的客戶端也將不同服務耦合在一起。是否有更加輕量敏捷的方式,讓我們快點開始寫第一行生產(chǎn)代碼?

于是我們看到REST的興起。起初是作為反叛,用更加輕量級的方式(http+json)使用Web。然后我們發(fā)現(xiàn)'企業(yè)級'應用并非需要ESB這樣昂貴的專有中間件,由'消費級'技術組成的萬維網(wǎng)是世界上最大規(guī)模的分布式網(wǎng)絡,我們應該向其學習如何構(gòu)建健壯、可演化的系統(tǒng)。Roy Fielding那篇論文所提出的無狀態(tài)、可緩存等特征已經(jīng)深入人心,而狹義上的REST API(基于資源的URI、HTTP動詞和狀態(tài)碼的標準接口)也成為API設計的最佳實踐。

既然API和網(wǎng)站一樣都是基于通用Web技術,API是否可以像網(wǎng)站一樣作為產(chǎn)品提供呢(APIs as product)?于是越來越多的企業(yè)開始將自己的業(yè)務能力封裝成API,提供給消費者,隨之而來的是更彈性的商業(yè)應用和更靈活的計費方式。很多組織也著手構(gòu)建自己的API市場,把內(nèi)部IT能力整合、復用,并為孵化外部產(chǎn)品做準備。API已經(jīng)成為商業(yè)價值主張的一部分。

我們從聚焦實現(xiàn)細節(jié)的rpc出發(fā),來到了更具價值導向的REST API。即使構(gòu)建內(nèi)部系統(tǒng),以消費者驅(qū)動的方式,也總是能幫助我們設計出更加松耦合和易于演進的API。


技術組件?不,是業(yè)務服務!

編程語言中的組件構(gòu)造(如Java中的jar, C#中的dll)是軟件架構(gòu)師們封裝可復用單元的最常用武器。組件作為理論上的最小部署單元,在工程實踐中卻并不容易獨立變更。一般應用程序需要講多個組件打包成一個部署單元(如war包),鏈接在內(nèi)存地址中進行調(diào)用。對單個組件的熱更新往往對組件間耦合和對象狀態(tài)管理有很高的要求,重新部署整個應用一般是默認選項。以進程為邊界構(gòu)建可獨立部署的服務成為架構(gòu)師的另一項選擇。

早期的服務只是單純的技術構(gòu)件,大多數(shù)組織從純粹的技術實現(xiàn)角度考慮服務的劃分。SOA的推動者們指出企業(yè)的信息資產(chǎn)應該被復用,信息孤島應該被打通。通過將不同的服務編排組合,我們應該能夠?qū)崿F(xiàn)IT對業(yè)務更加靈活的支撐。

(圖片來自:0SOA in practice, Nicolai Josuttism, 2009)

SOA的服務建模一般采用業(yè)務流程驅(qū)動的方式。一個典型的SOA設計是由業(yè)務分析師自頂向下地對企業(yè)現(xiàn)有業(yè)務流程進行分析,通過BPM引擎對流程進行建模,向下分解成組合服務,并進一步拆分成數(shù)據(jù)訪問服務(很多可憐的SOA實現(xiàn)中數(shù)據(jù)的訪問被拆分成不同的讀服務和寫服務)。然而這帶來的問題是,服務跟服務間的耦合非常嚴重。當我的業(yè)務發(fā)生了變化,可能會需要修改很多不同的服務,涉及到多個團隊的溝通和協(xié)調(diào)。在運行時層面,服務器間的通信非常頻繁,用戶在界面上的一次點擊按鈕,對應的后臺多層服務間的級聯(lián)通信。這給系統(tǒng)性能和穩(wěn)定性也帶來了巨大的挑戰(zhàn)。SOA式的服務建模從分析型思維出發(fā),卻往往低估了分布式系統(tǒng)和跨團隊協(xié)調(diào)的復雜度,導致服務拆分粒度過細。

微服務的名字常常讓人誤解,但實施正確的微服務粒度可能并不'微'。Martin Fowler與James Lewis在開創(chuàng)微服務定義的一文中已經(jīng)指出微服務應該圍繞完整的業(yè)務能力。今天我們在做微服務設計時,常常利用領域驅(qū)動設計中的Bounded Context來進行服務邊界的劃分。假設你的庫存管理是一個獨立的業(yè)務子域,針對庫存的維護和操作應該被放到通過一個上下文和微服務中,由一個團隊進行開發(fā)維護。多數(shù)業(yè)務變更都發(fā)生在上下文內(nèi)部,不涉及跨團隊協(xié)調(diào)。單個codebase內(nèi)的重構(gòu)和部署讓發(fā)布更加容易。維護庫存所需要的信息查詢的調(diào)用多發(fā)生在進程內(nèi),更好的性能,同時無需處理額外的一致性問題。

微服務的另一個特點在于Product over Project,這需要不同于傳統(tǒng)投資組合的預算管理與團隊組建。傳統(tǒng)的項目制將預算分配在相對短期的服務開發(fā)過程中,項目團隊關注的是如何將業(yè)務范圍(scope)實現(xiàn),開發(fā)結(jié)束后服務轉(zhuǎn)交運維團隊進行維護,項目團隊則被解散進行其他項目的開發(fā)。將微服務作為產(chǎn)品運營則需要建立業(yè)務結(jié)果導向的穩(wěn)定產(chǎn)品團隊。服務的設計不只聚焦于當下需求,更需要考慮價值定位和產(chǎn)品愿景。工程團隊則需要思考如何用有限成本支撐非線性的業(yè)務接入增長。

(圖片來自:Enterprise Architecture as Strategy, Ross et al, 2006)

如今我們對服務的定義已經(jīng)超越了技術組件,領先的組織已經(jīng)在嘗試將design thinking, business operating model應用到微服務設計中。


解耦服務就足夠了嗎?我們需要去中心化一切!

即使有了設計合理的服務于API,我們?nèi)匀恍枰c之匹配的工程實踐才能將其順利實施。

今天仍有很多企業(yè)使用集中式的應用服務器部署應用:開發(fā)團隊將軟件包構(gòu)建出來,再統(tǒng)一安裝到應用服務器中。對應用團隊來說,這往往意味著漫長的反饋周期和痛苦的自動化。我們很早就推薦用Jetty這樣內(nèi)嵌式的應用容器部署軟件,啟動更快,測試環(huán)境更接近生產(chǎn)。one Tomcat per VM的部署方式雖然運行時開銷較大,卻是前容器時代隔離性最好的服務部署模式。Docker將這個實踐更進一步,除了更輕量級的隔離,我們第一次可以將軟件和所依賴的環(huán)境本身打包成版本化的artifact,徹底統(tǒng)一開發(fā)和生產(chǎn)環(huán)境。容器技術的成熟讓我們可以將部署去中心化,開發(fā)團隊可以獨立部署一個服務。

數(shù)據(jù)庫耦合是影響服務獨立變更的另一重要因素。相比代碼構(gòu)成的應用軟件,數(shù)據(jù)庫schema更加難以變動。因為難以測試、難以兼顧性能優(yōu)化和耦合的發(fā)布周期等因素,服務間以數(shù)據(jù)庫集成成為臭名昭著的反模式。服務間的集成應該依賴封裝好的顯示接口,而不是數(shù)據(jù)庫這種實現(xiàn)細節(jié)。我們應該在兼顧數(shù)據(jù)一致性的情況下,為每個微服務分配獨立的db schema甚至db instance。如果說十年前數(shù)據(jù)幾乎等同于關系數(shù)據(jù)庫。如今數(shù) 據(jù)則可能呈現(xiàn)出各種形態(tài):鍵值、文檔、時間序列、圖...我們完全可以采用更加合適的技術,以去中心化的方式進行微服務的數(shù)據(jù)治理。

即使將這一切都解耦,如果將交給一個集中的團隊去實施,很有可能最終還是得到一個耦合的架構(gòu)。這就是是著名的康威定律??低筛嬖V我們“設計系統(tǒng)的架構(gòu)受制于產(chǎn)生這些設計的組織的溝通結(jié)構(gòu)”。但同樣我們可以將康威定律反轉(zhuǎn)應用:如果你想達成一個目標架構(gòu),則必須對團隊結(jié)構(gòu)進行調(diào)整,使之和目標架構(gòu)對齊。相比單體系統(tǒng),微服務在運行時監(jiān)控和運維所帶來的挑戰(zhàn)更大。'you build it, you run it'的DevOps文化成為必須。監(jiān)控運維不再是Ops部門的事情,產(chǎn)品團隊必須對微服務的整個生命周期負責。授權的去中心化自治團隊是實施微服務的必要條件。


我們干得還不錯,但也在持續(xù)搞砸一些事情...

我們在很多方向的確取得了進展。但即使在微服務時代,很多問題仍然在輪回發(fā)生著,似乎我們總是無法吸取歷史的教訓。讓我們看一看那些揮之不去的反模式陰云。

一個例子是開發(fā)者對強類型RPC代碼生成的依戀。盡管歷史經(jīng)驗已經(jīng)證明同步的rpc無法為分布式通信提供足夠好的封裝,偽裝成本地方法調(diào)用的客戶端往往鼓勵程序員做出糟糕的接口設計:細粒度的頻繁調(diào)用、缺少緩存和容錯處理。IDL生成客戶端也會導致服務間耦合,每次變更接口都需要升級數(shù)個相關服務。如果用可演進的REST API(如HATEOS)和tolerant reader模式,則可以優(yōu)雅地解決這個問題。然而新一代的開發(fā)者們還是經(jīng)?!爸匦隆卑l(fā)現(xiàn)rpc的這些能力并陷入依賴——更快的序列化反序列化、類型安全和來自IDE的智能提示、通過spec反向生成代碼...分布式計算先驅(qū)Vinoski不禁感嘆“開發(fā)人員的便利性是否真的勝過正確性,可擴展性,性能,關注點分離,可擴展性和意外復雜性?”

另一個揮之不去的陰影是ESB。ESB在將異構(gòu)的應用wire在一起有著關鍵的作用。然而當越來越多的職責被加入:數(shù)據(jù)報文的裁剪轉(zhuǎn)換、難以測試和版本控制的編排(orchection)邏輯、服務發(fā)現(xiàn)智能路由監(jiān)控治理分布式事務等All in One的solution將ESB變成了一個可怕的單點夢魘。所以微服務發(fā)出了“智能終端啞管道”的吶喊:我們只是需要一個不那么智能的代理處理可靠消息傳輸,將靈活的邏輯交給服務本身去編配(choreography)吧。

于是在典型的微服務架構(gòu)里,負載均衡、服務注冊發(fā)現(xiàn)、分布式追蹤等組件以Unix way的方式各司其職。然而在利益誘惑和特性競爭壓力之下,很多廠商不斷將更多的功能放進他們的中間件,其中為代表的Overambitious API gateways儼然要重新實現(xiàn)占據(jù)中心的ESB。如果API gateway只是處理鑒權、限流等橫切層邏輯沒有問題,如果API gateway開始處理數(shù)據(jù)轉(zhuǎn)換和業(yè)務邏輯編排,你應該提高警惕!

盡管行業(yè)在不斷發(fā)展,但很多時候人們?nèi)匀谎赜门f的思維,用新的技術去一遍遍重新實現(xiàn)這些舊的反模式。


如何更進一步

你總是可以在技術雷達里追蹤微服務的state of art,如今這個領域的前沿方向是什么,Service Mesh, Chaos Engineering, 還是Observability as Code?然而歷史告訴我們,新的技術在解決一些問題的同時,也可能會產(chǎn)生新的問題。更糟糕的是,我們永遠無法記住歷史,用新的工具更高效地重現(xiàn)舊日問題。

Technologies come and go, Principles stay forever。好在那些架構(gòu)和實踐背后的原則是經(jīng)久不變的。從操作系統(tǒng)到移動應用都會需要高內(nèi)聚低耦合的架構(gòu),任何軟件開發(fā)都需要版本控制、自動化構(gòu)建等實踐。謹記這些核心原則、謹記軟件被創(chuàng)造出來是為了解決有價值的問題,可以幫我們更好的借鑒歷史的經(jīng)驗,理解和采納新的技術。


    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多