在公司學習了接近一個月。 html
一個月內,從0開始開始接觸分佈式微服務架構,給了我不小的收穫。今天,我來從頭至尾梳理一下,有關微服務架構的核心內容(全是乾貨)。java
下文,你將看到業界主流微服務框架的核心原理,包括服務發現,網關,配置中心,監控等組件,功能和架構原理的簡單介紹。感謝閱讀!😋linux
想要解鎖更多新姿式?請訪問個人博客。😏ios
微服務Microservices之父,馬丁.福勒,對微服務大概的概述以下:git
就目前而言,對於微服務業界並無一個統一的、標準的定義(While there is no precise definition of this architectural style ) 。
但通在其常而言,微服務架構是一種架構模式或者說是一種架構風格,它提倡將單一應用程序劃分紅一組小的服務,每一個服務運行獨立的本身的進程中,服務之間互相協調、互相配合,爲用戶提供最終價值。服務之間採用輕量級的通訊機制互相溝通(一般是基於 HTTP 的 RESTful API ) 。每一個服務都圍繞着具體業務進行構建,而且可以被獨立地部署到生產環境、類生產環境等。
另外,應儘可能避免統一的、集中式的服務管理機制,對具體的一個服務而言,應根據業務上下文,選擇合適的語言、工具對其進行構建,能夠有一個很是輕量級的集中式管理來協調這些服務。可使用不一樣的語言來編寫服務,也可使用不一樣的數據存儲。
根據馬丁.福勒的描述,我總結了一下幾點:github
(字差,勿嫌)spring
小服務,沒有特定的標準或者規範,但他在整體規範上必定是小的。docker
每一組服務都是獨立運行的,可能我這個服務運行在tomcat
容器,而另外一個服務運行在jetty
上。能夠經過進程方式,不斷的橫向擴展整個服務。數據庫
過去的協議都是很重的,就像ESB,就像SOAP,輕通訊,着意味着相比過去更智能更輕量的服務相互調用,就所謂smart endpoints and dumb pipes,這些endpoint都是解耦的,完成一個業務通訊調用串起這些micro service就像是linux系統中經過管道串起一系列命令業務。segmentfault
過去的業務,咱們一般會考慮各類各樣的依賴關係,考慮系統耦合帶來的問題。微服務,可讓開發者更專一於業務的邏輯開發。
不止業務要獨立,部署也要獨立。不過這也意味着,傳統的開發流程會出現必定程度的改變,開發的適合也要有必定的運維指責
傳統的企業級SOA服務每每很大,不易於管理,耦合性高,團隊開發成本比較大。微服務,可讓團隊各思其政的選擇技術實現,不一樣的service能夠根據各自的須要選擇不一樣的技術棧來實現其業務邏輯。
爲何用微服務呢?由於好玩?
不是的。下面是我從網絡上找到說的比較全的優勢:
- 優勢每一個服務足夠內聚,足夠小,代碼容易理解這樣能聚焦一個指定的業務功能或業務需求
- 開發簡單、開發效率提升,一個服務可能就是專注的只幹一件事。
- 微服務可以被小團隊單獨開發,這個小團隊是 2 到 5 人的開發人員組成。
- 微服務是鬆藕合的,是有功能意義的服務,不管是在開發階段或部署階段都是獨立的。
- 微服務能使用不一樣的語言開發。
- 易於和第三方集成,微服務容許容易且靈活的方式集成自動部署,經過持續集成工具,如Jenkins,Hudson,bamboo。
- 微服務易於被一個開發人員理解,修改和維護,這樣小團隊可以更關注本身的工做成果。無需- - 經過合做才能體現價值。微服務容許你利用融合最新技術。
- 微服務只是業務邏輯的代碼,不會和 HTML,CSS或其餘界面組件混合。
- 每一個微服務都有本身的存儲能力,能夠有本身的數據庫。也能夠有統一數據庫。
總的來講,微服務的優點,就是在於,面對大的系統,能夠有效的減小複雜程度,使服務架構的邏輯更清晰明瞭。
可是這樣也會帶來不少問題,就譬如分佈式環境下的數據一致性,測試的複雜性,運維的複雜性。
微服務帶了種種優勢,種種弊端,那麼什麼組織適合使用微服務?
康威定律,是一個五十多年前就被提出來的微服務概念。在康威的這篇文章中,最有名的一句話就是:
Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations. - Melvin Conway(1967)
中文直譯大概的意思就是:設計系統的組織,其產生的設計等同於組織以內、組織之間的溝通結構。看看下面的圖片(來源於互聯網,侵刪),再想一想Apple的產品、微軟的產品設計,就能形象生動的理解這句話。
感興趣的各位能夠研究一下
架構是不斷演化出來的,微服務也是這樣,當從各大科技公司,規模大到必定程度,徹底須要演化成更進一步管理的技術架構體系。
(字差,勿嫌)
傳統的團隊,都是面向過程化的,產品想完了去找策劃,策劃完了找開發,接着順着一步一步找。咱們作技術都是爲了產品的,一旦過程出來了什麼問題,回溯尋找問題會很是耗時。
(字差,勿嫌)
使用了微服務架構體系,團隊組織方式須要轉變成跨職能團隊,即每一個團隊都有產品專家,策劃專家,開發專家,運維專家,他們使用API方式發佈他們的功能,而平臺使用他們的功能發佈產品
下面我分享一下大部分公司都使用的微服務技術架構體系。
(圖差,勿嫌)
主流的服務發現,分爲三種
第一種,開發人員開發了程序之後,會找運維配一個域名,服務的話經過dns就能找到咱們對應的服務
缺點是,因爲服務沒有負載均衡功能,對負載均衡服務,可能會有至關大的性能問題。
第二種,是目前廣泛的作法。能夠參考我上篇博客分析的zuul網關,每個服務都經過服務端內置的功能註冊到註冊中心,服務消費者不斷輪詢註冊中心發現對應的服務,使用內置負載均衡調用服務。
缺點是,對多語言環境不是很好,你須要單獨給消費者的客戶端開發服務發現和負載均衡功能。固然了,這個方法一般都是用在spring cloud
上的。
第三種,是將客戶端和負載均衡放在同一個主機,而不是同一個進程內。
這種方法相對第一種第二種方法來講,改善了他們的缺點,可是會極大增長運維成本。
咱們能夠聯繫生活實際想一下。每個大的公司,都會有一偏屬於本身的建築區,而這建築區內,都有很多的門衛。若是有外來人員進入公司,會先和門衛打好招呼,才能進去。
將生活實際聯繫到微服務上,就不難理解網關的意思了。
zuul
網關核心實際上是一個servlet
,全部請求都會通過zuul servlet
傳到zuulFilter Runner
,而後分發到三種過濾器。
先說說架構圖左半部分,分別是使用Groovy
實現的前置路由過濾器,路由過濾器,後置路由過濾器。
通常請求都會先通過前置路由過濾器處理,通常的自定義java封裝邏輯也會在這裏實現。
路由過濾器,實現的是找到對應的微服務進行調用。
調用完了,響應回來,會通過後置路由過濾器,經過後置路由過濾器咱們能夠封裝日誌審計的處理。
能夠說zuul
網關最大的特點就是它三層過濾器。
架構圖右半部分,是zuul
網關設計的自定義過濾器加載機制。網關內部會有生產者消費者模型,自動的將過濾器腳本發佈到zuul
網關讀取加載運行。
之前,開發人員把配置文件放在開發文件裏面,這樣會有不少隱患。譬如,配置規範不一樣,沒法追溯配置人員。一旦須要大規模改動配置,改動時間會很長,沒法追溯配置人員,從而影響整個產品,後果是咱們承擔不起的。
所以就有配置中心這個嘍~
如今的開源中心有百度配置中心 Disconf,spring cloud config,Apollo,今天重點說說如今應用質量不錯的配置中心阿波羅。
開源地址👉:https://github.com/ctripcorp/...
apollo的配置中心規模比較大,本地應用會有響應的配置中心客戶端,能夠定時同步配置中內心的配置。若是配置中心怠機,會使用緩存來進行配置。
關於通信方式,通常市面也就是兩種遠程調用方式,我整理了一個表格:
RPC | REST | |
---|---|---|
耦合性 | 強耦合 | 鬆散耦合 |
消息協議 | TCP | HTTP |
通信協議 | 二進制 | 文本XML,Json |
性能 | 高 | 低於RPC |
接口契約IDL | thrift,protobuf,IdL | Swagger |
客戶端 | 強類型客戶端,通常自動生成 | 通常HTTP可訪問,生成強類型客戶端,多語言支持好 |
案例 | Dubbo,Dubbox,motan,tars,grpc,thrift | spring boot,tax-rs,dropwizard |
開發者友好 | 客戶端比較方面,二進制消息不能讀 | 可讀消息 |
對外開放 | 通常須要轉成REST/文本協議 | 可直接對外開發 |
監控預警對於微服務很重要,一個可靠的監控預警體系對微服務運行相當重要。通常監控分爲以下層次:
從基礎設施到用戶端,層層有監控,全方位,多角度,每個層面都很重要。整體來講,微服務可分5個監控點:日誌監控,Metrics監控,健康檢查,調用鏈檢查,告警系統
下面的圖是大部分公司的一種監控架構圖。每個服務都有一個agent
,agent
收集到關鍵信息,會傳到一些MQ中,爲了解耦。同時將日誌傳入ELK,將Metrics傳入InfluxDB時間序列庫。而像nagios,能夠按期向agent發起信息檢查微服務。
不少公司都有調用鏈監控,就譬如阿里有鷹眼監控,點評的Cat,大部分調用鏈監控(沒錯,我指的Zipkin
)架構是這樣的👇
當請求進入Web容器的時候,會通過建立Tracer
,鏈接spans
(模擬潛在的分佈式工做的延遲,該模塊還包含在系統網絡間傳遞跟蹤上下文信息的工具包,如經過http headers)。Spans
有一個上下文,其中包含tracer
標識符,將其放在表示分佈式操做的樹的正確位置。當咱們把圖中的各類span放到後端的時候,咱們的服務調用鏈會動態的生成調用鏈。
下面是一些市場上用的比較多的調用鏈監控:
一、Pinpoint
github地址:GitHub - naver/pinpoint: Pinpoint is an open source APM (Application Performance Management) tool for large-scale distributed systems written in Java.
對java領域的性能分析有興趣的朋友都應該看看這個開源項目,這個是一個韓國團隊開源出來的,經過JavaAgent的機制來作字節碼代碼植入,實現加入traceid和抓取性能數據的目的。
NewRelic、Oneapm之類的工具在java平臺上的性能分析也是相似的機制。
二、SkyWalking
github地址:wu-sheng/sky-walking
這是國內一位叫吳晟的兄弟開源的,也是一個對JAVA分佈式應用程序集羣的業務運行狀況進行追蹤、告警和分析的系統,在github上也有400多顆星了。
功能相對pinpoint仍是稍弱一些,插件還沒那麼豐富,不過也很可貴了。
三、Zipkin
官網:OpenZipkin · A distributed tracing system
github地址:GitHub - openzipkin/zipkin: Zipkin is a distributed tracing system
這個是twitter開源出來的,也是參考Dapper的體系來作的。
Zipkin的java應用端是經過一個叫Brave的組件來實現對應用內部的性能分析數據採集。
Brave的github地址:https://github.com/openzipkin/brave
這個組件經過實現一系列的java攔截器,來作到對http/servlet請求、數據庫訪問的調用過程跟蹤。
而後經過在spring之類的配置文件里加入這些攔截器,完成對java應用的性能數據採集。
四、CAT
github地址:GitHub - dianping/cat: Central Application Tracking
這個是大衆點評開源出來的,實現的功能也仍是蠻豐富的,國內也有一些公司在用了。
不過他實現跟蹤的手段,是要在代碼裏硬編碼寫一些「埋點」,也就是侵入式的。
這樣作有利有弊,好處是能夠在本身須要的地方加埋點,比較有針對性;壞處是必須改動現有系統,不少開發團隊不肯意。
五、Xhprof/Xhgui
這兩個工具的組合,是針對PHP應用提供APM能力的工具,也是非侵入式的。
Xhprof github地址:GitHub - preinheimer/xhprof: XHGUI is a GUI for the XHProf PHP extension, using a database backend, and pretty graphs to make it easy to use and interpret.
Xhgui github地址:GitHub - perftools/xhgui: A graphical interface for XHProf data built on MongoDB
我對PHP不熟,不過網上介紹這兩個工具的資料仍是蠻多的。
面對巨大的突發流量下,大型公司通常會採用一系列的熔斷(系統自動將服務關閉防止讓出現的問題最大化)、隔離(將服務和服務隔離,防止一個服務掛了其餘服務不能訪問)、限流(單位時間內之容許必定數量用戶訪問)、降級(當整個微服務架構總體的負載超出了預設的上限閾值或即將到來的流量預計將會超過預設的閾值時,爲了保證重要或基本的服務能正常運行,咱們能夠將一些 不重要或 不緊急 的服務或任務進行服務的 延遲使用 或 暫停使用)措施。
下面介紹一下hystrix
的運行流程(沒找到架構圖很差意思):
每個微服務調用時,都會使用hystrix
的command
方式(上圖的左上角那個),而後使用command
同步的,或者是響應式的,或者是異步的,判斷電路是否熔斷(順着圖從左往右看),
若是斷路則走降級fallback;
若是這個線閉合着,可是線程資源沒了,隊列滿了,則走限流措施(看圖的第5步);
若是走完了,執行成功了,則走run()方法,獲取response,可是這個過程若是出錯了,則繼續走降級fallback.
同時,看圖最上面有一個後綴是health
的,這是一個計算整個鏈路是否健康的組件,每一步操做都被它記錄着。
從物理機到虛擬機,從虛擬機到容器;從物理集羣到open stack
,open stack
到kubernetes
;科技不斷的變化,咱們的認知也沒刷新。
咱們從容器開始提及,它首先是一個相對獨立的運行環境,在這一點有點相似於虛擬機,可是不像虛擬機那樣完全。
虛擬機會將虛擬硬件、內核(即操做系統)以及用戶空間打包在新虛擬機當中,虛擬機可以利用「虛擬機管理程序」運行在物理設備之上。虛擬機依賴於hypervisor,其一般被安裝在「裸金屬」系統硬件之上,這致使hypervisor在某些方面被認爲是一種操做系統。一旦 hypervisor安裝完成, 就能夠從系統可用計算資源當中分配虛擬機實例了,每臺虛擬機都可以得到惟一的操做系統和負載(應用程序)。簡言之,虛擬機先須要虛擬一個物理環境,而後構建一個完整的操做系統,再搭建一層Runtime,而後供應用程序運行。
對於容器環境來講,不須要安裝主機操做系統,直接將容器層(好比LXC或libcontainer)安裝在主機操做系統(一般是Linux變種)之上。在安裝完容器層以後,就能夠從系統可用計算資源當中分配容器實例了,而且企業應用能夠被部署在容器當中。可是,每一個容器化應用都會共享相同的操做系統(單個主機操做系統)。容器能夠當作一個裝好了一組特定應用的虛擬機,它直接利用了宿主機的內核,抽象層比虛擬機更少,更加輕量化,啓動速度極快。
相比於虛擬機,容器擁有更高的資源使用效率,由於它並不須要爲每一個應用分配單獨的操做系統——實例規模更小、建立和遷移速度也更快。這意味相比於虛擬機,單個操做系統可以承載更多的容器。雲提供商十分熱衷於容器技術,由於在相同的硬件設備當中,能夠部署數量更多的容器實例。此外,容器易於遷移,可是隻能被遷移到具備兼容操做系統內核的其餘服務器當中,這樣就會給遷移選擇帶來限制。由於容器不像虛擬機那樣一樣對內核或者虛擬硬件進行打包,因此每套容器都擁有本身的隔離化用戶空間,從而使得多套容器可以運行在同一主機系統之上。咱們能夠看到所有操做系統層級的架構均可實現跨容器共享,唯一須要獨立構建的就是二進制文件與庫。正由於如此,容器才擁有極爲出色的輕量化特性。
咱們最經常使用的容器是daocker,網址以下👉https://www.docker.com/
過去虛擬機能夠經過雲平臺open stack
管理虛擬化,容器時代如何管理容器呢?這就要看看容器編排引擎了。
mesos是基於master,slave架構,框架決定如何利用資源,master負責管理機器,slave會按期的將機器狀況報告給master,master再將信息給框架。master是高可用的,由於zk,也有leader的存在。下面是架構圖👇
kubernetes是最近十分火熱的開源容器編排引擎,具體能夠參考kubernetes中文文檔
Kubernetes設計理念和功能其實就是一個相似Linux的分層架構,先說說每個Kubernetes節點內部,kubelet管理全局全局pod,而每個pod承載着一個或多個容器,kube-proxy負責網絡代理和負載均衡 。
Kubernetes節點外部,則是對應的控制管理服務器,負責統一管理各個節點調度分配與運行。
。。。待更新
調用鏈選型之Zipkin,Pinpoint,SkyWalking,CAT
此片完了~ 想要了解更多精彩新姿式?
請訪問個人我的博客
本篇爲原創內容,已在我的博客率先發表,隨後看心情可能會在CSDN,segmentfault,掘金,簡書,開源中國同步發出。若有雷同,緣分呢兄弟。趕快加個好友,我們兩個想個號碼, 買個彩票,先掙他個幾百萬😝