基於 Kubernetes 的微服務項目設計與實現

來源:http://dwz.date/eFPdhtml

隨着互聯網的發展,後端服務和容器編排技術的日益成熟,微服務成爲了後端服務的首選,Kubernetes 也已經成爲目前容器編排的事實標準, 微服務擁抱容器時代已經來臨。前端

筆者結合本身的經驗,寫了這篇微服務+ Kubernetes 入門寶典,但願可以拋磚引玉。能讓你們瞭解 微服務和 Kubernetes 如何配合。java

上卷主要描述 微服務設計,項目實現,kubernetes 部署,微服務的部署 高可用和監控 這幾個部分。linux

下卷計劃討論服務化網格和數據持久化, 有狀態服務,operator 這幾部分。nginx

本文由我獨立完成(ppmsn2005@gmail.com)若有任何錯誤,是我我的緣由,請直接和我聯繫,謝謝!您能夠在https://github.com/xiaojiaqi/deploy-microservices-to-a-Kubernetes-cluster 找到本文的全文和相關資料。git

本文會從設計開始,設計一個簡單的先後端分離的項目,並將它部署在 kubernetes 集羣上,期間咱們將關注微服務和 kubernetes 配合的各個方面,而且從 系統的可用性,可靠性、強壯性、可擴展進行討論,最終設計一個能夠真正實用的系統。程序員

總體上咱們從4個章節描述這個目標,分別是:github

第一章:微服務項目的設計web

第二章:微服務項目的具體實現ajax

第三章:kubernetes的部署

第四章:微服務高可用部署及驗證

微服務是一種設計思想,它並不侷限於任何開發語言,在本例中咱們選擇java的spring boot 框架來實現微服務。 微服務之間的 RPC 方案也不少,咱們這裏選擇RESTFUL 這種最多見的方案。 爲了項目的簡潔,項目也沒有涉及數據庫和緩存,配置中心相關的內容。 咱們主要注重項目的設計思想實踐和項目改進。

第一章:微服務項目的設計

1.1 微服務設計的思想

首先咱們簡單地回顧一下微服務,微服務的定義當來自 Martin flowerlerhttps://martinfowler.com/articles/microservices.html 一文,借用大佬的一張圖 描述了微服務最本質的東西。

微服務把各個功能拆開了,每一個模塊的功能更加獨立,也更加單一。每一個模塊都獨立發展,能夠說作到了功能的高內聚,低偶合。

再借一張,這樣數據庫也被完全拆分開了。一個巨大複製的單體數據庫也按照功能拆成了小的獨立數據庫。

微服務就是這麼簡單嗎?固然不是,裏面有不少細節須要考慮,紙上得來終覺淺,絕知此事要躬行。此次讓咱們開始從0開始真正的設計整套系統。

1.2 實踐設計和改進

如今咱們要設計一個最簡單的微服務架構。爲了更貼近真實的業務。咱們假設這個系統是這樣的。

整個系統的前端是一個有着先後端分離站點,用戶訪問了www.demo.com 這個前端站點,經過前端頁面發起請求,www.demo.com 服務器將請求發往a.demo.com.  而後a.demo.com 再請求b.demo.com ,b.demo.com 再請求 c.demo.com。c.demo.com 將結果返回後,不斷返回,最終顯示在前端站點,完成微服務的全套調用流程。[ 通常業務系統 在前端和微服務直接還存在一個網關部分,網關通常用於鑑權,請求分類,監控等功能, 這裏由於比較簡單,因此省略了這個部分]

最終咱們將這套架構將部署在kubernetes 上,開始真正的服務用戶。

1.3 改進項目

從圖一咱們能夠看到這是一個很是簡單而單薄的架構,存在不少問題,咱們須要不斷地解決它們。下面咱們開始改進項目。

首先,咱們要解決節點的可靠性。在圖一全部的節點都只有一個實例,任何節點的崩潰都將形成項目沒法運行,在真正的項目中這是不可接受的。怎麼解決呢?固然是多個實例

1.3.1 加入多實例及註冊中心

咱們將各個模塊的實例數目增長,多個實例才能保證整個系統的可靠性。若是一個實例有問題,咱們仍是能夠其餘相同的實例進行服務。

可是多個實例又帶來一個問題,各個組件之間如何定位呢?若是有10個b.demo.com 實例,它的上下游又該如何找到它們呢?解決方案之一是註冊中心。註冊中心解決的是應用之間的尋址問題。有了它,上下游之間的應用能夠相互尋址,而且獲知那些實例是可用的,應用挑選可用的實例進行工做。註冊中心的方案不少,有eureka,zookeeper, console, Nacos 等等,關於討論各類註冊中心是AP、CP的區別,優劣的文章不少,這篇文章不是一篇微服務的開發教程,咱們選擇比較常見的eureka爲演示的註冊中心。

注:在kubernetes 中部署微服務,對註冊中心是沒有任何限制的。因此不要被某些文章誤導,按照這篇文章作,你徹底能夠作到代碼零修改,直接在kubernetes 上運行。

1.3.2 監控系統 Metrics

在完成了註冊中心的功能後,雖然整個系統能夠運行了,咱們會發現沒有應用監控的狀況下,咱們對系統運轉狀態是徹底摸黑的,這樣至關於盲人騎馬,很是危險。咱們須要知道全部微服務運行的狀態,必須將各個微服務的狀態監控起來,只有這樣才能作到 指揮若定,決勝千里。

在這裏,咱們選擇使用Prometheus和Grafana這套監控組合。Prometheus + Grafana是一個比較常見的組合, 基本是如今容器監控的標準配置。

在kubernetes 上,咱們須要每一個微服務的實例裏開啓監控數據到導出功能。同時利用Prometheus 的自動發現功能, 這樣Prometheus 能夠將數據收集存儲起來。這裏的數據包括每一個應用的各項指標好比內存大小,200錯誤數目,500錯誤數目, JVM裏線程數量,GC時間大小。配合granfana的聚合顯示能力,咱們能夠直觀地對整個系統有完整把控。在應用開發過程當中,咱們只須要在代碼里加入一個類庫就能夠實現信息的導出,不須要專門寫代碼。

1.3.3 日誌系統 logging

目前已經有了監控,日誌還有存在的必要嗎?固然 下面這個圖就反應監控的3個維度。

這3個維度分別是Mertics Tracing 和logging

Metrics  主要就是指剛纔說的監控,它主要反應的就是一個聚合的數據,好比今天200錯誤是多少,QPS是多少?它指的是一段時間內的數據聚合。

Logging 就是咱們如今討論的日誌。的它描述一些離散的(不連續的)事件。好比各個系統裏的錯誤,告警。因此咱們須要將日誌收集起來。

Tracing 則關注單次請求中信息。咱們關注請求的質量和服務可行性,是咱們優化系統,排查問題的工具。

說到了日誌,在一個分佈式系統,日誌是很是重要的一環。由於微服務和容器的緣故,致使日誌收集不是這麼簡單了。由於在kubernetes 裏 容器的銷燬和重啓都是常常可能出現的,咱們須要第一時間就把日誌收集起來。

日誌收集的方案有不少,有些方案是在本地啓動一個收集進程,將落地的日誌轉發到kakfa組件再轉發日誌中心,也有的方案是直接寫到kafka組件直接進入日誌中心。二者各有優劣。

在這裏,咱們的方案選擇了後者。咱們簡單地利用一個組件將日誌直接打入kafka 組件。這種方案的好處是咱們日誌再也不落地,日誌IO被消除了,日誌的存儲也和容器作到了分離。咱們不再用擔憂日誌IO對宿主機形成的系統壓力了。

圖片

1.3.4      追蹤系統 Tracing

剛纔咱們討論了監控 (Metric)和日誌(Logging),還有一個維度就是追蹤(Tracing).

隨着微服務的實例愈來愈多,有一個很現實的問題出現了,當大規模分佈式集羣出現了,應用構建在不一樣的容器集羣裏、有可能布在了幾千臺容器裏,橫跨多個不一樣的數據中心。所以,就須要一些能夠幫助理解系統行爲、用於分析性能問題的工具。這該怎麼解決呢?能夠看看google的論文 google dapper

Google 的論文描述一種解決辦法,咱們通常稱做APM(Application Performance Monitor). 它把一次調用加入一個獨立無二的標記,而且在各個系統裏透傳標記,從而達到追蹤整個消息處理過程的能力。市面上大多數實現都是基於這一思想,可選方案的有不少,如 cat pip, zipkin, skywalkin。它們有須要代碼注入的,有無注入的。關於他們的優劣也有不少文章評述。在這裏咱們選用zipkin 。Zipkin 須要在項目中加入一個庫,並不須要寫代碼,這對業務的入侵作到了不多,很是方便。

1.3.5 流量控制

你認爲這一切就完了嗎?固然不是,微服務裏還有一項很是重要的功能:流量控制,咱們尚未作。

當海量的請求來臨的時候,咱們能夠用增長容器數量的辦法來提升咱們的服務能力,可是簡單地添加實例是很危險的,由於整個系統的服務能力是被系統短板所限制的,簡單地添加實例,並非總能起到提升服務能力的做用。反而可能引發副作用,最終致使整個系統的崩潰。

咱們對整個系統的負載容量是有一個設計的,當超出咱們設計的能力時,咱們須要對多餘的請求說No。相應的方案分別是熔斷、限流和降級。目前java領域的這方面的hystrix,sentinel 在這方面都作得很好。Sentinel 在阿里接受了考驗,而且使用起來也很簡單,因此咱們選它。如今咱們在整個系統里加上一個流量控中心。這樣一個基本完整的 可靠的 高可靠的系統就基本完成了。

(在實際開發中,其實還有最關鍵的配置中心(apollo),數據庫(db),緩存(redis) 等組件, 服務化網格, 咱們能夠把這些組件暫時放在kubernetes 以外,仍然是能夠起到一樣的效果)

好了設計部分,先到這裏,開始實現。

第二章:微服務項目的具體實現

從 前端向後端開始實現

2.1 前端站點

前端站點的邏輯很簡單,就是顯示一個頁面,頁面中有一個按鍵。當你點擊按鍵的時候,前端頁面發起ajax請求,訪問前端站點自己的一個接口,這個接口被nginx代理,轉發到a.demo.com 微服務上,a. demo.com 微服務再將請求轉發到b. demo.com, b. demo.com 再將請求轉發到c. demo.com. 最終將結果返回給前端。前端站點再將結果顯示在頁面上。咱們經過

結果顯示,就能知道 此次請求經過了那些服務器,每臺服務器的服務運行時間大概是多少。

前端站點代碼 大致以下:

而後看a、b、 c 應用部分的java代碼,這就是個普通的多模塊Maven項目。

項目很簡單,分紅了3個部分,一個是註冊中心,也就是利用eureka實現註冊中心服務,另外一個則是基礎庫項目,大部分功能都在這裏實現,最後則是各個微服務項目,微服務項目只須要簡單調用基礎庫就能完成。

2.2 註冊中心

註冊中心的代碼很是簡單,只須要加一個簡單的聲明

這是註冊中心的配置文件,在kubernetes集羣裏運行時,咱們會運行3個節點組成高可用的註冊中心集羣。這時 這個配置項須要相應的修改。

2.3 基礎庫

在基礎庫項目裏,咱們將不少的依賴都放在裏面,這樣應用項目只須要簡單依賴基礎庫就能夠,可以作到統一修改。

同時咱們也能夠看到大部分依賴庫只須要加入就能夠,並不需編寫代碼就能夠工做,這讓開發工做變得輕鬆。

對於微服務的返回結果,咱們作了一些美化格式。這樣能夠在檢查結果時,比較容易。

簡單的定義了一些返回的結構,能夠經過這些結構,微服務能夠把處理時的時間戳,線程號,實例ip這些信息返回出來。

基礎模塊的日誌實現,從github 找的例子簡單地進行了修改。(簡單實現,不要用於生產)這時咱們利用logback.xml 的配置,能夠選擇咱們是把日誌寫入本地磁盤仍是直接寫入kafka.

2.4 a.demo.com b.demo.com c.demo.com 應用實現

實現很簡單,只是簡單地調用基礎庫就能夠了。注意 每一個應用須要實現一個探活接口 /hs. 這樣kubernetes 系統能夠經過這個接口來探活,獲知你這個應用是否是準備好了,能不能接入流量。不然 你這個應用可能還在啓動過程當中,可是流量已經接入了,那麼確定會出問題。

在每一個應用的配置裏,咱們都預置了各個配置的項目,在本地運行的時候,咱們能夠填注入本地的配置,在kubernetes 裏 以容器形式進行運行,咱們能夠利用yaml來動態地修改它們,作到2種狀況下徹底兼容。

第三章:kubernetes的部署

在完成應用的編寫後,咱們須要安裝kubernetes系統了,若是已經有kubernetes 集羣的,就能夠直接跳過這個部分了,請看下一章。除了kubernetes 集羣之外,你還須要Prometheus and Grafana這樣的監控組件。因此這裏我推薦一個牛逼的安裝工具,和全部現有的Kubernetes 安裝工具比,它是最好的,沒有之一。

它的名字是 K8seasy, 它的優勢在於

  1. 能夠一鍵安裝總體kubernetes 系統,無需瞭解任何背景知識
  2. 全部的鏡像都已經內置,不會由於下載鏡像失敗而致使失敗
  3. 安裝支持各類不一樣版本kubernetes版本
  4. 安裝的服務是二進制版本的,非容器版本, 穩定高效
  5. 支持安裝3節點 高可用的生產環境集羣

3.1 安裝過程

下載K8seasy,官方主頁 https://github.com/xiaojiaqi/K8seasy_release_page

安裝下載頁:http://dl.K8seasy.com/

將3個安裝文件都下載下來, 其中 pack.2020.10.02.bin 和installer 都是安裝文件, kubernetes-server-linux-amd64.tar.gz 是kubernetes 的官方軟件包,你能夠本身選擇一個最新的版本。

若是要選擇一個其餘版本的kubernetes

安裝的過程很簡單,2條命令便可,這裏咱們假設 須要安裝Kubernetes的網絡爲 192.168.2.0, master 主機爲192.168.2.50

1 建立密鑰

sudo ./installer --genkey -hostlist=192.168.2.1

2 建立集羣

sudo ./installer -kubernetestarfile kubernetes-server-linux-amd64v1.18.2.tar.gz -masterip 192.168.2.50

稍等一下子 就能看到相似以下輸出

就這麼簡單,一個Kubernetes已經裝好了。此時相關的全部監控已經被徹底安裝好了。

3. 各項監控

以master 節點爲 192.168.2.50 爲例子

http://192.168.2.50:10000 能夠直接打開dashboard, 對整個集羣有一個全面瞭解

打開 http://192.168.2.50:8080  能夠直接訪問alertmanager

打開 http://192.168.2.50:8081 你能夠直接使用 Grafana (用戶 admin, 密碼admin)

打開 http://192.168.2.50:8082 你能夠訪問 Prometheus.

4. 多套環境監控

這一切就完了嗎?固然不是,爲了支持多集羣管理,再推薦一個工具。剛纔咱們說到直接使用 http://192.168.2.50:1000 這個頁面能夠直接管理整個集羣,可是在公司裏若是有多個集羣,該如何管理呢? 別擔憂,K8seasy 已經有對應的解決方案

仔細看剛纔的安裝好的日誌,裏面提示你 專門生產了一個 lens.kubeconfig 的配置文件, 而且有一個 域名和 ip 的對應表。這時候,你只須要 首先在本地Host 文件里加入這個對應

而後去 https://Kuberneteslens.dev/

下載一個lens的安裝包。安裝lens之後,你只須要將 lens.kubeconfig 導入到lens裏

導入完成後,你就能夠遠程管理這個集羣了。這樣有多個集羣,你也能夠只用一套lens 進行管理了。

Lens的界面優美,使用方便,快試試吧。

好了 Kubernetes 的安裝完成了。固然了K8seasy 的功能是很是強大的,你能夠用 sudo ./installer -h 查看幫助, 也可使用 sudo ./installer -demo 查看各類場景的安裝幫助。

第四章:微服務高可用部署及驗證

Kubernetes 裝好了,如今開始將微服務部署上去了。咱們剛纔的代碼只是Java 源碼,咱們還須要將它們編譯成Jar包,而後再打成docker 鏡像才能部署,這部分比較簡單,因此我不演示如何完成了,我將相關的Dockerfile 和 最終Yaml 都放在Github 裏了,在開始開發時,我提到將日誌寫入Kafka, 因此有2套配置,一套使用了Kafak 一套沒有使用Kafka。請注意區別,有由於沒有Kafka 比較容易實施,我這裏就演示沒有Kafak的版本。這樣全部只要有一臺Linux 就能夠保證將整個流程實施成功。

4.1  服務部署上去

依次運行每條部署Yaml的命令便可,不須要作其餘的操做。

注意,鏡像在Docker-Hub, 可能須要必定時間能下載。

運行後在 Dashboard 查看,你能夠看到相似的信息,全部的服務都已經成功運行。

查看Dashboard

此時修改你本地的Hosts

這樣的話,由於咱們的Kubernetes 是支持 nginx-ingress的,因此你能夠直接訪問Master的物理IP來訪問這些服務,不須要作任何轉換。

首先咱們能夠打開dashboard 從中查到eureka.服務器的具體ip, 而後訪問eurka 服務。

查看註冊中心

在頁面中你能夠發現,在Kubernetes集羣裏,咱們啓動了3個eureka服務,它們相互註冊,組成了一個高可用集羣。

其次,咱們在Grafana 中導入 jvm 的監控項目

這樣Grafana能夠幫助咱們把 各個Java服務的具體狀態作一個收集,完成咱們須要的監控。

前端驗證

此時 咱們打開 http://www.demo.com 的網頁。

咱們能夠點擊頁面上的 get 請求按鍵,模擬發出請求,隨後咱們就會發現頁面裏顯示出的信息在不斷變化。

在頁面顯示的內容裏,咱們能夠清楚地發現,咱們的消息在不一樣實例裏處理,若是有一個實例出現了故障是不會影響咱們如今的業務的。

好了開始驗證整個系統。

模擬驗證

使用一個簡單的腳本 模擬每3秒從前端訪問一次後端。

調用關係驗證

首先打開zipkin  zipkin.demo.com

點擊具體的請求,能夠查看到每次請求在內部的細節。

限流熔斷驗證

其次 打開 sentinel 站點,這個站點能夠監控,也能夠對微服務進行限流,限速,熔斷等操做。(密碼口令都是 sentinel)

進入控制檯後,咱們能夠發現全部的服務已經自動被發現,並存在於左邊的菜單。

分別點開 a b c 3個服務,能夠看到規律的週期訪問,和咱們的腳本的測試速度是一致的。

Sentinel 裏面內含強大的監控,流控 降級等功能,具體的使用,能夠慢慢學習,相信你必定會受益良多。

應用狀態驗證

打開Grafana的監控頁,你能夠查看全部應用的狀態,包括heap 大小,啓動時間,錯誤數目 等等。

經過這張圖你能夠了解每一個應用自己的狀態,使用了多少內存,響應的代碼是多少,jvm 使用狀況。相信此時 你已經對各個組件的狀況,監控都有了一個全面瞭解。一個基於 Kubernetes 的微服務架構已經開始工做了。

最後送一張經常使用的系統架構圖,但願你們能經過本文對高可用微服務如何架設 Kubernetes 上有一個基本的瞭解,將本文討論的東西用於實踐。謝謝!


若是此文對你有所幫助,但願能隨手點個轉發!



End




乾貨分享



這裏爲你們準備了一份小小的禮物,關注公衆號,輸入以下代碼,便可得到百度網盤地址,無套路領取!

001:《程序員必讀書籍》
002:《從無到有搭建中小型互聯網公司後臺服務架構與運維架構》
003:《互聯網企業高併發解決方案》
004:《互聯網架構教學視頻》
006:《SpringBoot實現點餐系統》
007:《SpringSecurity實戰視頻》
008:《Hadoop實戰教學視頻》
009:《騰訊2019Techo開發者大會PPT》

010: 微信交流羣


我就知道你「在看」






本文分享自微信公衆號 - JAVA日知錄(javadaily)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索