微服務架構的規劃

微服務架構的規劃

 

 

人只有獻身於社會,才能找出那短暫而有風險的生命的意義。

——愛因斯坦

 

1、前言

本節主要跟大家聊聊如何去規劃一個項目的架構,平時工作當中,很多同學接觸到的項目都是現成的,由專門人員搭建好之後,自己在其基礎上進行開發,自己也從來沒想過爲什麼是這樣的架構,這樣的架構有什麼缺點,有沒有更好的方案等等,就只管編寫自己的代碼。時間長了,感覺寫代碼真的很簡單,一旦你真感覺寫代碼很簡單的時候,其實是在提醒你要學習了,否則很容易就會進入舒適區。有時候,你看似很簡單的問題,但是真要自己動手去搭建一遍,發現遇到的問題很多。

首先,我們梳理一個項目的完整開發流程大概是什麼樣的?

階段 1: 需求的規劃、原型圖的設計;這部分工作一般是產品和美工完成的,主要目的是把虛擬的東西變成一個感觀可見的東西。

階段 2: 需求分析設計階段,主要是把需求文檔的文字梳理成各個模型,包括架構圖設計、流程圖設計等。這個環節非常的重要,如果跳過該環節直接進入代碼實戰,則往往事倍功半。

階段 3: 代碼實戰,就是擼代碼階段

階段 4: 功能測試,大家都是熟悉的。包括:接口聯調、測試環境測試、灰度測試

階段 5: 項目上線

上面的流程大家應該都不陌生,作爲開發人員,我們比較熟悉的應該是階段2 和階段3;我們的本節的重點就是階段2 需求的分析和設計。其實在這個階段,開發人員通過畫項目的架構圖、各個業務的詳細流程圖,很多難點都會在流程圖上體現出來,再針對難點做技術方案的選型等;這個步驟做好之後,那麼代碼階段就會非常的簡單,只需要按照標準去實現即可。

 

思考:規劃系統架構需要考慮哪些問題呢?

①架構模式

  • 一般根據項目的預估併發量、項目的規模來選擇合適的架構,通常分爲單體架構、垂直架構、SOA 架構、微服務架構。

②技術選型

  • 技術選型通常分爲基礎的開發框架(比如:ssm、SpringBoot+MyBatis 等)、分佈式架構本身所引起的技術難點(比如:服務治理、網關、配置中心等等)、具體業務場景選擇什麼樣的解決方案(這個實戰部分會深入分析)。
  • 同種類型的框架如何選擇,比如:消息隊列的主流框架有 ActiveMQ、RabbitMQ、RocketMQ、Kafka 等,我們應該選擇哪款框架。
  • 必須熟悉分佈式架構常見的問題及解決方案,比如:服務治理問題、自動化部署、系統的穩定性(容錯、限流)、分佈式事務、分佈式鎖等等。

③部署架構

  • 根據預估流量、接口壓測,來選擇具體的部署架構方案,是選擇做單節點部署還是集羣部署,是傳統的部署還是容器化部署。

 

2、項目架構的規劃

 

2.1、架構模式

瞭解一下單體模式:
圖片描述

無論開發的時候,分多少個子項目,上線的時候,只打成一個包進行部署的項目就是單體項目。

單體項目模式 1:

platform							(項目名稱)
	|-- src/main/java
    |  |-- com.micro.utils			(工具包)
	|  |-- com.micro.modules
	|  |-- com.micro.modules.user	(用戶模塊)
	|  |  |-- UserController.java
	|  |  |-- UserService.java
	|  |  |-- UserServiceImpl.java
	|  |  |-- UserDao.java
	|  |-- com.micro.modules.order	(訂單模塊)
	|  |  |-- OrderController.java
	|  |  |-- OrderService.java
	|  |  |-- OrderServiceImpl.java
	|  |  |-- OrderDao.java
	|  |-- com.micro.modeules.goods	(商品模塊)
	|  |  |-- GoodsController.java
	|  |  |-- GoodsService.java
	|  |  |-- GoodsServiceImpl.java
	|  |  |-- GoodsDao.java
  • 描述:通過包名來區分不同的模塊
  • 優點:項目架構簡單
  • 缺點:①所有的模塊代碼嚴重耦合一起,代碼非常的臃腫;②技術受限,不可以靈活的選擇合適的開發語言;③整體運行性能較低

單體項目模式 2:

platform
	|-- platform-user	(用戶工程)
	|-- platform-order	(訂單工程)
	|-- platform-goods	(商品工程)
  • 描述:開發過程中把一個大的項目拆分多個子項目;但是最後是打包成一個項目來進行部署
  • 優點:相比上面的模式,項目做了拆分,可以實現代碼的重複性利用
  • 缺點:①還是技術受限,所有工程必須遵守統一技術規範,否則無法整合;②整體運行性能較低

瞭解一下分佈式(微服務)模式:
圖片描述

  • 描述:把一張完整項目拆分多個獨立運行的服務,可以是每個服務獨立自己的數據庫、也可以共用一個數據庫。
  • 優點:①每個服務的功能單一;②運行速度快;③開發和迭代週期短;④技術選型比較靈活
  • 缺點:①服務數量較多;②部署複雜度提高;③會引起很多的其他問題(下面詳細分析)

大型項目都會選擇微服務的架構模式,架構模式是,前後端分離 + 後端微服務架構,具體如下:

圖片描述

  • 相信很多老程序員都接觸過 jsp 這玩意,它是一種模板引擎技術,前後端分離之前,基本上都是使用它來開發的頁面。jsp 雖然內置了好多的標籤,開發起來也比較方便。但是分工責任問題,讓前端和後端開發人員合作起來相對比較麻煩。前端開發好 html 頁面丟給後端整合成 jsp,這中間出現各種樣式問題、兼容性問題等等。因此前後端分離讓項目開發起來效率更加高,畢竟專業的人做專業的事。

思考:微服務架構會存在哪些問題呢?

 

1)穩定性問題

服務網穩定性問題,主要來自於以下幾個方面。

①高併發訪問、或者突發流量、惡意攻擊等;

  • 可以採用限流、容錯、防惡意攻擊的方式保護服務,比如:前端加驗證碼、IP 控制、網關限流、消息隊列限流、服務限流。

②由於服務的數量很多、關係複雜,其中一個服務出問題,就可能導致雪崩效應。

  • 爲了防止服務之間的雪崩效應,最常見解決方案就是,服務容錯及降低,主要是當調用的服務出問題時,返回默認值。

③分佈式事務問題,這個是服務拆分必然引起的問題。

  • 原來單體項目模式,則所有操作屬於同一個事務,數據一致性得到了保證,但是微服務模式下,則不在同一個事務下了,需要解決分佈式事務的問題。

④爲了更好的保護我們的服務,我們需要在所有服務前面加上一層網關,它的核心功能是請求轉發、認證、鑑權、限流。

⑤接口調用冪等性問題,比如:接口消費方超時時間是 2s,但是此時接口提供方出現卡頓了,處理花了 5s,此時消費方會發起接口重試,就會導致重複執行。

⑥網絡延遲、連接假死等引起遠程通訊問題

 

2)通訊問題

服務之間通訊,如果使用傳統的 HttpClient、WebService 肯定是滿足不了的,因爲服務之間互相通訊,複雜度更加的高,比如:集羣模式需要動態新增節點、負載均衡、服務容錯等,一般得集成服務治理框架(Dubbo 等)。

 

3)部署問題

服務數量很多,並且服務器數量也很多的情況下,手工部署效率會非常的低,一般都是自動化部署和自動化擴容;然而項目部署肯定需要修改項目的配置信息,因此需要依賴一個叫配置中心的中間件。

 

4)錯誤定位問題

日誌文件散落在各個服務器,如何快速定位異常信息呢?如果依靠手工去每臺服務中查看日誌信息,則效率非常的慢。因此需要集成日誌採集、存儲、分析框架,比如:ELK 技術棧。除此之外,爲了提高效率,建議做以下兩個小操作。

  • 最好自定義異常類,這樣可以更加快速的定位異常地方。

  • 很難篩出指定請求的全部相關日誌,以及下游服務調用對應的日誌,因此建議使用一個 traceId 跟蹤請求的全部路徑。

 

5)鏈路追蹤問題

服務之間互相依賴,方法之間調用,可能是層層調用,複雜度很高,導致系統上線之後,爲如何定位異常、性能監控等帶來難題,因此我們需要使用這方面的開源中間件來監控,比如:Zipkin 等。

通過上面分析微服務存在的問題和解決方案,我來大致描繪一下微服務的架構圖,具體如下:
圖片描述

架構圖分析說明

  • ①綠色部分需要做限流,可以使用 RateLimiter 框架,也可以使用阿里 Sentinel 框架
  • ②紅色部分容錯,表示的是服務之間的接口調用(rpc 遠程調用),需要容錯機制,否則其中一個服務出問題了,可能引起一片服務產生問題,也就是常說的雪崩效應
  • ③紅色部分日誌採集,一般採用埋點的方式進行日誌採集,也就是說提供一個 jar 給服務集成,底層採用 Aop 的模式進行收集信息,這個後面實戰部分會詳細講解
  • ④配置中心,目的是把經常變動的配置信息由項目抽離到配置中心,方便後期在線修改,常見框架有 Nacos、Apollo
  • ⑤註冊中心,目的是做服務地址管理,一般是跟 rpc 框架結合使用,例如:Dubbo

 

2.2、技術選型

上面我們瞭解完整個微服務的架構圖了,這裏我們主要講解微服務涉及的技術棧及相應的解決方案是什麼。

目前主流的微服務技術方案,主要是 SpringCloudNetflix 和 SpringCloudAlibaba 兩個派系,SpringCloudNetflix 的話,它會有針對每個場景都有具體的解決方案。這裏主要講解以阿里係爲主的解決方案說明。

序號 解決方案 落地技術
1 服務網關 Nginx,注意的是 Zuul 和 Gateway 不適合 Dubbo,它依賴 Eureka
2 限流框架 Sentinel
3 容錯框架 Sentinel
4 配置中心 Nacos
5 分佈式事務 seata
6 服務治理 Dubbo+Zookeeper
7 鏈路追蹤 Zipkin
8 接口冪等性 可以全局 ID 手工實現
9 日誌管理 一般使用 ELK 技術棧,進行日誌的採集、存儲、分析、展示

以上只是最基本的微服務技術棧,還有一些常見業務場景的解決方案,具體如下:

序號 業務點 技術
2 分佈式文件系統 FastDFS、HDFS
2 分佈式鎖 Zookeeper、Redis
3 消息隊列 ActiveMQ、RabbitMQ、RocketMQ、Kafka
4 全文檢索引擎 Solr、ElasticSearch
5 分佈式緩存 Redis
9 過期監聽 Redis 過期監聽、延遲隊列
10 消息推送 WebSocket、Netty

 

 

2.3、部署架構

一般情況下,高併發的系統部署架構都會採用分佈式集羣部署,主要核心是解決以下方面的問題

  • ①提高系統性能,一般需要使用多層負載均衡的方式解決流量分散,負載均衡的含義,其實就是把用戶的請求,根據某種算法均攤到不同的服務器身上,減輕單臺服務器的壓力,是提高系統性能的常見手段。
  • ②節點容災,也稱爲服務高可用,例如:只有一個 Nginx 對外提供服務,如果該 Nginx 掛掉之後,則整個項目無法對外提供正常服務,因此需要做節點高可用。特殊說明,負載均衡其實也是解決高可用其中一種方式;可以使用 Keepalived 來實現節點高可用,可以參考部署篇,裏面有這部分的詳細講解。
  • ③服務器災備,服務器是會宕機的,服務器宕機之後,裏面的所有服務都失效了,一般使用 docker-swarm、k8s 去做災備。
  • ④數據備份,數據安全是非常重要的,很多小公司做備份,使用人工備份或者定時備份,其實這是不夠安全的,比如說:機房發生火災,那麼數據將全部丟失,因此需要做一個異地備份(雙機房備份),參考後面 MySQL 主從章節。

負載均衡部署架構圖:
圖片描述

  • ①OSPF (開放式最短鏈路優先) 是一個內部網關協議 (Interior Gateway Protocol, 簡稱 IGP)。OSPF 通過路由器之間通告網絡接口的狀態來建立鏈路狀態數據庫,生成最短路徑樹,OSPF 會自動計算路由接口上的 Cost 值,但也可以通過手工指定該接口的 Cost 值,手工指定的優先於自動計算的值。

    OSPF 計算的 Cost,同樣是和接口帶寬成反比,帶寬越高,Cost 值越小。到達目標相同 Cost 值的路

    徑,可以執行負載均衡,最多 6 條鏈路同時執行負載均衡。

  • ②LVS 負載,Lvs 是第四層負載(tcp/ip 協議)

  • ③Nginx 負載,Nginx 主要是用於搭建 Tomcat 負載均衡集羣,它是第七層負載(http 協議)

  • 如果有條件,也可以使用 F5 負載,成本比較高

 

3、案例分析

通過上面的分析,相信大家對微服務也有了一個瞭解了,這裏主要是以網盤系統爲案例講解如何規劃它的架構。

首先大概瞭解網盤系統的核心功能(可以登錄系統查看)。網盤主要分爲三個核心部分:網盤後臺、個人文件的管理、以及對接應用系統;它的客戶端類型分爲好多種(比如:網頁版、h5 版本、app 版本等)。那麼我們如何架構網盤的項目架構呢?

 

方案 1:垂直架構
圖片描述

  • 描述:網盤系統和後臺管理系統都是獨立的工程,操作同一份數據庫;
  • 缺點:如果有相同的接口,則重複在兩個工程裏面實現;所有功能都在單體項目裏面實現了。

 

方案 2:微服務架構 1
圖片描述

  • 描述:把 controller 工程和 service 工程獨立,遠程調用接口
  • 優點:共用同一個接口工程,controller 工程變的很薄
  • 缺點:Controller 工程拆分粒度比較粗

 

方案 3:微服務架構 2
圖片描述

  • 描述:把 controller 工程和 service 工程獨立,並且 controller 根據客戶端類型再細分,遠程調用接口
  • 優點:拆分粒度更細,controller 工程變的更薄
  • 缺點:工程數量比較多

 

方案 4:微服務架構 3
圖片描述

  • 描述:controller 根據客戶端類型拆分,Service 也拆分成主要業務和非主要業務並通過 MQ 解耦,總體拆分粒度比較細
  • 優點:拆分粒度更細,整體性能更高
  • 缺點:工程數量比較多

總結:關於工程拆分粒度的總結

①controller 拆分,一般根據根據業務來拆分(比如:訂單、商品);或者客戶端類型來拆分

②service 拆分,一般根據業務來拆分(比如:訂單服務、商品服務);或者根據主要業務和輔助業務拆分(主要目的是提高主要業務的處理速度,快速響應用戶)

總結,其實項目的架構不一定是一步就到位的,我們按照項目的規模、按照項目的併發量來進行選擇。以上四種模式就是架構的一個逐步升級的過程,根據實際情況來選擇合適的架構。

思考:比如,一個網站的首頁應該怎麼規劃呢?網站首頁的功能非常的多,涉及的服務非常的多。

 

方案 1:
圖片描述

  • 描述:整個網站只對應一個 Controller 工程,由 controller 工程再具體調用不同的服務;
  • 優點:只有一個 Controller,相對簡單
  • 缺點:如果 Controller 掛了則整個網站就訪問不了了(當然可以做集羣);無法很好解耦,比如說:秒殺壓力很大,則所有模塊都會受秒殺模塊的影響;如果系統升級的時候,所有模塊都受影響。

 

方案 2:
圖片描述

  • 描述:網站的不同模塊對應不同的 Controller 工程,
  • 優點:這樣壓力也均攤到不同 Controller 上,每個 Controller 工程的後期迭代升級、項目部署都互不干擾。適合更加大型的項目
  • 缺點:架構變的更加龐大了和複雜了。

 

4、小結

本節主要介紹微服務架構的模式,微服務面臨的問題及它的技術解決方案,微服務總體架構圖,以及通過案例來分析微服務架構圖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章