如何快速搭建一個 “簡單模式” 的微服務架構

程式設計師生態圈發表於2018-08-23

這篇文章,我們就分享一下如何搭建一個簡單模式的微服務架構。

 


本篇文章屬於轉載,維權請聯絡小編刪除

何謂微服務架構的簡單模式?

 

相對於大型網際網路平臺動輒幾萬併發的訪問量,或者每天多次的線上版本釋出,絕大多數企業和專案並沒有這樣的需求。他們關注的是如何更好地提高開發效率,如何更快地實現新需求,如何更便利地運維,等等。

微服務架構的簡單模式就是可以滿足以上需求的軟體架構方案。

相對於“完美”的微服務架構方案,微服務架構簡單模式可以暫且不用關注保障資料一致性的分散式事務技術、方便程式包在環境間(開發、測試、生產)遷移的配置中心元件、監控 API 呼叫情況的呼叫鏈元件、避免系統超載的斷路器元件、方便 API 管理和測試的 API 文件框架、Zookeeper、Redis,以及各種 MQ。只需要關注常常談到的註冊中心、服務發現、負載均衡服務閘道器即可。

 

如何落地?

落地微服務架構,重點就是發揚優點,克服缺點。相對於單體架構,微服務架構最大的缺點是 上手難 和 運維難。下面我們就來看看如何從這兩個方面入手,將微服務架構的簡單模式落地。

 

上手難

相對於傳統的單體架構,微服務架構一下子引入了太多的概念,讓新手有點無可適從。所以,我們更要去蕪存菁,理清楚哪些是自身需要的,哪些只是江湖上的傳說。下面就來看看哪些元件是開發一個微服務架構的系統所必需的。

首先說一下,使用微服務簡單模式進行開發的四個步驟:

第一步:沿用組織中現有的技術體系開發單一職責的微服務。

第二步:服務提供方將地址資訊註冊到註冊中心,呼叫方將服務地址從註冊中心拉下來。

第三步:通過門戶後端(服務閘道器)將微服務 API 暴露給門戶和移動 APP。

第四步:將管理端模組整合到統一的操作介面上。

 

為了實現以上 4 點,相對應的就是下面必需掌握的基礎技術(必需的元件)。

註冊中心、服務發現、負載均衡:對應上邊第一步與第二步

服務閘道器:對應上邊第三步

管理端整合框架:對應上邊第四步

 註冊中心、服務發現、負載均衡

和單體架構不同,微服務架構是由一系列職責單一的細粒度服務構成的 分散式網狀結構,服務之間通過輕量機制進行通訊,這時候必然引入一個 服務註冊發現 問題,也就是說服務提供方要將自己的服務地址註冊到某個地方(服務註冊中心, Service Registry Center),服務的呼叫方可以從服務註冊中心找到需要呼叫的服務的地址(服務發現,Service Discovery)。同時,服務提供方一般以叢集方式提供服務,也就引入了 負載均衡 的需求。

根據負載均衡(Load Balancer,簡稱 LB)所在位置的不同,目前主要的服務註冊、發現和負載均衡方案有三種:

集中式 LB 方案

第一種是集中式 LB 方案,在服務消費者和服務提供者之間有一個獨立的 LB,LB 通常是專門的硬體裝置如 F5,或者基於軟體如 LVS,HAproxy 等實現。

服務呼叫者呼叫服務時,向 LB 發起請求,LB 再根據一定的策略(比如輪詢、隨機、最小響應時間、最小併發數等等)將請求路由到指定的服務。這個方案的最大問題是:呼叫者和提供者之間增加了一跳,LB 也最有可能成為整個系統的瓶頸

程式內 LB 方案

第二種是程式內 LB 方案,針對集中式 LB 的不足,程式內 LB 方案將 LB 的功能以庫的形式整合到服務消費方程式裡頭,該方案也被稱為軟負載 (Soft Load Balancing) 或者客戶端負載方案。

其原理是:服務提供者將自身的地址傳送到服務註冊中心,同時定時傳送心跳給註冊中心,註冊中心按心跳情況判斷是否將此節點從登錄檔中摘除。服務呼叫者呼叫服務時,先從註冊中心拉取服務註冊資訊,然後根據一定的策略去呼叫服務節點。

這種情況下,即使註冊中心當機,呼叫方也可以根據記憶體中已經拉到的服務地址將請求路由到正確的服務上去。這個方案的最大問題是:服務呼叫者可能需要整合註冊中心的客戶端,即將來註冊中心服務端升級,可能會需要升級註冊中心客戶端

主機獨立 LB 程式方案

第三種是主機獨立 LB 程式方案,該方案是針對第二種方案的不足而提出的一種折中方案,原理和第二種方案基本類似,不同之處是,他將 LB 和服務發現功能從程式內移出來,變成主機上的一個獨立程式,主機上的一個或者多個服務要訪問目標服務時,他們都通過同一主機上的獨立 LB 程式做服務發現和負載均衡。該方案的典型案例是 Airbnb 的 SmartStack 服務發現框架。這個方案的最大問題是:部署和運維比較麻煩

溫馨提示 : 微服務架構交流群:628134587


 

當下,隨著 Netflix 的微服務方案和 Spring Cloud 的興起與成熟,第二個方案 成為我們的首選。我們推薦使用 Eureka 做服務註冊中心,Ribbon 做客戶端服務發現和負載均衡。

這個選擇的最大好處是 簡單 + 實用 + 可控,不用引入額外的 Zookeeper、Etcd 做註冊中心,部署和運維也都比較簡單。從程式碼上來說,使用起來也非常簡單。

只是,需要注意的是,這種方案一般是用來做 區域網內 的負載均衡,如果要為開放到網際網路的服務做負載均衡,可以使用 Nginx Upstream 來做。

下面是 Eureka 最重要的幾個引數配置,從這些引數也可以大概看看 Eureka 是如何工作的。

由於 Eureka 的註冊及過期機制,服務從啟動到完全可用需要近 2 分鐘的時間,所以,為了提高開發及測試環境中的發版速度,我們改了以下幾個引數。生產時,一定要改回去。

Eureka 註冊中心的介面如下:

 

 服務閘道器

通常,一個大系統裡會有很多職責單一的微服務,如果門戶系統或移動 APP 來呼叫這些微服務的 API 時,至少要做好兩件事:

由統一的入口來呼叫微服務的 API

API 鑑權

這就需要一個 服務閘道器。2015 年,我們使用 Rest Template + Ribbon 做了一個簡單的 API 閘道器。原理就是當 API 閘道器接到請求 /service1/api1.do 時,將請求轉發到 service1 對應的微服務的 api1 介面。

後來,發現我們實現的功能,Spring Cloud Zuul 都有比較好的實現,也就切換到 Zuul 上面去了。Zuul 是 Netflix 基於 Java 開發的服務端 API 閘道器和負載均衡器。

除此之外,Zuul 還可以對過濾器進行動態的載入、編譯、執行。最令人吃驚的是,Zuul 的轉發效能據說和 Nginx 差不多。詳細資訊可參考 https://github.com/Netflix/zuul。

總的來說,一般情況下,API 閘道器(可以稱為門戶後端)用來進行反向代理、許可權認證、資料剪裁、資料聚合等。

 管理端整合框架

掌握註冊中心、服務發現、負載均衡和服務閘道器技術後,微服務已經可以為門戶系統和移動 APP 提供可靠服務。但是,給後臺運營人員使用的管理端是怎麼實現的呢?

由於後端運營系統的壓力不大,我們可以通過 CAS 和 UPMS(UPMS 是我們團隊研發的契合微服務架構的使用者及許可權管理系統,我們將分享到青柳雲官網,歡迎關注)將單獨開發的微服務整合起來。

三步整合一個微服務的基本過程就是:

在微服務中引入基於 Spring Boot 的 security starter,starter 裡包含了系統的頂端 Banner 和左側選單。

將微服務的訪問地址註冊到 UPMS 中,這個地址作為此微服務的入口選單(一級選單)。

在 UPMS 中配置微服務的功能選單及角色許可權資訊。

使用者從瀏覽器開啟一個微服務的時候,security starter 會呼叫 UPMS 的 API 拉取所有的微服務清單(一級選單)和當前微服務的功能清單(二級選單),並將當前微服務的頁面在內容區展現給使用者。

溫馨提示 : 微服務架構交流群:628134587

應用架構圖:

UPMS 截圖,橙色部分由 UPMS 框架提供,紅色框為微服務的頁面:

UPMS 通過“模組”功能接入新的微服務:

所以,到最後,一個簡單模式的基於微服務架構的系統就可以長成這樣:

至此,基本的微服務架構已經搭建起來。下面來聊聊怎麼解決微服務運維的問題。

 

運維難

微服務架構的運維問題,主要是相對於單體架構來說的。因為實施微服務架構後,整個系統的模組一下子比原來多了很多,模組變多後,部署和維護的工作量都會變大。所以,解決運維難的問題,可以先從 自動化 的角度來解決。

更進一步,如果希望更好地發揮微服務架構的優勢,規避缺點,則建議準備一個可靠的基礎設施,包含自動構建、自動部署、日誌中心、健康檢查、效能監控等功能。

否則,很有可能會因為微服務架構的缺點導致我們的團隊喪失對微服務架構的信心,從而回到單體架構的老路上去。工欲善其事,必先利其器,這一點真的很重要。

 持續整合

單體應用被微服務化後,很有可能從原來的一個程式包分成了 10 個、20 個甚至更多的程式包。那麼,我們首先遇到的麻煩就是部署工作直接擴大了 10 - 20 倍。這時,持續整合的方法和工具就成了實施微服務架構的前提條件。我們在實踐過程中,利用基於 Docker 的容器服務平臺自動部署整個系統的微服務。其過程如下圖:

如果沒有微服務支撐平臺,也可以通過 Shell 指令碼的形式來呼叫 Jenkins API 和 Docker API。

 

主要過程是:

呼叫 Jenkins 命令從程式碼倉庫拉取程式碼,並打包程式碼。

呼叫 Docker /build 和 /images/push 命令構建映象,並將映象推送到私有映象倉庫中。

呼叫 Docker /containers/create 和 /containers/start 命令建立並啟動容器。

 配置中心

在開發 / 測試環境上,程式包已經被打包成 Docker 映象,如果能將通過測試的映象直接推到生產環境,可以直接省去為生產環境而重複進行的打包部署工作,豈不是很美?

如果需要達到這個效果,就需要將程式包打包成具有環境無關性,也就是說,在程式包裡是不可以有環境相關的配置資訊的,這也就引入了 配置中心 元件。

這個元件非常簡單,只是根據專案代號、環境代號和微服務代號來獲取微服務所需要的鍵值對。例如:

ProjectA_PRODUCTION_MicroService1_jdbc.connection.url。

使用配置中心還有一個很重要的附加價值,那就是可以做到不同環境的配置資訊可以由不同的人來管理,加強了生產環境的配置資訊的安全性,例如資料庫帳號和密碼。

這個模組也有一些開源的專案可以參考,例如百度 disconf,Spring Cloud Config。而我們自己發楊了重複造輪子的精神,開發了一個配置中心微服務,以方便地與上面提到的 UPMS 進行整合。

注意:這一元件並不是微服務架構簡單模式的必需元件,只是建議使用。

 監控告警

單體應用被微服務化後,一個單體應用被拆成了很多個微服務,系統的健康巡檢、效能監控、業務指標健康、檔案備份監控、資料庫備份監控、定時任務執行情況監控都變得困難。

所以,為了讓運維的同學能生活得踏實點,最好也能把監控平臺給建了。如果希望快速搭建監控平臺,可以考慮 Nagios,Zabbix。如果希望擴充套件性、可定製性更好,可以考慮使用以下元件搭建:

Collectd是一款主機、資料庫、網路、儲存指標採集器。GitHub 上 1653 個 Star。

Metrics是一款牛逼的 JVM 指標採集器,提供了很多模組可以為第三方庫或者應用提供輔助統計資訊, 比如 Jetty, Logback,Log4j,Apache HttpClient,Ehcache,JDBI,Jersey,它還可以將度量資料傳送給 Ganglia 和 Graphite 以提供圖形化的監控。GitHub 上 5000+ 個 Star。

CAdvisor是一款 Docker 容器指標採集器,Google 出品。GitHub 上 6000 個 Star。

Grafana是一款非常精美的開源儀表盤工具,支援 Graphite,InfluxDB ,MySQL 和 OpenTSDB 等多種資料來源。GitHub 上 17000 個 Star。

InfluxDB是一款優秀的開源分散式時序資料庫,目前在時序資料中排名第一,它的特性中,RETENTION POLICY 可以自動地清除不需要的歷史資料,很實用。GitHub 上 11175 個 Star。

除了以上模組,我們還開發了一個模組,用來探測應用程式的健康情況和效能,在主機、程式健康情況、程式效能等各種指標出現異常時,傳送警報給運維人員。

寫在最後

在這篇文章結束的時候,我們可以回過頭來看看,我們只需要在開發層面理解了註冊中心、服務發現、負載均衡、服務閘道器和管理端整合框架,在運維層面準備好持續整合工具、配置中心和監控告警工具,就可以很容易地落地微服務架構,享受微服務架構帶來的精彩。祝大家玩得愉快。

 

相關文章