- 鳳凰架構:構建可靠的大型分布式系統
- 周志明
- 4158字
- 2021-06-24 11:30:50
1.4 微服務時代
“微服務”這個技術名詞最早在2005年就已經被提出,由Peter Rodgers博士在2005年的云計算博覽會(Web Services Edge 2005)上首次使用,當時的說法是“Micro-Web-Service”,指的是一種專注于單一職責的、與語言無關的細粒度Web服務(Granular Web Service)。“微服務”一詞并不是Peter Rodgers憑空創造出來的概念,它最初可以說是SOA發展時催生的產物,就如同EJB推廣過程中催生了Spring和Hibernate那樣,這一階段的微服務是作為SOA的一種輕量化的補救方案而被提出的。時至今日,在英文版的維基百科上,仍然將微服務定義為SOA的一種變體,所以微服務在最初階段與SOA、Web Service這些概念有所牽扯也完全可以理解,但現在來看,維基百科對微服務的定義已經頗有些過時了。
額外知識
微服務是一種軟件開發技術,是SOA的一種變體。
——Wikipedia
微服務的概念提出后,在將近十年的時間里面,它并沒有受到太多追捧。如果只是對現有SOA架構的修修補補,確實難以喚起廣大技術人員的更多關注。不過,在這十年時間里,微服務本身也在不斷蛻變。2012年,在波蘭克拉科夫舉行的“33rd Degree Conference”大會上,Thoughtworks首席咨詢師James Lewis做了題為“Microservices-Java,the UNIX Way”[1]的主題演講,其中提到了單一服務職責、康威定律、自動擴展、領域驅動設計等原則,卻只字未提SOA,反而號召應該重拾UNIX的設計哲學(As Well Behaved UNIX Service),這點仿佛與筆者在1.3節所說的“初心與自省”遙相呼應。微服務已經迫不及待地要脫離SOA的附庸,成為一種獨立的架構風格,也許,未來還將是SOA的革命者。
微服務真正崛起是在2014年,相信閱讀此文的大多數讀者,也是從Martin Fowler與James Lewis合寫的文章“Microservices:A Definition of This New Architectural Term”[2]中首次了解微服務的。當然,這并不是指各位一定讀過這篇文章,應該準確地說——今天大家所了解的“微服務”就是這篇文章中定義的“微服務”。此文首先給出了現代微服務的概念:“微服務是一種通過多個小型服務組合來構建單個應用的架構風格,這些服務圍繞業務能力而非特定的技術標準來構建。各個服務可以采用不同的編程語言、不同的數據存儲技術,運行在不同的進程之中。服務采取輕量級的通信機制和自動化的部署機制實現通信與運維。”此外,文中列舉了微服務的九個核心的業務與技術特征,下面將其一一列出并解讀。
·圍繞業務能力構建(Organized around Business Capability)。這里再次強調了康威定律的重要性,有怎樣結構、規模、能力的團隊,就會產生對應結構、規模、能力的產品。這個結論不是某個團隊、某個公司遇到的巧合,而是必然的演化結果。如果本應該歸屬同一個產品內的功能被劃分在不同團隊中,必然會產生大量的跨團隊溝通協作,而跨越團隊邊界無論在管理、溝通、工作安排上都有更高昂的成本,因此高效的團隊自然會針對其進行改進,當團隊、產品磨合穩定之后,團隊與產品就會擁有一致的結構。
·分散治理(Decentralized Governance)。這里是指服務對應的開發團隊有直接對服務運行質量負責的責任,也有不受外界干預地掌控服務各個方面的權力,譬如選擇與其他服務異構的技術來實現自己的服務。這一點在真正實踐時多少存有寬松的處理余地,大多數公司都不會在某一個服務使用Java,另一個服務用Python,再下一個服務用Go,而是通常會用統一的主流語言,乃至統一的技術棧或專有的技術平臺。微服務不提倡也并不反對這種“統一”,只要負責提供和維護基礎技術棧的團隊有被各方依賴的覺悟,有“經常被凌晨3點的鬧鐘吵醒”的心理準備就好。微服務更加強調的是在確實需要技術異構時,應能夠有選擇“不統一”的權利,譬如不應該強迫Node.js去開發報表頁面,要做人工智能訓練模型時可以選擇Python,等等。
·通過服務來實現獨立自治的組件(Componentization via Service)。之所以強調通過“服務”(Service)而不是“類庫”(Library)來構建組件,是因為類庫在編譯期靜態鏈接到程序中,通過本地調用來提供功能,而服務是進程外組件,通過遠程調用來提供功能。前文我們也已經分析過,盡管遠程服務有更高昂的調用成本,但這是為組件帶來自治與隔離能力的必要代價。
·產品化思維(Product not Project)。避免把軟件研發視作要去完成某種功能,而是視作一種持續改進、提升的過程。譬如,不應該把運維只看作運維團隊的事,把開發只看作開發團隊的事,團隊應該為軟件產品的整個生命周期負責,開發者不僅應該知道軟件如何開發,還應該知道它如何運作,用戶如何反饋,乃至售后支持工作是怎樣進行的。注意,這里服務的用戶不一定是最終用戶,也可能是消費這個服務的另外一個服務。以前在單體架構下,程序的規模決定了無法讓全部成員都關注完整的產品,如開發、運維、支持等不同職責的成員只關注自己的工作,但在微服務下,要求開發團隊中每個人都具有產品化思維,關心整個產品的全部方面是具有可行性的。
·數據去中心化(Decentralized Data Management)。微服務明確提倡數據應該按領域分散管理、更新、維護、存儲。在單體服務中,一個系統的各個功能模塊通常會使用同一個數據庫。誠然,中心化的存儲天生就更容易避免一致性問題,但是,同一個數據實體在不同服務的視角里,它的抽象形態往往是不同的。譬如,Bookstore應用中的書本,在銷售領域中關注的是價格,在倉儲領域中關注的是庫存數量,在商品展示領域中關注的是書的介紹信息,如果使用中心化存儲,所有領域都必須修改和映射到同一個實體之中,這很可能使不同服務相互影響而喪失獨立性。盡管在分布式中處理好一致性問題也相當困難,很多時候都沒辦法使用傳統的事務處理來保證,但是兩害相權取其輕,即使有一些必要的代價,但仍是值得使用的。
·強終端弱管道(Smart Endpoint and Dumb Pipe)。弱管道(Dumb Pipe)幾乎是直接反對SOAP和ESB的通信機制。ESB可以處理消息的編碼加工、業務規則轉換等;BPM可以集中編排企業業務服務;SOAP有幾十個WS-*協議族在處理事務、一致性、認證授權等一系列工作,這些構建在通信管道上的功能也許對某個系統中的某一部分服務是有必要的,但對于另外更多的服務則是強加進來的負擔。如果服務需要上面的額外通信能力,就應該在服務自己的Endpoint上解決,而不是在通信管道上一攬子處理。微服務提倡使用類似于經典UNIX過濾器那樣簡單直接的通信方式,所以RESTful風格的通信在微服務中會是更合適的選擇。
·容錯性設計(Design for Failure)。不再虛幻地追求服務永遠穩定,而是接受服務總會出錯的現實,要求在微服務的設計中,能夠有自動的機制對其依賴的服務進行快速故障檢測,在持續出錯的時候進行隔離,在服務恢復的時候重新聯通。所以“斷路器”這類設施,對實際生產環境中的微服務來說并不是可選的外圍組件,而是一個必需的支撐點,如果沒有容錯性設計,系統很容易被一兩個服務崩潰所帶來的雪崩效應淹沒。可靠系統完全可能由會出錯的服務組成,這是微服務最大的價值所在,也是本書前言中所說的“鳳凰架構”的含義。
·演進式設計(Evolutionary Design)。容錯性設計承認服務會出錯,演進式設計則承認服務會被報廢淘汰。一個設計良好的服務,應該是能夠報廢的,而不是期望得到長存永生。假如系統中出現不可更改、無可替代的服務,這并不能說明這個服務多么優秀、多么重要,反而是一種系統設計上脆弱的表現,微服務所追求的自治、隔離,也是反對這種脆弱性的表現。
·基礎設施自動化(Infrastructure Automation)。基礎設施自動化,如CI/CD的長足發展,顯著減少了構建、發布、運維工作的復雜性。由于微服務架構下運維對象數量是單體架構運維對象數量的數量級倍,使用微服務的團隊更加依賴于基礎設施的自動化,人工是很難支撐成百上千乃至上萬級別的服務的。
“Microservices”一文中對微服務特征的描寫已經相當具體了,文中除了定義微服務是什么,還專門申明了微服務不是什么——微服務不是SOA的變體或衍生品,應該明確地與SOA劃清界限,不再貼上任何SOA的標簽。如此,微服務的概念才算是一種真正豐滿、獨立的架構風格,為它在未來幾年時間里如明星一般閃耀崛起于技術舞臺鋪下了理論基礎。
額外知識
微服務與SOA
由于與SOA具有一致的表現形式,這讓微服務的支持者更加迫切地拒絕微服務再被打上SOA的標簽,盡管有一些人堅持認為微服務就是SOA的一種變體,也許從面向服務方面來說是對的,但無論如何,SOA與微服務都是兩種不同的東西,正因如此,使用一個別的名稱來簡明地定義這種架構風格就顯得更有必要。
——Martin Fowler/James Lewis
從以上微服務的定義和特征中,你應該可以明顯地感覺到微服務追求的是更加自由的架構風格,摒棄了幾乎所有SOA里可以拋棄的約束和規定,提倡以“實踐標準”代替“規范標準”。可是,如果沒有了統一的規范和約束,以前SOA解決的那些分布式服務的問題,不也就一下子都重新出現了嗎?的確如此,對于服務的注冊發現、跟蹤治理、負載均衡、故障隔離、認證授權、伸縮擴展、傳輸通信、事務處理等問題,微服務中將不再有統一的解決方案。即使只討論Java范圍內會使用到的微服務,僅一個服務間遠程調用問題,可以列入解決方案的候選清單的就有RMI(Sun/Oracle)、Thrift(Facebook)、Dubbo(阿里巴巴)、gRPC(Google)、Motan2(新浪)、Finagle(Twitter)、brpc(百度)、Arvo(Hadoop)、JSON-RPC、REST,等等;僅一個服務發現問題,可以選擇的就有Eureka(Netflix)、Consul(HashiCorp)、Nacos(阿里巴巴)、ZooKeeper(Apache)、etcd(CoreOS)、CoreDNS(CNCF),等等。其他領域也與此類似。
微服務所帶來的自由是一把雙刃開鋒的寶劍,當軟件架構者拿起這把寶劍,一刃指向SOA定下的復雜技術標準,將選擇的權力奪回的同一時刻,另外一刃也正朝著自己映出冷冷的寒光。在微服務時代,軟件研發本身的復雜度確實有所降低。一個簡單服務,并不見得會同時面臨分布式中的所有問題,也就沒有必要背上SOA那百寶袋般沉重的技術包袱。需要解決什么問題,就引入什么工具;團隊熟悉什么技術,就使用什么框架。此外,像Spring Cloud這樣膠水式的全家桶工具集,通過一致的接口、聲明和配置,進一步屏蔽了源自具體工具、框架的復雜性,降低了在不同工具、框架之間切換的成本,所以,作為一個普通的服務開發者,作為一個“螺絲釘”式的程序員,微服務架構是友善的。可是,微服務對架構者卻是滿滿的“惡意”,對架構能力的要求已提升到史無前例的程度。筆者在本書的多處反復強調過,技術架構者的第一職責就是決策權衡,有利有弊才需要決策,有取有舍才需要權衡,如果架構者本身的知識面不足以覆蓋所需要決策的內容,不清楚其中利弊,恐怕將無可避免地陷入選擇困難癥的境遇之中。
微服務時代充滿著自由的氣息,微服務時代充斥著迷茫的選擇。軟件架構不會止步于自由,微服務仍不是架構探索的終點,如果有下一個時代,筆者希望是信息系統擁有微服務的自由權利,圍繞業務能力構建自己的服務而不受技術規范管束,但又不用以承擔自行解決分布式的問題的責任為代價。管他什么利弊權衡!小孩子才做選擇題,成年人全部都要!
[1] 下載地址:http://2012.33degree.org/talk/show/67。
[2] 下載地址:https://martinfowler.com/articles/microservices.html。
- Linux設備驅動開發詳解:基于最新的Linux4.0內核
- Linux系統文件安全實戰全攻略
- PLC控制程序精編108例
- Arch Linux Environment Setup How-to
- 深入Linux內核架構與底層原理(第2版)
- Linux網絡內核分析與開發
- Django Project Blueprints
- Windows 8實戰從入門到精通(超值版)
- AWS SysOps Cookbook
- 新編電腦辦公(Windows 10+ Office 2013版)從入門到精通
- Learn CUDA Programming
- Advanced Infrastructure Penetration Testing
- Mastering Windows 8 C++ App Development
- Android應用性能優化最佳實踐
- 基于Arduino的嵌入式系統入門與實踐