搭建一個微服務框架所須要哪些技術:
一、Eureka用於服務的註冊於發現
二、Feign支持服務的調用以及均衡負載
三、Hystrix處理服務的熔斷防止故障擴散
四、Spring Cloud Config服務集羣配置中心html
五、Spring Cloud zuul提供負載均衡、反向代理、權限認證的一個API gateway前端
服務化的一個好處就是,不限定服務的提供方使用什麼技術選型,可以實現大公司跨團隊的技術解耦,以下圖:程序員
服務A是歐洲團隊提供服務,歐洲團隊的技術背景是Java,能夠用Java實現服務;spring
服務B是美洲團隊提供服務,能夠用C++實現服務;數據庫
服務C是中國團隊提供服務,能夠用Go實現服務;編程
服務的上游調用方,按照接口、協議便可完成對遠端服務的調用。後端
但實際上,99.9%的公司的團隊規模有限,技術團隊人數也有限,基本是使用同一套技術體系來調用和提供服務的:瀏覽器
這樣的話,若是沒有統一的服務框架,RPC框架,各個團隊的服務提供方就須要各自實現一套序列化、反序列化、網絡框架、鏈接池、收發線程、超時處理、狀態機等「業務以外」的重複技術勞動,形成總體的低效。因此,統一RPC框架把上述「業務以外」的技術勞動統一處理,是服務化首要解決的問題。安全
在達成【「使用統一的RPC框架」是正確的道路】這個一致的前提下,本文指望用簡單通俗的言語簡述一下一個通用RPC框架的技術點與實現。性能優化
什麼是RPC(Remote Procedure Call Protocol),遠程過程調用?
先來看下什麼是本地函數調用,當咱們寫下:
int result = Add(1, 2);
這段代碼的時候,咱們知道,咱們傳入了1,2兩個入參數,調用了本地代碼段中的一個Add函數,獲得了result出參。此時,傳入數據,傳出數據,代碼段在同一個進程空間裏,這是本地函數調用。
那有沒有辦法,咱們可以調用一個跨進程(因此叫「遠程」,典型的,這個進程部署在另外一臺服務器上)的函數呢?
最容易想到的,兩個進程約定一個協議格式,使用Socket通訊,來傳輸【入參】【調用哪一個函數】【出參】。
假設請求報文協議是一個11字節的字節流:
(1)前3個字節填入函數名
(2)中間4個字節填入第一個參數
(3)末尾4個字節填入第二個參數
同時能夠設計響應報文協議是一個4字節的字節流:
即處理結果。
調用方的代碼可能變爲:
request = MakePacket(「add」, 1, 2);
SendRequest_ToService_B(request);
response = RecieveRespnse_FromService_B();
int result = unMakePacket(respnse);
簡單解釋一下:
(1)講傳入參數變爲字節流
(2)將字節流發給服務B
(3)從服務B接受返回字節流
(4)將返回字節流變爲傳出參數
服務方的代碼可能變爲:
request = RecieveRequest();
args/function = unMakePacket(request);
result = Add(1, 2);
response = MakePacket(result);
SendResponse(response);
這個過程也很好理解:
(1)服務端收到字節流
(2)將字節流轉爲函數名與參數
(3)本地調用函數獲得結果
(4)將結果轉變爲字節流
(5)將字節流發送給調用方
這個過程用一張圖描述如上,調用方與服務方的處理步驟都是很是清晰的。這個過程存在最大的問題是什麼呢?
回答:調用方太麻煩了,每次都要關注不少底層細節
(1)入參到字節流的轉化,即序列化應用層協議細節
(2)socket發送,即網絡傳輸協議細節
(3)socket接受
(4)字節流到出參的轉化,即反序列化應用層協議細節
能不能調用層不關注這個細節呢?
回答:能夠,RPC框架就是解決這個問題的,它可以讓調用方「像調用本地函數同樣調用遠端的函數(服務)」。
在此我向你們推薦一個架構學習交流羣。交流學習羣號:575745314 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
經過上面的討論,RPC框架要向調用方屏蔽各類複雜性,要向服務提供方也屏蔽各種複雜性:
(1)調用方感受就像調用本地函數同樣
(2)服務提供方感受就像實現一個本地函數同樣來實現服務
因此整個RPC框架又分爲client部分與server部分,負責把整個非(1)(2)的各種複雜性屏蔽,這些複雜性就是RPC框架的職責。
再細化一些,client端又包含:序列化、反序列化、鏈接池管理、負載均衡、故障轉移、隊列管理,超時管理、異步管理等等等等職責。
server端包含:服務端組件、服務端收發包隊列、io線程、工做線程、序列化反序列化、上下文管理器、超時管理、異步回調等等等等職責。
however,由於篇幅有限,這些細節不作深刻展開
軟件架構是一個包含各類組織的系統組織,這些組件包括 Web服務器, 應用服務器, 數據庫,存儲, 通信層), 它們彼此或和環境存在關係。系統架構的目標是解決利益相關者的關注點。
Conway’s law: Organizations which design systems[...] are constrained to produce designs which are copies of the communication structures of these organizations.
(設計系統的組織,其產生的設計和架構等價於組織間的溝通結構。)
Monolithic比較適合小項目,優勢是:
開發簡單直接,集中式管理, 基本不會重複開發
功能都在本地,沒有分佈式的管理開銷和調用開銷。它的缺點也很是明顯,特別對於互聯網公司來講(不一一列舉了):
開發效率低:全部的開發在一個項目改代碼,遞交代碼相互等待,代碼衝突不斷
代碼維護難:代碼功能耦合在一塊兒,新人不知道何從下手
部署不靈活:構建時間長,任何小修改必須從新構建整個項目,這個過程每每很長
穩定性不高:一個微不足道的小問題,能夠致使整個應用掛掉
擴展性不夠:沒法知足高併發狀況下的業務需求
微服務是指開發一個單個小型的但有業務功能的服務,每一個服務都有本身的處理和輕量通信機制,能夠部署在單個或多個服務器上。微服務也指一種種鬆耦合的、有必定的有界上下文的面向服務架構。也就是說,若是每一個服務都要同時修改,那麼它們就不是微服務,由於它們緊耦合在一塊兒;若是你須要掌握一個服務太多的上下文場景使用條件,那麼它就是一個有上下文邊界的服務,這個定義來自DDD領域驅動設計。
相對於單體架構和SOA,它的主要特色是組件化、鬆耦合、自治、去中心化,體如今如下幾個方面:
一組小的服務
服務粒度要小,而每一個服務是針對一個單一職責的業務能力的封裝,專一作好一件事情。
獨立部署運行和擴展
每一個服務可以獨立被部署並運行在一個進程內。這種運行和部署方式可以賦予系統靈活的代碼組織方式和發佈節奏,使得快速交付和應對變化成爲可能。
獨立開發和演化
技術選型靈活,不受遺留系統技術約束。合適的業務問題選擇合適的技術能夠獨立演化。服務與服務之間採起與語言無關的API進行集成。相對單體架構,微服務架構是更面向業務創新的一種架構模式。
獨立團隊和自治
團隊對服務的整個生命週期負責,工做在獨立的上下文中,本身決策本身治理,而不須要統一的指揮中心。團隊和團隊之間經過鬆散的社區部落進行銜接。
咱們能夠看到整個微服務的思想就如咱們如今面對信息爆炸、知識爆炸是同樣的:經過解耦咱們所作的事情,分而治之以減小沒必要要的損耗,使得整個複雜的系統和組織可以快速的應對變化。
咱們爲何採用微服務呢?
"讓咱們的系統儘量快地響應變化" - Rebecca Parson
讓咱們的系統儘量快地去響應變化。其實幾十年來咱們一直在嘗試解決這個問題。若是必定要在前面加個限制的話,那就是低成本的快速響應變化。上世紀90年代Kent Beck提出要擁抱變化,在同期出現了諸多輕量級開發方法(諸如 XP、Scrum);2001年敏捷宣言誕生,以後又出現了精益、看板等新的管理方式。若是說,這些是爲了儘快的響應變化,在軟件開發流程和實踐方面提出的解決方案,那麼微服務架構就是在軟件技術和架構層面提出的應對之道。
Autonomous
A Microservice is a unit of functionality; it provides an API for a set of capabilities oriented around a business domain or common utility
Isolated
A Microservice is a unit of deployment; it can be modified, tested and deployed as a unit without impacting other areas of a solution
Elastic
A Microservice is stateless; it can be horizontally scaled up and down as needed
Resilient
A Microservice is designed for failure; it is fault tolerant and highly available
Responsive
A Microservice responds to requests in a reasonable amount of time
Intelligent
The intelligence in a system is found in the Microservice endpoints not ‘on the wire’
Message Oriented
Microservices rely on HTTP or a lightweight message bus to establish a boundary between components; this ensures loose coupling, isolation, location transparency, and provides the means to delegate errors as messages
Programmable
Microservices provide API’s for access by developers and administrators
Composable
Applications are composed from multiple Microservices
Automated
The lifecycle of a Microservice is managed through automation that includes development, build, test, staging, production and distribution
通常同步調用比較簡單,一致性強,可是容易出調用問題,性能體驗上也會差些,特別是調用層次多的時候。RESTful和RPC的比較也是一個頗有意 思的話題。通常REST基於HTTP,更容易實現,更容易被接受,服務端實現技術也更靈活些,各個語言都能支持,同時能跨客戶端,對客戶端沒有特殊的要 求,只要封裝了HTTP的SDK就能調用,因此相對使用的廣一些。RPC也有本身的優勢,傳輸協議更高效,安全更可控,特別在一個公司內部,若是有統一個 的開發規範和統一的服務框架時,他的開發效率優點更明顯些。就看各自的技術積累實際條件,本身的選擇了。而異步消息的方式在分佈式系統中有特別普遍的應用,他既能減低調用服務之間的耦合,又能成爲調用之間的緩衝,確保消息積壓不會沖垮被調用方,同時能 保證調用方的服務體驗,繼續幹本身該乾的活,不至於被後臺性能拖慢。不過須要付出的代價是一致性的減弱,須要接受數據最終一致性;還有就是後臺服務通常要 實現冪等性,由於消息發送出於性能的考慮通常會有重複(保證消息的被收到且僅收到一次對性能是很大的考驗);最後就是必須引入一個獨立的broker,如 果公司內部沒有技術積累,對broker分佈式管理也是一個很大的挑戰。
•服務價值的精華體現
•可靠、可用、可讀
•只有一次機會
實現一個API網關做爲全部客戶端的惟一入口。API網關有兩種方式來處理請求。有些請求被簡單地代理/路由到合適的服務上,其餘的請求被轉給到一組服務。
相比於提供普適的API,API網關根據不一樣的客戶端開放不一樣的API。好比,Netflix API網關運行着客戶端特定的適配器代碼,會向客戶端提供最適合其需求的API。
API網關也能夠實現安全性,好比驗證客戶端是否被受權進行某請求。
在此我向你們推薦一個架構學習交流羣。交流學習羣號:575745314 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
•Version
•RequstID
•Auth&Signature
•RateLimit
•Docs
•ErrorCode&Message
•按需伸縮
–部署與監控運維成本
•獨立部署
–機器數量與部署成本
•業務獨立
–服務依賴、治理,版本管理、事務處理
•技術多樣性
–環境部署成本、約定成本
•運行狀態治理
–監控、限流、SLA、LB、日誌分析
•服務註冊與發現
•部署
–快速、複製、擴容
–單機開發
•調用
–安全、容錯、服務降級、調用延時
當企業微服務化之後,服務之間會有錯綜複雜的依賴關係,例如,一個前端請求通常會依賴於多個後端服務,技術上稱爲1 -> N扇出. 在實際生產環境中,服務每每不是百分百可靠,服務可能會出錯或者產生延遲,若是一個應用不能對其依賴的故障進行容錯和隔離,那麼該應用自己就處在被拖垮的風險中。在一個高流量的網站中,某個單一後端一旦發生延遲,可能在數秒內致使全部應用資源(線程,隊列等)被耗盡,形成所謂的雪崩效應(Cascading Failure),嚴重時可致整個網站癱瘓。
服務依賴
一個完整的微服務系統,它的底座最少要包含如下功能:
日誌和審計,主要是日誌的彙總,分類和查詢
監控和告警,主要是監控每一個服務的狀態,必要時產生告警
消息總線,輕量級的MQ或HTTP
註冊發現
負載均衡
部署和升級
事件調度機制
資源管理,如:底層的虛擬機,物理機和網絡管理
如下功能不是最小集的一部分,但也屬於底座功能:
認證和鑑權
微服務統一代碼框架,支持多種編程語言
統一服務構建和打包
統一服務測試
微服務CI/CD流水線
服務依賴關係管理
統一問題跟蹤調試框架,俗稱調用鏈
灰度發佈
藍綠部署
•容器夠小
–解決微服務對機器數量的訴求
•容器獨立
–解決多語言問題
•開發環境與生產環境相同
–單機開發、提高效率
•容器效率高
–省錢
•代碼/image一體化
–可複用管理系統
•容器的橫向與縱向擴容
–可複製
–可動態調節CPU與內存
•Image管理
•系統安全管理
•受權管理
•系統成熟度
•社區成熟度
隨着持續交付概念推廣以及Docker容器普及,微服務將這兩種理念和技術結合起來,造成新的微服務+API + 平臺的開發模式,提出了容器化微服務的持續交付概念。
下圖傳統Monolithic的DevOps開發隊伍方式:
這種總體型架構要求產品隊伍橫跨產品管理 Dev開發 QA DBA 以及系統運營管理,而微服務架構引入之後,以下圖:
微服務促進了DevOps方式的重組,將一個大臃腫的總體產品開發隊伍切分爲根據不一樣微服務的劃分的產品隊伍,以及一個大的總體的平臺隊伍負責運營管理,二者之間經過API交互,作到了鬆耦合隔絕。
微服務的實施是有必定的先決條件:基礎的運維能力(如監控、快速配置、快速部署)需提早構建,不然就會陷入如咱們般被動的局面。推薦採用基礎設施及代碼的實踐,經過代碼來描述計算和網絡基礎設施的方法,使得圖案度i能夠快速安全的搭建和處理由新的配置代替的服務器,服務器之間能夠擁有更高的一致性,下降了在「個人環境工做,而你的環境不工做」的可能,也是爲後續的發佈策略和運維提供更好的支撐。
因爲Docker引入,不一樣的微服務可使用不一樣的技術架構,好比Node.js Java Ruby Python等等,這些單個的服務均可以獨立完成交付生命週期,以下:
Netflix的微服務架構以下,着重全球分發 高可擴展性和可用性:
Twitter的微服務架構,注重高效的可擴展的數據中心:
架構須要由人去設計,這些人被稱爲架構師。或許不少人並未授予架構師的頭銜,但本身卻從事着架構的工做。咱們認爲,架構這項工做永遠都須要由人去完成,可能短時間內都沒法由機器來取代。若是咱們不理解什麼是架構,或者對架構師的職責感到疑惑,那麼很難讓架構這項工做有效地落地。咱們將在本節從新認識架構,並從新定義架構師的職責。此外,架構演進是一個曲折的過程,但咱們卻不難看出架構的發展規律,甚至還能推測出架構未來的發展趨勢。咱們相信,微服務必定不是架構的終點,它或許只是架構從重量級轉型爲輕量級的橋樑,咱們正是設計並建造這座橋樑的工程師。
如今咱們從架構與架構師的角度開始出發,開啓輕量級微服務的架構探險之旅。
1. 架構與架構師
可能絕大多數的程序員都想成爲一名優秀的架構師,天天都能從事技術架構的相關工做,編點框架代碼,畫點架構圖,寫點PPT,帥氣地站在講臺上給程序員們進行技術培訓。你們廣泛認爲,架構師的代碼比別人寫得少,可是工資卻比別人拿得多,架構師是技術團隊中技術最牛的人,別人搞不定的技術問題,在架構師眼中都是小菜一碟。
這樣的人真的是架構師嗎?
咱們認爲,他們不是架構師,而是技術專家。其實架構師與技術專家有着本質的區別,從他們所關注的技術方向來看,架構師更偏向技術廣度,而技術專家更偏向技術深度,如圖1-1所示。
圖1-1 架構師與技術專家的區別
換句話說,架構師須要有較強的綜合能力,他們須要接觸的技術領域較廣,但他們所掌握的技術專業能力卻沒有技術專家那麼深。若是咱們想成爲一名架構師,那麼就不該該把全部的精力都投入在某個技術領域上,而是要學會分散本身所關注的層面,作到在衆多技術領域上都要有必定的深度。
架構師除了須要具有在技術上所需的「硬技能」,還須要不斷完善本身的「軟技能」,好比溝通、組織、學習等技能。有時候軟技能可能比硬技能更加劇要,甚至軟技能還會影響本身的職業發展。若是沒有較好的軟技能,架構師將沒法將本身所設計的架構順利地移交到程序員們手中,並指導他們將其真正落地。架構師正是經過他們所具有的綜合能力來帶領技術團隊,解決不斷出現的技術挑戰。
架構師的職責是什麼?
咱們的回答是:制定規範 + 指導落地。
架構師根據業務需求所制定的合理且可落地的技術規範,咱們將這樣的規範稱爲架構。
將架構工做作好猶如咱們用兩條腿走路同樣,左腿邁出去表示「制定規範」,右腿跟上來表示「指導落地」,如圖1-2所示。
圖1-2 架構師的職責
若是左腿邁出去,右腿沒跟上來,那不是架構師,多是須要拄拐的人。然而,咱們身邊卻有一些這樣的不合格的架構師,他們只懂得制定規範,卻忽略了指導落地。若是架構沒法落地,那麼就沒法稱爲架構了。
此外,還有一些架構師認爲,架構只是技術層面上的問題,本身設計的架構應該用到市面上最爲流行的新技術,好比別人公司在用微服務,那麼本身公司也要用起來。若是將架構工做脫離於業務需求,咱們認爲這不是作架構,而是玩技術。脫離業務來設計架構是對架構的不尊重。微服務是一種應用系統架構,須要架構師圍繞業務進行設計。
可是,咱們毫不要爲了微服務而去微服務。
從事微服務架構工做的架構師,相比傳統架構的架構師而言,所要求的技能更加全面。他們不只僅是系統架構師,也是業務分析師,他們的責任重大且挑戰艱鉅。
從大的方向來看,微服務架構師須要具有如下基本職責。
(1)分析業務需求並切分微服務邊界。
(2)定義架構規範與文檔標準。
(3)確保微服務架構順利落地。
(4)改善微服務架構並提升開發效率。
職責與挑戰每每是沒法分離的,微服務架構師必須面對並克服這些挑戰。
(1)架構須要適應不斷變化的業務需求。
(2)架構具有穩定性、擴展性、安全性、容錯性等。
(3)使技術團隊深入理解微服務思想。
(4)展示微服務架構的價值。
咱們認爲,傳統架構師轉型爲微服務架構首先須要作到的是深入理解業務,而不是表面上瞭解需求。業務和需求實際上是兩碼事,業務的背後反映了客戶的剛需,而需求每每是產品經理根據業務剛需所指定的解決方案。做爲微服務架構師,咱們須要透過需求的表象去理解業務的本質。其次須要作到的是不斷優化架構,讓架構變得更加簡單,更加輕量級。咱們要將昨天最好的表現,當成今天最低的要求,只有在技術上不斷要求本身,才能讓架構變得更好。
2. 架構演進過程
話說天下大勢,分久必合,合久必分,對於架構演進過程而言,也符合這個規律。
最先的應用程序其實是沒有任何架構的,由於那時業務比較簡單,沒有架構也許是合理的,如圖1-3所示。
圖1-3 沒有架構
但隨着業務不斷複雜起來,咱們意識到架構能夠作到水平分層,好比表現層、邏輯層、數據層等,咱們可在不一樣的層上實現每一層所關注的內容,咱們稱其爲「關注點分離」。但此時的架構更像是一塊「鐵板」,每一層的沒法進行分離,所以咱們也將這樣的架構稱爲「單塊架構」,如圖1-4所示。
今後架構發生了更爲複雜的變化,層次結構愈來愈深,並且再也不侷限於水平方向上的分層,實際上愈來愈多的應用程序圍繞着不一樣的業務需求來實現,此時出現了「垂直分層架構」,每一個垂直應用中實際上都是一個獨立的子系統,它們共同組成了整個應用系統。然而,這些子系統通常能夠部署在不一樣的服務器上,這些服務器能夠分佈在不一樣的地域中,咱們也稱其爲「分佈式架構」,如圖1-5所示。
圖1-4 水平分層架構(單塊架構)
圖1-5 垂直分層架構(分佈式架構)
業務並無中止發展的腳步,架構的演變也是如此。分佈式應用之間的調用愈來愈多,整個系統的複雜度急劇上升,人們但願找到一種途徑來下降分佈式應用之間的耦合。此時出現了面向服務架構(SOA),人們但願SOA能成爲解決分佈式應用系統複雜性的「銀彈」,然而事實卻事與願違。應用的複雜性不只沒有獲得解決,反而還讓架構變得更加複雜,同時也造成了大量的SOA商業產品,這些現象讓人們更加恐懼SOA,將它視爲複雜和昂貴的代名詞,如圖1-6所示。
隨着互聯網行業不斷髮展,用戶對產品的體驗要求愈來愈高,前端的價值逐漸被凸顯出來,此時出現了「先後端分離」的趨勢,前端工程師專心在界面展示與數據渲染上,後端工程師關注在業務邏輯與數據結構上,先後端只需經過REST API進行交互,工做分工更加明確,開發效率更加高效,如圖1-7所示。
圖1-6 面向服務架構(SOA)
圖1-7 先後端分離架構
彷佛很長時間都未出現任何技術能與當年的SOA相提並論,除了微服務架構。微服務的概念在2014年首次被提出以來,近幾年一直是應用架構領域的核心話題。但人們每每仍是容易想到當年的SOA,認爲微服務與SOA有着相同的目的,只是實現細節不太同樣罷了,如圖1-8所示。
圖1-8 微服務架構
微服務與SOA到底有何區別?
咱們認爲,微服務是SOA的一種落地方案。
SOA是一種面向服務的架構思想,微服務也一樣推崇這種思想。微服務是將一個大型的單塊架構,拆分爲多個細粒度服務的架構。微服務更加考驗咱們的是,深刻理解業務併合理地對服務邊界進行切分。微服務的概念相比SOA更容易落地的緣由不是概念上的創新,而是技術上的突破,尤爲是容器與自動化運維技術的普及與應用。
咱們始終相信,微服務並非架構發展的終點,也許是新架構時代的起點。
3. 微服務架構發展趨勢
微服務架構所涉及的範圍至關普遍,咱們不妨從多個角度來推測微服務架構的發展趨勢。
從微服務開發角度來看,咱們認爲微服務的開發框架將變得更加多樣化。
開發人員可以使用更加適合的開發框架來完成微服務業務實現,而再也不拘泥於某一種編程語言,只需確保對外提供統一的API接口方式便可。甚至可將查詢與修改操做相分離,查詢操做能夠用一種更加輕量級的編程語言來實現,而修改操做會涉及事務,通常須要藉助開發框架的事務特性來保證。
咱們堅信,微服務必將堅持走輕量級技術路線。
究竟什麼是輕量級?
咱們認爲,輕量級必須包含三個特徵:易用、快速、穩定。
咱們但願微服務架構中所涉及的技術都可以快速上手,運行時不佔用過多的系統資源且性能突出,並且可以長期穩定地運行。
從微服務部署角度來看,咱們認爲微服務的部署過程將變得更加自動化。
部署微服務再也不經過手工的方式去完成,由於這樣既低效又容易出錯,咱們更加傾向於使用軟件工具將其自動完成。要實現自動化部署這個目標,咱們每每沒法一步到位,最合理的方式是「先讓它跑起來,再讓它跑得快」。也就是說,早期的自動化部署方案也許不夠完備,或多或少會存在一些人工參與的狀況,其實這些都再正常不過了,但咱們須要不斷優化,努力經過自動化技術來取代重複性的人工操做。
最後想說的是,自動化雖好,但不要爲了自動化而去自動化,或許有些環節經過手工處理纔是最有效的方式。
搭建微服務架構毫不是一件輕鬆的事情,咱們不只要對微服務概念有着深入的理解,還要研究大量的技術工具,並掌握它們的優缺點,最終須要結合技術團隊對技術的瞭解程度,選擇最爲合適的技術選型。這些純技術的技術工具只是微服務的基礎設施,咱們還須要在此基礎設施上圍繞真實的業務場景,對微服務邊界進行合理地切分。咱們將在本節介紹微服務的冰山模型,你們將從這座冰山中看到微服務架構的全貌,隨後咱們將深刻冰山之下的世界,去探索微服務基礎設施的八大中心,最後咱們還會介紹一些關於切分微服務邊界的原則和技巧。
咱們如今就從微服務冰山模型開始吧,這座冰山彷佛比咱們想象中的要大不少。
1. 認識微服務架構冰山模型
有些人認爲,使用了Spring Boot開發框架就是擁有了微服務,其實這樣的認識是不正確的。Spring Boot只是一款微服務的開發框架,並且僅能用於Java應用程序中,毫無疑問,它只是微服務的冰山一角。此外,咱們建議你們結合自身的業務場景,選擇更爲合適的編程語言以及開發框架來實現微服務,而不要拘泥於一種編程語言。
還有一些人認爲,用上了Docker就進入了微服務時代,其實這樣的認識也是不正確的。Docker只是一種封裝微服務應用程序的容器化技術,它改變了應用程序的交付方式,也加速了微服務架構的落地速度。能夠確定地說,若是沒有Docker容器技術,或許今天咱們沒法聽到微服務的概念。
若是將微服務架構中所涉及的技術棧比喻爲一座冰山的話,那麼冰山之上最顯而易見的部分就是微服務的開發框架與容器技術了,Spring Boot與Docker都屬於冰山之上的技術。
冰山之下到底有哪些技術呢?
咱們認爲冰山之下的技術是整個微服務架構的基石,它們構成了整個微服務架構的基礎設施。好比咱們在上冊中學習的ZooKeeper服務註冊表、Node.js服務網關、Jenkins持續部署系統等,它們都屬於冰山之下的部分。
咱們可經過一幅圖來描繪微服務架構這座冰山,如圖1-9所示。
圖1-9 微服務架構冰山模型
因爲服務註冊表集中管理了微服務相關的服務配置,所以咱們也將它稱爲「註冊中心」;因爲服務網關是前端應用程序的惟一入口,所以咱們也將其稱爲「調用中心」;一樣,咱們也將持續部署系統稱爲「部署中心」。這些中心都聚集在微服務冰山模型之下,除此以外,還有其餘功能的中心,這些中心共同構成了微服務的基礎設施。
2. 冰山下的微服務基礎設施
冰山下的微服務基礎設施,實際包括了八大中心。
(1)註冊中心:用於註冊微服務相關配置信息的中心,咱們選用ZooKeeper實現。
(2)調用中心:用於提供給前端調用的統一入口,咱們選用Node.js實現。
(3)部署中心:用於編譯並打包微服務源碼並將其部署到Docker引擎中,咱們選用Jenkins實現。
(4)日誌中心:用於收集並管理微服務應用程序中產生的日誌,第2章中將詳細介紹。
(5)監控中心:用於監控微服務的實時運行情況,第3章中將詳細介紹。
(6)追蹤中心:用於最終微服務的調用軌跡,第3章中將詳細介紹。
(7)消息中心:用於解耦微服務之間的調用關係,第5章中將詳細介紹。
(8)配置中心:用於管理微服務應用程序所需的配置參數,第7章中將詳細介紹。
也許你們看到以上八大中心後會產生一些疑惑:不少人說微服務是去中心化的,爲什麼咱們還要提供這些中心呢?
咱們認爲,中心分爲兩類:一類是含有業務意義的中心;另外一類是不含業務意義的中心(只是技術層面的中心)。
在微服務架構中咱們應該去除的是含有業務意義的中心,而不是去除技術層面上的廣義中心。好比,咱們所設計的調用中心內部是不可能帶有任何業務流程的,它只是一個純技術層面的框架。對於其餘中心也是如此,絕對不含有任何的業務,不然咱們就應該將其去除。
3. 根據業務切分微服務邊界
凡是學習過微服務的人都知道,咱們須要根據業務來切分微服務邊界。道理可能你們都懂,但或許仍然不知道應該怎麼去作。例如,切分微服務邊界有哪些關鍵性步驟,以及包含哪些重要性原則?
通過大量的微服務實踐,咱們總結了如下五個步驟,可幫助你們有效地切分微服務邊界。
在切分微服務以前,咱們要作的第一件事情就是梳理業務流程。不妨找業務專家諮詢,經過與他們溝通從而瞭解真實的業務流程,並將其繪製成流程圖。對於過於複雜的業務流程,咱們也可單獨繪製流程圖,並增長相關的流程說明。固然也能提供相應的狀態圖,用於說明業務流程中所涉及狀態的變化過程。
花再多時間去分析業務流程都不過度,如今所花的每一分鐘都是至關值得的。
在業務流程中與業務不太相關的部分,咱們可考慮將其剝離出來,並造成公共服務。例如,郵件發送、文件上傳、其餘第三方接口等。每種公共服務都對應一個微服務,每一個微服務都有相關API,每一個API都有本身的輸入與輸出。這些API必定要造成文檔,以便其餘服務調用。
通常狀況下,抽取的公共服務都不太會變化,咱們必定要想辦法將不變的東西從可變的世界中抽取出來。
當公共服務抽取完畢後,業務流程中剩下來的部分就是業務服務了。建議剛開始實施微服務時,不要將業務服務的邊界切得太細,能夠考慮先「大切幾塊」,但須要確保每一個服務之間儘可能不要有依賴關係。換句話說,每一個服務都是獨立的,雖然此時服務的塊頭可能比較大。
咱們先確保這些大塊頭服務能夠運行在微服務基礎設施上,再不斷將它們進行細化,拆解爲更小的服務。
深刻到每一個業務服務中,咱們首先要作的是定義它底層所涉及的數據模型,也稱爲「領域模型」。此時會涉及數據庫表結構設計,以及數據模型與關係設計。在數據層面上的設計是相當重要的,若是該部分設計得不到位,將增長後期實現微服務的成本。
數據模型的設計一樣也須要進行文檔化,這些文檔將指導後端工程師順利地完成微服務實現。
底層的數據模型設計完畢後,咱們將視角轉換到頂層的服務接口上。服務接口實際上就是一組API,這些API需作到職責單一,並且須要經過名稱就能識別出它的業務含義。建議確保每一個API的命名是全局惟一的,也建議每一個API都有各自的版本號,版本號能夠用自增加的方式來體現。
服務接口也須要進行文檔化,這些文檔通常由後端工程師編寫,並提供給前端與測試工程師閱讀。
在此我向你們推薦一個架構學習交流羣。交流學習羣號:575745314 裏面會分享一些資深架構師錄製的視頻錄像:有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構等這些成爲架構師必備的知識體系。還能領取免費的學習資源,目前受益良多
做爲一名微服務架構師,咱們不只須要深刻理解業務,並能準確地劃分服務邊界,並且還須要深刻理解微服務,並能合理地選擇技術選型。咱們認爲,微服務架構實際上分爲兩大部分,其中一部分對應部署階段,另外一部分對應運行階段。這兩部分包含了大量的技術工具,咱們須要結合多方面因素來考慮,選擇最爲合適的技術選型來搭建微服務架構,並確保它能保持輕量級。
本節將着眼於微服務的部署與運行兩大階段,經過圖文方式來描述輕量級微服務架構。
1. 輕量級微服務部署架構
當開發人員完成了微服務的細節實現後,首先要作的是確保本身所寫代碼的可用性,他們每每會藉助單元測試工具來保證這一環節不出問題。當他們將源碼提交併推送到代碼倉庫後,此時部署中心將從代碼倉庫中獲取源碼,並執行編譯與打包操做。
不只如此,部署中心還需從配置中心獲取對應運行環境的配置參數,並生成相應的配置文件,並將這些配置文件與應用程序一同複製到Docker鏡像中,最後還需將此鏡像上傳到鏡像倉庫,以便後續可從鏡像倉庫中下載指定的鏡像,從而運行相應的Docker容器。
此外,部署中心還可掃描源碼並自動生成API文檔站點,以便其餘技術人員可隨時從文檔站點中查看最新部署服務所包含的API文檔。固然,咱們還能夠對所需完成的微服務僅提供簡單的代碼實現,這樣就能將微服務文檔的輸出時間儘量提早,以便其餘技術人員可以更早地瞭解到微服務的相關API信息,隨後再去完成更加細節的代碼實現,這是咱們推薦的工做方法。
當Docker鏡像上傳到鏡像倉庫後,部署中心可在不一樣的運行環境下根據特定的鏡像來啓動相應的Docker容器。爲了便於描述,咱們將該容器稱爲「服務容器」,它包含了承載微服務的應用程序及其配置文件。
當服務容器啓動後,會自動將其配置信息寫入註冊中心,與此同時,部署中心也會鏈接到註冊中心,並設置服務的版本號,以便於在後續調用服務時可根據版本號來識別當前可用的服務。
咱們可將以上過程繪製爲一幅架構圖,如圖1-10所示。
圖1-10 輕量級微服務部署架構
可見,在微服務部署階段中,部署中心是其中的主角,它支配其餘組件,使服務能夠成功部署,咱們須要確保它的穩定性。
2. 輕量級微服務運行架構
當用戶經過瀏覽器或移動端訪問應用系統時,請求首先將進入服務網關,由於它是全部請求調用的中心,咱們也將其稱爲「調用中心」。它雖然是不帶任何業務的中心,但咱們須要確保它所作的事情足夠少,讓它不會成爲整個應用系統的調用瓶頸。
隨後調用中心將鏈接註冊中心,並經過服務名稱從註冊中心中獲取服務所在的IP地址與端口號(即服務地址),該過程稱爲「服務發現」,進而調用中心可根據服務地址以反向代理的方式來調用具體的服務容器,該過程稱爲「服務調用」。
在服務容器中可能會觸發一些事件,這些事件將以消息的方式寫入消息中心,以便其餘服務可監聽消息中心並從中獲取相應的消息。該方案可解決服務之間的耦合問題,同時能將同步調用轉爲異步調用,提升整個應用系統的吞吐率。
在服務容器運行時會產生大量的日誌,咱們可將這些日誌統一寫入日誌中心,並能在日誌中心所提供的控制檯上查詢具體的日誌信息。此外,日誌中心也能幫助咱們快速地定位並分析系統出現的異常情況。
爲了觀察服務容器是否運行正常,咱們可藉助監控中心所輸出的圖形化數據來判斷。監控中心將不斷地收集服務容器中的運行狀態,包括CPU、內存、硬盤、網絡,以及應用程序的JVM內存使用狀況。
因爲微服務很難切得乾淨,服務之間不免會出現少許的調用關係,咱們可將每次調用所產生的相關信息寫入追蹤中心,並經過追蹤中心提供的圖形化界面來查看服務之間的調用軌跡以及所產生的調用延時,從而可分析出服務調用所產生的性能瓶頸。
咱們可將以上過程繪製爲一幅架構圖,如圖1-11所示。
圖1-11 輕量級微服務運行架構
可見,在微服務運行階段中,調用中心是其中的主角,註冊中心做爲它的數據來源,服務容器做爲它的調用目標,它須要具有良好的高性能與高可用等特性。
3. 輕量級微服務全局架構
咱們用一張圖將輕量級微服務的部署架構與運行架構進行整合,它就是輕量級微服務架構的全貌,如圖1-12所示。
圖1-12 輕量級微服務全局架構
圖1-12所示的架構圖中包括12個組件,其中的代碼倉庫、部署中心、註冊中心、鏡像倉庫、調用中心、服務容器這6個組件已在上冊中進行描述,剩下的配置中心、文檔站點、消息中心、日誌中心、監控中心、追蹤中心這6個組件將在下冊後續章節中深刻探索。
本章從宏觀上描述了輕量級微服務架構,爲後續探險歷程提供了明確的藍圖。首先咱們從架構與架構師開始講起,簡單回顧了架構演進的過程與微服務的發展趨勢,咱們認爲,微服務的出現是必然的,並且它將朝着輕量級方向發展。隨後咱們探討了在搭建微服務架構以前須要準備的工做,也認識了微服務架構的「冰山模型」,本書將重點集中在冰山之下的微服務基礎設施中,此外還介紹了切分微服務邊界的方法和技巧,咱們認爲,合理地切分微服務邊界是微服務架構師的職責之一。最後咱們從部署與運行兩個角度來觀察微服務架構,並以一幅架構全景圖來結束本章,隨後的章節將圍繞這張架構圖的相關部分進行展開,咱們會選擇最爲合適的技術選型來搭建這款輕量級微服務架構。