sop服務治理

一,爲什麼需要服務治理:

我們最先接觸的單體架構, 整個系統就只有一個工程, 打包往往是打成了 war 包, 然後部署
到單一 tomcat 上面, 這種就是單體架構, 如圖:

 

 

 


假如系統按照功能劃分了, 商品模塊, 購物車模塊, 訂單模塊, 物流模塊等等模塊。 那麼所
有模塊都會在一個工程裏面, 這就是單體架構。
單體架構優點
1、 結構簡單, 部署簡單
2、 所需的硬件資源少
3、 節省成本
缺點
1、 版本迭代慢, 往往改動一個代碼會影響全局
2、 不能滿足一定併發的訪問
3、 代碼維護困難, 所有代碼在一個工程裏面, 存在被其他人修改的風險
隨着業務的拓展, 公司的發展, 單體架構慢慢的不能滿足我們的需求, 我們需要對架構進行
變動, 我們能夠想到的最簡單的辦法就是加機器, 對應用橫向擴展。
如圖:
這種架構貌似暫時解決了我們的問題, 但是用戶量慢慢增加後, 我們只能通過橫向加機器來
解決, 還是會存在版本迭代慢, 代碼維護困難的問題。 而且用戶請求往往是讀多寫少的情況,
所以可能真正需要擴容的只是商品模塊而已, 而現在是整個工程都擴容了, 這無形中是一種
資源的浪費, 因爲其他模塊可能根本不需要擴容就可以滿足需求。 所以我們有必要對整個工
程按照模塊進行拆分, 拆分後的架構圖如下:

 

 

 


模塊拆分後, 模塊和模塊之間是需要通過接口調用的方式進行通信, 模塊和模塊之間通過分
流軟件進行負載均衡。 這個架構解決前面的資源浪費問題和代碼管理問題, 因爲我們是對系
統拆分了, 各個模塊都有單獨的工程, 比如我修改商品模塊, 就不需要擔心會不會影響購物
車模塊。 但是這種架構擴展非常麻煩, 一旦需要橫向加機器, 或者減機器都需要修改 nginx
配置, 一旦機器變多了以後, nginx 的配置量就是一個不能完成的工作。 OK, 這時候 SOA
務治理框架就應運而生, 架構圖如下:

 

 

 


基於註冊中心的 SOA 框架, 擴展是非常方便的, 因爲不需要維護分流工具, 但我們啓動應
用的時候就會把服務通過 http 的方式註冊到註冊中心。
SOA 框架中一般會有三種角色: 1、 註冊中心 2、 服務提供方 3、 服務消費方
1、 註冊中心
在註冊中心維護了服務列表
2、 服務提供方
服務提供方啓動的時候會把自己註冊到註冊中心
3、 服務消費方
服務消費方啓動的時候, 把獲取註冊中心的服務列表, 然後調用的時候從這個服務列表中選
擇某一個去調用。
微服務工程的特點:
1、 擴展靈活
2、 每個應用都規模不大
3、 服務邊界清晰, 各司其職
4、 打包應用變多, 往往需要藉助 CI 持續集成工具

二,Eureka 用戶認證
服務續約保活
當客戶端啓動想 eureka 註冊了本身服務列表後, 需要隔段時間發送一次心跳給 eureka 服務
端來證明自己還活着, 當 eureka 收到這個心跳請求後纔會知道客戶端還活着, 纔會維護該
客戶端的服務列表信息。 一旦因爲某些原因導致客戶端沒有按時發送心跳給 eureka 服務端,
這時候 eureka 可能會認爲你這個客戶端已經掛了, 它就有可能把該服務從服務列表中刪除
掉。


Eureka 健康檢測
Eureka 默認的健康檢測只是你校驗服務連接是否是 UP 還是 DOWN 的, 然後客戶端只會調用
狀態爲 UP 狀態的服務, 但是有的情況下, 雖然服務連接是好的, 但是有可能這個服務的某
些接口不是正常的, 可能由於需要連接 Redismongodb 或者 DB 有問題導致接口調用失敗,
所以理論上服務雖然能夠正常調用, 但是它不是一個健康的服務。 所以我們就有必要對這種
情況做自定義健康檢測。


服務下線
比如有些情況是服務主機意外宕機了, 也就意味着服務沒辦法給 eureka 心跳信息了, 但是
eureka 在沒有接受到心跳的情況下依賴維護該服務 90s, 在這 90s 之內可能會有客戶端調用
到該服務, 這就可能會導致調用失敗。 所以我們必須要有一個機制能手動的立馬把宕機的服
務從 eureka 服務列表中清除掉, 避免被服務調用方調用到。

三 服務隔離,降級,熔斷

服務雪崩
雪崩是系統中的蝴蝶效應導致其發生的原因多種多樣, 有不合理的容量設計, 或者是高併發
下某一個方法響應變慢, 亦或是某臺機器的資源耗盡。 從源頭上我們無法完全杜絕雪崩源頭
的發生, 但是雪崩的根本原因來源於服務之間的強依賴, 所以我們可以提前評估。 當整個微
服務系統中, 有一個節點出現異常情況, 就有可能在高併發的情況下出現雪崩, 導致調用它
的上游系統出現響應延遲, 響應延遲就會導致 tomcat 連接本耗盡, 導致該服務節點不能正
常的接收到正常的情況, 這就是服務雪崩行爲。


服務隔離
如果整個系統雪崩是由於一個接口導致的, 由於這一個接口響應不及時導致問題, 那麼我們
就有必要對這個接口進行隔離, 就是隻允許這個接口最多能接受多少的併發, 做了這樣的限
制後, 該接口的主機就會空餘線程出來接收其他的情況, 不會被哪個壞了的接口占用滿。
Hystrix 就是一個不錯的服務隔離框架

Hystrix 服務隔離策略
1、 線程池隔離
THREAD 線程池隔離策略 獨立線程接收請求 默認的
默認採用的就是線程池隔離

2、 信號量隔離
信號量隔離是採用一個全局變量來控制併發量, 一個請求過來全局變量加 1, 單加到跟配置
中的大小相等是就不再接受用戶請求了。


Hystrix 服務降級
服務降級是對服務調用過程的出現的異常的友好封裝, 當出現異常時, 我們不希
望直接把異常原樣返回, 所以當出現異常時我們需要對異常信息進行包裝, 拋一
個友好的信息給前端。
定義降級方法, 降級方法的返回值和業務方法的方法值要一樣

Hystrix 數據監控
Hystrix 進行服務熔斷時會對調用結果進行統計, 比如超時數、 bad 請求數、 降
級數、 異常數等等都會有統計, 那麼統計的數據就需要有一個界面來展示,
hystrix-dashboard 就是這麼一個展示 hystrix 統計結果的服務。

 

Hystrix 熔斷
熔斷就像家裏的保險絲一樣, 家裏的保險絲一旦斷了, 家裏就沒點了, 家裏用電
器功率高了就會導致保險絲端掉。 在我們 springcloud 領域也可以這樣理解, 如
果併發高了就可能觸發 hystrix 的熔斷。
熔斷髮生的三個必要條件:
1、 有一個統計的時間週期, 滾動窗口
相應的配置屬性
metrics.rollingStats.timeInMilliseconds
默認 10000 毫秒
2、 請求次數必須達到一定數量
相應的配置屬性
circuitBreaker.requestVolumeThreshold
默認 20 次
3、 失敗率達到默認失敗率
相應的配置屬性
circuitBreaker.errorThresholdPercentage
默認 50%
上述 3 個條件缺一不可, 必須全部滿足才能開啓 hystrix 的熔斷功能。

熔斷器的三個狀態:
1、 關閉狀態
關閉狀態時用戶請求是可以到達服務提供方的
2、 開啓狀態
開啓狀態時用戶請求是不能到達服務提供方的, 直接會走降級方法
3、 半開狀態
hystrix 熔斷器開啓時, 過一段時間後, 熔斷器就會由開啓狀態變成半開狀態。

半開狀態的熔斷器是可以接受用戶請求並把請求傳遞給服務提供方的, 這時候如果遠程調用
返回成功, 那麼熔斷器就會有半開狀態變成關閉狀態, 反之, 如果調用失敗, 熔斷器就會有
半開狀態變成開啓狀態。
Hystrix 功能建議在併發比較高的方法上使用, 並不是所有方法都得使用的。

 


 分佈式配置中心
分佈式配置中心解決了什麼問題
1、 抽取出各模塊公共的部分, 做到一處修改各處生效的目標
2、 做到系統的高可用, 修改了配置文件後可用在個模塊動態刷新, 不需要重啓服務器

3、 分佈式配置中心配置規則
分佈式配置中心服務端是需要遠程連接代碼倉庫的, 比如 GitHubgitlab 等, 把需要管理的
配置文件放到代碼倉庫中管理, 所以服務端就需要有連接代碼倉庫的配置:
spring.cloud.config.server.git.uri=https://github.com/zgjack/zg-config-repo
spring.cloud.config.server.git.search-paths=config-repo
spring.cloud.config.server.git.username=zg-jack
spring.cloud.config.server.git.password=zg0001jack
4、 客戶端使用配置中心
客戶端只需要指定連接的服務端就行了, 從服務端拉取配置信息

6、 配置動態加載刷新
這個是一個革命性的功能, 在運行期修改配置文件後, 我們通過這個動態刷新功能可以不重
啓服務器, 這樣我們系統理論上可以保證 7*24 小時的工作

1Environment 的動態刷新
動態刷新其實要有一個契機, 其實這個契機就是手動調用刷新接口, 如果你想刷新哪臺主機
的配置, 就調用哪臺註解的刷新接口
刷新接口爲: http://localhost:8088/actuator/refresh
2@Value 注入的屬性動態刷新
其實前面在調用刷新接口後, @Value 注入的屬性是沒有刷新的還是老的配置, 這個也好理
解, @Value 注入的屬性是項目啓動就已經定了的。 如果要使@Value 屬性也刷新, 就必須要
在類上面加上: @RefreshScope 註解。
但是調用每臺主機的刷新接口顯然太麻煩了, 如果需要刷新的集羣機器有幾百臺, 是不是就
需要手動調用幾百次呢, 這幾乎是一個不能完成的工作量。
Springcloud 中也提供了消息總線的東西, 藉助 mq 來完成消息的廣播, 當需要刷新時我們就
只要調用一次刷新接口即可。

消息總線
消息總線其實很簡單, 就是爲了解決一點刷新的功能, 在一個點調用請求刷新接口, 然後所
有的在消息總線中的端點都能接到刷新的消息, 所有我們必須把每一個端點都拉入到消息總
線中來。

消息總線
消息總線其實很簡單, 就是爲了解決一點刷新的功能, 在一個點調用請求刷新接口, 然後所
有的在消息總線中的端點都能接到刷新的消息, 所有我們必須把每一個端點都拉入到消息總
線中來。

Zuul 服務網關
Zuul 是分佈式 springcloud 項目的流量入口, 理論上所有進入到微服務系統的請求都要經過
zuul 來過濾和路由。

zuul 過濾器
Zuul 大部分功能都是通過過濾器來實現的, Zuul 定義了 4 種標準的過濾器類型, 這些過濾器
類型對應於請求的典型生命週期。
apre: 這種過濾器在請求被路由之前調用。 可利用這種過濾器實現身份驗證、 在集羣中選
擇請求的微服務, 記錄調試信息等。
brouting: 這種過濾器將請求路由到微服務。 這種過濾器用於構建發送給微服務的請求, 並
使用 apache httpclient netflix ribbon 請求微服務。
cpost: 這種過濾器在路由到微服務以後執行。 這種過濾器可用來爲響應添加標準的 http
header、 收集統計信息和指標、 將響應從微服務發送給客戶端等。
eerror: 在其他階段發送錯誤時執行該過濾器。

 

 

 微服務系統的權限校驗

 

 

 採用 token 認證的方式校驗是否有接口調用權限, 然後在下游系統設置訪問白名單隻允許
zuul 服務器訪問。 理論上 zuul 服務器是不需要進行權限校驗的, 因爲 zuul 服務器沒有接口,
不需要從 zuul 調用業務接口, zuul 只做簡單的路由工作。 下游系統在獲取到 token 後, 通過
過濾器把 token 發到認證服務器校驗該 token 是否有效, 如果認證服務器校驗通過就會攜帶
這個 token 相關的驗證信息傳回給下游系統, 下游系統根據這個返回結果就知道該 token
有的權限是什麼了。 所以校驗 token 的過程, 涉及到下游系統和認證服務器的交互, 這點不
好。 佔用了寶貴的請求時間。

 

 

獲取 token 的過程
Token 是通過一個單獨的認證服務器來頒發的, 只有具備了某種資質認證服務器纔會把 token
給申請者。
2、 獲取 token
獲取 token oauth2.0 裏面有 4 中模式, 這裏我們講三種


1、 客戶端模式

 

 


我們可以看到客戶端模式申請 token, 只要帶上有平臺資質的客戶端 id、 客戶端密碼、 然後
帶上授權類型是客戶端授權模式, 帶上 scope 就可以了。 這裏要注意的是客戶端必須是具有
資質的。

 


密碼模式獲取 token
密碼模式獲取 token, 也就是說在獲取 token 過程中必須帶上用戶的用戶名和密碼, 獲取到
token 是跟用戶綁定的。
密碼模式獲取 token
客戶端 id 和客戶端密碼必須要經過 base64 算法加密, 並且放到 header 中, 加密模式爲
Base64(clientId:clientPassword),如下:

 

 

 

 

 

 

 

認證服務器和下游系統權限校驗流程

 

 

1zuul 攜帶 token 請求下游系統, 被下游系統 filter 攔截
2、 下游系統過濾器根據配置中的 user-info-uri 請求到認證服務器
3、 請求到認證服務器被 filter 攔截進行 token 校驗, 把 token 對應的用戶、 和權限從數據庫
查詢出來封裝到 Principal
4、 認證服務器 token 校驗通過後過濾器放行執行 security/check 接口, 把 principal 對象返回
5、 下游系統接收到 principal 對象後就知道該 token 具備的權限了, 就可以進行相應用戶對
應的 token 的權限執行

 


授權碼模式獲取 token
授權碼模式獲取 token, 在獲取 token 之前需要有一個獲取 code 的過程。
1、 獲取 code 的流程如下:

 

 

1、 客戶端模式
一般用在無需用戶登錄的系統做接口的安全校驗, 因爲 token 只需要跟客戶端綁定, 控制粒
度不夠細
2、 密碼模式
密碼模式, token 是跟用戶綁定的, 可以根據不同用戶的角色和權限來控制不同用戶的訪問
權限, 相對來說控制粒度更細
3、 授權碼模式
授權碼模式更安全, 因爲前面的密碼模式可能會存在密碼泄露後, 別人拿到密碼也可以照樣
的申請到 token 來進行接口訪問, 而授權碼模式用戶提供用戶名和密碼獲取後, 還需要有一
個回調過程, 這個回調你可以想象成是用戶的手機或者郵箱的回調, 只有用戶本人能收到這
code, 即使用戶名密碼被盜也不會影響整個系統的安全。

 

29、 鏈路追蹤
其實鏈路追蹤就是日誌追蹤, 微服務下日誌跟蹤, 微服務系統之間的調用變得非常複雜, 往
往一個功能的調用要涉及到多臺微服務主機的調用, 那麼日誌追蹤也就要在多臺主機之間進
行, 人爲的去每臺主機查看日誌這種工作幾乎是不能完成的工作,
原理詳見:https://www.cnblogs.com/dw-haung/p/13751030.html



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