注: 原文做者即 Micro 框架的開發者。html
過去幾個月中,咱們收到了不少關於 micro 的微服務架構和設計模式的問題。因此今天咱們試着解釋一下這兩方面的問題。ios
Micro 是一個微服務工具集。它被用來實現它的特性和接口,同時提供強大的可插拔的架構來保證基礎組件能夠被替換掉。git
Micro 專一於解決構建微服務系統的基礎需求。它採用了深思熟慮地富有預見性的方式來實現它的設計。github
若是你想深刻研究 Micro 工具集請點這裏查看上一篇博客,或者若是你想學習微服務的基本概念請查看這裏web
在咱們開始討論 Micro 的架構以前,咱們將快速的介紹一下 Micro 的特性.算法
Go Micro是一個用 GO 來寫微服務的、可插拔的 RPC 框架。它提供了服務發現,客戶端負載均衡,編碼,同步異步通信等功能的庫。數據庫
Micro API 是爲訪問微服務提供了 HTTP 服務和路由功能的 API 網管。在 Micro 中,它提供一個單一的入口,它能夠被用做反向代理,或者將 HTTP 請求轉換成 RPC.後端
Micro Web 是微型網絡應用(micro web application)的儀表盤和反向代理。咱們相信 web 應用應該被構建成微服務所以應被看作微服務世界的一等公民。它像一個 API 的反向代理但它同時提供對 web socket 的支持。設計模式
Micro Sidecar 提供將 go-micro 用做 HTTP 服務的全部功能。Sidecar 提供使用其餘語言寫微服務應用的途徑。api
Micro CLI 是和你的微服務們交互的命令行接口。它還可讓你在不想直接鏈接服務的時候使用 Sidecar 做爲一個代理。
下面讓咱們更深刻的瞭解。
你的第一個疑問可能就是,爲何是 RPC 而不是 REST? 咱們認爲 RPC 更適合內部服務通訊的場景。或者更具體的, 使用 protobuf 編碼而且用 protobuf IDL 定義 API 的 RPC。聯合使用這些技術可以很方便的建立強定義的 API 接口和有效的消息編碼。RPC 是很是直觀的通訊協議。
咱們並非這一信條的獨立擁護者。
Google 是 protobuf 的創造者,在內部使用 RPC 而且最近開源的 RPC 框架 gRPC. Hailo 一樣也是 RPC/Protobuf 的強烈倡導者,並從中受益不淺,更有趣的是在跨團隊協助方面得到的收益比系統性能上的收益更多。Uber 正則開發資金的 PRC 框架協議 TChannel。
我我的認爲將來的 API 應該是使用 RPC 構建的,由於它有諸如 protobuf 這類的有良好的結構化的格式,有易用高效的編碼方法的協議,從而能構建強定義的 API 和高效的通信。
然而在現實中,在 web 上使用 RPC 還有很長的路要走。儘管在數據中心內部使用 RPC 很完美,可是支撐高併發的網站和移動 API 又是另外一回事。好吧,徹底從 HTTP 切換到 RPC 來由很長的路要走。這也是爲何 micro 提供了 API 網關組件,來支撐和轉換 HTTP 請求。
API gateway 是微服務架構中使用的一種模式。它是微服務和外界溝通的惟一入口,它根據 HTTP 請求調用對應的服務。API gateway 使一個 HTTP API 可以組合調用多個不一樣的微服務。
這是一個很強大的模式。因 API 一部分的更改致使整個單一部署的服務掛掉的日子將一去不復返。
微服務 API 使用 路徑-服務 的解決方案,所以每一個請求路徑可以調用不一樣的微服務 API,例如 /user => user api, /order => order api
舉個例子,到 /customer/orders 的請求將被帶着方法名 Customer.Orders 轉發到 API go.micro.api.customer 。
你可能好奇, API 服務究竟是什麼。如今咱們來討論不一樣類型的服務。
微服務的概念主要是按關注點分離 -- 從著名的 unix 哲學 doing one thing and doing it well 中借鑑了不少。出於這個緣由,咱們認爲有必要從邏輯上和架構上將擁有不一樣任務的服務分離。
這些概念並非什麼新的概念,最近變得很引人注目是由於它被一些很是成功的技術公司證實是可行的。咱們的目標是推廣這些開發哲學並經過構建工具鏈來指導設計決策。
如下是咱們定義的服務的類型。
API - 基於 micro api,API 服務在設施的最頂端,通常直接支撐你的移動或 web 應用。你可使用 HTTP handler 建造它而後使用反向代理模式啓動 micro api,或者,默認狀況下處理這種專門格式的 RPC API 請求和響應。
Web - 基於 micro web, 專門用來提供 html 內容和管理面板訪問的 Web 服務。micro web 爲 HTTP 和 WebSockets 提供反向代理。目前,僅支持這兩週格式,將來可能會支持更多的格式。就像以前提到過的那樣,咱們相信 「web 應用即微服務」。
SRV - 基於 RPC 的後端服務。它們主要關注於爲你的系統提供核心功能而且大多數狀況下不會對外開放。若是你願意,你仍可使用 micro api 或 micro web 使用 /rpc 路徑來訪問它,但通常使用 go-micro 客戶端來直接調用它們。
基於以往的經驗,咱們發現這種架構模式及其強大而且見到過使用它支撐數百個微服務的系統。
Namespacing(命名空間)
你可能會好奇,如何隔斷 micro api 和 micro web 之間的通訊?咱們使用邏輯命名空間裏作分離。經過給服務名加前綴(prefix)咱們清晰的肯定它的意圖以及它在系統中的位置。這個簡單但有效的模式讓咱們受益良多。
micro api 和 micro web 將組成由命名空間和請求路徑的第一個路徑組成的服務名稱。例如,訪問 api/customer 的請求變爲 go.micro.api.customer。
默認的命名空間爲:
咱們常常聽到微服務和響應式模式一同出現。對於大多數來講,微服務是建立事件驅動的架構,而且主要經過異步通訊的服務。
Micro 將異步通訊做爲一等公民對待而且將其構建成爲微服務的基礎組成部分之一。經過與事件異步通訊的方式容許任何人消費這些事件,並針對這些事件執行本身的任務。能夠在此基礎上新的單獨部署的服務而不須要需改他們的其餘任何方面。這是一個強大的設計模式而且正因爲此咱們在 go-micro 中實現了一個異步的 broker 接口。
在 Micro 中,同步和異步通訊被放到隔離的需求中。Transport 接口用來建立服務間點對點的鏈接。構建在 transport 基礎上的 go-micro 客戶端和服務器可以提供請求-響應模式的 RPC 調用,也能夠提供雙向流模式下的調用。
在構建系統時兩種通訊模型都應該被使用,但關鍵是要理解何時,在哪兒用哪一種方式更合適。不少狀況下,沒有對錯,可是咱們仍是要權衡兩種的利弊。
舉個例子,在製做用來保存跟蹤用戶操做歷史的審計系統時,broker 和異步通訊可能更合適。
在這個例子中,每一個 AI 或者說服務,當一些動做發生(客戶登陸,更新簡介或下訂單)時都會肺部一個事件。審計服務將會訂閱這些事件並將它們存儲到按時間序列存儲的數據庫中。管理員或其餘任何用戶都能看到任何用戶產生的任何事件發生的歷史。
若是這個系統被設計成同步的,當流量高或服務數量增長時,審計系統很容易被壓垮。若是審計系統宕機或者請求失敗咱們可能會丟失這條歷史記錄。經過將這些事件發佈給 broker 咱們能保持他們異步。這是事件驅動型架構構建的微服務的一種通用模式。
咱們講了不少 Micro toolkit 提供的功能,也定義了不少類型的服務(API, WEB, SRV)可是並沒怎麼講微服務究竟是什麼。
關於微服務的定義和解釋有不少,但這組是最合適的。
基於有限上下文的架構的低耦合的服務
--Adrian Cockcroft
將單個應用開發爲一組跑在獨立進程上而且互相之間使用輕量級方法進行通訊的微小的服務
--Martin Fowler
就像 unix 哲學說的那樣 Do one thing and do it well
--Doug McIlroy
咱們認爲一個微服務就是一個專一於一個實體(或領域)的應用 -- 而且經過強定義的 API 訪問它。
讓咱們拿社交網絡來舉個現實中的例子。
有一個軟件架構模式隨着 Ruby On Rails 的崛起而變得流行 -- 那就是 MVC(模型 -- 視圖 -- 控制)。
在 MVC 的世界裏,每一個實體,或者說,域,都被表示爲一個從數據庫中抽象而來的模型。模型可能和其餘模型之間有相互關係,好比說一對多,多對多。控制層處理收到的請求,從 model 中查詢數據,而後把它傳遞給用戶,從而展示給用戶。
如今舉一個微服務架構中一樣的例子。模型被服務取而代之,它經過 API 傳遞數據。用戶請求,數據收集和數據呈現由多個 web service 處理。
每一個服務都有一個單一的關注點。當咱們想添加一個新功能或新的實體時,咱們能夠簡單的修改關注於那個功能的服務或者直接寫一個新的服務。這種分離的方式提供了可以很好 scale 的軟件開發方式。
接下來咱們迴歸正題。
版本管理是現實軟件開發中重要的一部分。在微服務的世界中很重要的一點是 API 和業務邏輯是被分紅不少不一樣的服務的。正因爲此,服務的版本控制很重要,被放到核心工具庫中,提供更好的細粒度的控制和升級過程當中的流量遷移。
在 go-micro 中服務有一個名字和版本號定義。倉庫(Registry)返回一個 list 表示一個服務 -- 經過節點
註冊時的版本號來區分這些節點。
這是咱們用於構建基於版本的路由功能的構建模塊的一段代碼
type Service struct { Name string Version string Metadata map[string]string Endpoints []*Endpoint Nodes []*Node }
它和 Selector -- 一個客戶端的負載均衡 -- 結合起來使用,從而在 go-micro 內部保證請求分發到不一樣的版本上去。
Selector 是一個強大的接口。咱們在它之上提供不一樣類型的路由算法:隨機(默認),round robin(環形隊列?),基於標籤,基於延遲,等等。
經過默認的基於隨機哈希的負載均衡算法,並逐步將新版本的服務實例加入,你能夠執行藍綠髮布(link)並實行金絲雀測試。
將來咱們會實現一個內嵌 selector 的面向全球服務的負載均衡服務來提供爲既存的系統作路由決策。它還能勝任在運行時爲不一樣版本的服務分配不一樣的負載的職能,而且能動態地爲服務添加原信息或標籤,從而在此之上能夠作動態的路由決策。
上文關於版本控制的說明經已說起了伸縮一個服務使用的基礎模型。倉庫(registry)用來存儲服務的相關信息,selector 用來控制路由和負載均衡。
咱們再一次實踐了關注點分離(separation of concoerns)和作一件事並把它作好(dooing one thing well)的哲學。伸縮基礎設施、代碼很依賴於簡化、強定義的 API 以及分層的架構。經過編寫上面那些構建模塊,咱們可以開發伸縮性更強的軟件系統,並專一於更高層面的東西。
這是 Micro 的基礎,也是在微服務世界裏咱們但願引領的軟件開發的方式。
在以前的文章 Micro on NATS中咱們簡要討論了關於雲端架構模型的問題。如今咱們簡單回顧下其中的一些觀點。
當在生產環境部署服務時,你但願你的系統是可伸縮的、能容錯的、以及性能優異的。雲計算使咱們能構建有很強伸縮性能的服務,但很難不受錯誤影響。事實上容錯性是構建分佈式系統時最關鍵的考察點之一。因此在構建基礎設施時,咱們應該充分考慮容錯性。
在雲的世界裏,咱們但願能容忍可用區的錯誤,甚至是整個區域中斷。過去,咱們嘗試經過熱備份,冷備份或者災難恢復計劃來應對。如今,技術最早進的公司們有一個國際慣例,那就是把每一個應用製做多個副本跑在世界各地的多個數據中心上。
咱們須要向 Google, Facebook, Netflix 和 Twitter 學習。咱們必須保證咱們構建的系統能在可用區失敗時不影響用戶並且在大多數狀況下在數分鐘內解決可用區失敗。
經過提供可插拔的接口, Micro 能夠構建這樣的架構。咱們能爲 micro toolkit 中的每一個需求選用最合適的分佈式系統。
服務發現和倉庫(registry)是 Micro 的構建模塊。他能用來在可用區,區域或其餘配置範圍內隔離和發現服務。
而後 Micro API 可以在這個拓補結構中路由以及負責均衡一系列的服務。
Microservices is first and foremost about software design patterns. We can enable certain foundational patterns through tooling while providing flexibility for other patterns to emerge or be used.
Because Micro is a pluggable architecture it’s a powerful enabler of a variety of design patterns and can be appropriately used in many scenarios. For example if you’re building video streaming infrastructure you may opt for the HTTP transport for point to point communication. If you are not latency sensitive then you may choose a transport plugin such as NATS or RabbitMQ instead.
The future of software development with a tool such as Micro is very exciting.
If you want to learn more about the services we offer or microservices, check out the blog, the website micro.mu or the github repo.
但願這篇文章講清了 Micro 的架構和它如何使用可伸縮的設計模式來開發微服務應用。 微服務首先是一種軟件設計模式。 .... 感受後面沒啥用,就略了...