1. 程式人生 > >微服務設計 筆記

微服務設計 筆記

微服務設計

一、微服務架構理論

1.六邊形架構
1)六邊形架構(Hexagonal Architecture),又稱為埠和介面卡架構風格;使用介面卡與外界進行互動,外界通過應用層API與內部進行互動。
2)經典分層架構更多的精力放在抽象的分離上,每個層的職責分的很明確。 在六邊形架構中,是用“元件化”的形式來避免耦合的出現,每個業務單元儘可能的最小化,這種方式用一個詞來概括,那就是“扁平化”。
3)經典分層架構分為四層,而對於六邊形架構,一般會分成三層:領域層、埠層、介面卡層。
2.服務的大小
1)某些場景下,認為每個微服務的開發工作量不應大於2個周。
2)黃金法則,對一個微服務的修改及部署,不影響其他服務。

3.微服務的優勢
1)技術異構性
2)高容錯,服務可降級(艙壁)。單個服務故障,不會引起整個系統故障。
3)已於擴充套件 只需擴充套件高負載的應用即可。
4)簡化部署 相對於部署單一大型應用,更簡單。
5)與組織結構相匹配,易於工作分派。
6)組合、重用性。
7)可替代性優化 可以避免無法改造大型單一應用的痛苦。
4.OSGI
OSGI(Open Services Gateway Initiative)支援模組熱部署,方便模組管理.但是其最終基於jvm,一個服務的故障依然會導致整個jvm crush.osgi適合構建單一服務節點的內部應用,對於微服務架構來說,大部分場景下有點不實用;java9之後推出JPMS方式,OSGI的應用場景就更受擠壓了。

二、微服務架構師

1.原則
1)演化 架構師應該從演化的角度看待問題,不應關注具體技術細節,追求完美。
2)分割槽 架構師不應過多關注服務內部的問題,而應更多的關注區域之間的問題。
3)戰略目標的設定不是架構師的職責
4)程式碼治理 把控範例
5)評估技術債務
6)進行例外管理
7)集中治理和團隊建設
2.設計標準
1)監控 健康監控應該標準化,不應該為特定服務改變監控服務。
2)介面
a.API應該與消費方解耦,應選擇技術不相關的實現方式,並易於升級,如可隨意增加欄位,而不影響已有消費者。
b.REST API設計應該基於“資源“,無狀態,URL中不出現動詞,只用名詞,使用GET、POST、DELETE等操作資源。

GET:查詢,POST:新增,PUT:更新,DELETE:刪除
c.API應該有版本的概念。
d.使用Token進行身份校驗,而不是cookie。
e.RFC標準中URL中大小寫是敏感的,雖然實際使用中不敏感,但應統一使用小寫,使用-而不是_做字串分隔符。搜尋引擎認為字元"-"是多個關鍵詞,IE瀏覽器對"_"的支援不好。
f.速度限制
如果對訪問的次數不加控制,很可能會被DDos攻擊。為此RFC6585引入了HTTP狀態碼429(too many requests)。
Github API 使用的三個相關的頭部:
X-RateLimit-Limit: 使用者每個小時允許傳送請求的最大值
X-RateLimit-Remaining:當前時間視窗剩下的可用請求數目
X-RateLimit-Rest: 時間 視窗重置的時候,到這個時間點可用的請求數量就會變成X-RateLimit-Limit的值
g.使用HTTP頭處理快取和併發
h.對大結果集應進行分頁
i.避免多個服務共享一個數據庫的情況
3)關注架構安全性 應妥善處理錯誤請求,可使用斷路器

三、微服務建模

1.原則 高內聚 鬆耦合
2.使用領域工程和界限上下文來劃分服務
3.避免過早劃分服務
4.優先考慮地理位置和組織結構,按照技術接縫劃分並不一定正確。

四、整合

1.選擇合理的介面技術
2.合理選擇編排與協同
通常協同可以更好的降低耦合度

3.避免災難性故障轉移 如:會導致消費者崩潰的訊息,應設定最大重試次數,並及時移入死信佇列。
4.按引用訪問服務資源 如呼叫郵件傳送模組時,往往是延遲傳送的,傳送內容可能已經被修改了,正確的方式是,只發送引用,在傳送郵件時,再查詢詳細資訊。
5.服務應該採用容錯性讀取。
Postel法則,魯棒性原則 每個模組都應該寬進嚴出,對自己傳送的東西嚴格,對接收的東西容錯。

五、分解單塊系統

1.通過界限上下文,找出系統接縫,通過接縫拆分服務及資料庫。 重構資料庫的最佳實踐是,先分離資料庫,再拆分應用。

六、部署

1.CI(Continuous Integration,持續整合)
CD(Continuous Delivery,持續交付)
a.構建流水線,將構建分解為多個階段,快速失敗。
b.在專案初始階段,所有服務可以放在一個構建裡,當服務穩定後,應該每個微服務都有自己的構建。
c.定製化映象,加速部署;將微服務本身也預安裝在映象中,將映象作為構建物。
d.統一配置檔案管理,開發專用部署系統。

七、測試

1.消費者驅動契約測試(Consumer-Driven Contract,CDC)
CDC可以有效避免變更破壞新服務的消費者。CDC會定義消費者的期望,這些期望會變成對生產者的測試程式碼。
2.部署後再測試
僅僅依靠部署之前的測試,不可能把缺陷率將為0。部署與上線是不同的階段,可以通過藍綠部署,部署兩套系統,但只有一套系統接受真正的請求。 也可以採用金絲雀釋出,將一小部分真正的流量引向新版本,進行驗證。
3.平居故障修復時間MTTR勝過平均故障間隔時間MTBF
4.Scrum敏捷軟體開發中,將自動化測試分為了單元測試、服務測試、使用者介面測試三層。

八、監控

1.使用語義監控,我們可以在生產環境執行一些測試用例,當這些案例如果沒有達到我們預期的值時,我們會認為生產環境的某個環境出問題了;如定時開啟首頁等。
2.通過關聯標識,標記呼叫鏈,例如在HTTP首部追加標識。
3.建立標準化的日誌,以標準格式記錄日誌,統一服務指標名稱(響應時間、錯誤率、應用指標等)。

九、安全

1.身份驗證和授權方式
1)SSO
2)SAML安全斷言標記語言 基於XML/SOAP的開源標準資料格式
3)OpenID Connect協議 4)單點登入閘道器 使用閘道器驗證身份與授權;認證通過後,閘道器將主體資訊放在HTTP頭上。
應該進行深度防禦,不應完全依賴單點登陸閘道器。也可以在閘道器上終止HTTPS,進行入侵檢測等。
單點登陸閘道器應該只負責粗粒度的授權,細粒度的授權應該在服務中實現。
2.服務間身份驗證和授權
1)在邊界內允許一切。
2)使用HTTPS基本身份驗證
3)使用SAML或OpenID Connect
4)使用客戶端證書
5)在HTTP之上使用HAMC
當使用HTTPS效能損耗較大,且不能快取時,可以使用HMAC。
HMAC(Hash-based Message Authentication Code,基於HASH的訊息碼),它使用對稱金鑰,將請求的主體和金鑰一起,進行HASH處理。
伺服器也進行hash就知道資料是否被篡改了,但不能防止資料洩露。在亞馬遜S3中使用了該方式。
6)API金鑰
7)SSL之上的流量不能被反向代理伺服器快取。HTTPS的CDN價格較高。
8)混淆代理人問題
成功通過認證的使用者可能會偽裝成其他使用者,訪問他人資料。
3.資料安全
使用加鹽的密碼hash
不應把敏感的資料寫入日誌
4.深度防禦
防火牆/日誌/入侵檢測/網路隔離/作業系統
5.OWASP安全框架 安全威脅Top10

十、組織與系統設計的關係

1.康威定律
任何組織所交付的設計方案在結構上都與該組織的溝通結構保持一致。
反向康威定律
設計糟糕的系統有時迫使組織修改其結構,以適應系統。
2.組織耦合度
通常鬆耦合的組織開發的產品模組化更好,耦合度更低。
典型的緊耦合組織如商業產品公司,鬆耦合組織如開源社群。
3.組織與軟體質量的關係
在windows vista的開發中發現,與組織結構相關聯的指標和軟體質量的相關度最高。而非程式碼複雜度等常見指標。
4.組織應對服務的整個生命週期負責
組織應對服務具有所有權,而非多個組織共享服務所有權。
在涉及多個組織的專案中,不共享服務所有權,會帶來溝通問題。較為有效的解決方案是實行內部開源,互相開放程式碼與文件,像開源專案那樣貢獻與合併程式碼。
保證程式碼質量,與持續可維護性。
5.組織結構應該與界限上下文保持一致。
6.不同業務線間的服務應採用非同步批處理方式,以便可以隨時停機維護。

十一、規模化微服務

1.部署名詞
1)藍綠部署
同時部署兩套冗餘系統,實現不停機升級。涉及在途業務及資料遷移。
2)A/B測試
一部分使用者用老系統/一部分用新系統 驗證新系統可靠性。
3)灰度釋出/金絲雀釋出
在保持老版本可用的情況下,部署一套新系統,新系統有問題立即切換回老系統。
4)滾動釋出
只有一套叢集,無冗餘,每次取出一部分,如20%的伺服器升級,直到全部升級完成。
2.架構安全性措施
在出現故障時,應當能夠恰當的功能降級,而非使整個系統下線。
要防止由於某一服務的故障導致級聯大崩潰。
架構安全性措施:
超時/延遲帶來的危害往往致命,要注意超時機制的使用。
斷路器,下游出現問題時,及時斷開,快速失敗。
艙壁,隔離影響。
隔離,設計上允許下游離線,服務間相互隔離。
3.冪等
4.擴充套件
垂直擴充套件 更好的主機
拆分負載 拆分成不同服務
分散風險 分散部署
負載均衡 SSL往往會在負載均衡器前終止,為了防止資訊洩露,可以嘗試把負載均衡器與後端例項放在一個區域網內。
基於worker的系統 除了負載均衡,也可以通過訊息佇列來降低脆弱性,降低負載。
5.資料庫擴充套件
讀寫分離 擴充套件快取往往比讀寫分離更有效。
寫擴充套件 資料分片,更好的主機,分片擴充套件困難,不能解決HA。
避免共享一個數據庫基礎設施 一個物理資料庫建立多個schema。
嘗試使用CQRS(命令查詢職責分離模式) 將應用程式分為兩部分:命令端和查詢端。命令端處理程式建立,更新和刪除請求,並在資料更改時發出事件。查詢端負責查詢。
6.快取
1)客戶端快取/反向代理和CDN快取/伺服器端快取(一級快取、二級快取)
2)HTTP快取
a.cache-control TTL(Time To Live)指定快取幾秒
b.設定Expires頭部 指定快取到某一具體時間,如:新版本上線時間
c.設定Etag 在URL後增加隨機字串
3)必要時增加寫快取,先寫快取,再寫入資料庫。
4)使用彈性快取 在下游出現故障時,使用快取的資料,比停止服務好。
5)隱藏源服務 在快取故障或大量失效時,要避雪崩。可以通過快速失敗、資料庫本地一級快取等措施保護源服務。
6)應避免多級快取,不要使用過長的快取過期時間,在ISP和使用者瀏覽器中的快取是不受控的。
7)衛報使用了爬蟲技術,爬取自己的網頁,在系統故障時,有一個可使用的靜態網頁。
7.CAP定理
無法同時滿足一致性Consistency、可用性Availability、分割槽容錯性Partition
由於分散式系統必須要分割槽,所以往往權衡選擇AP或CP。
可以在部分功能使用AP、另外一些功能使用CP。

十二、微服務原則

1.微服務理念

核心 自治的小服務
圍繞業務概念建模
自動化的文化
隱藏內部實現細節
一切都去中心化
獨立部署
隔離失敗
高度可觀察
2.問題
要熟悉業務領域,劃分服務。
叢集的部署/監控等問題。
不建議從0開發微服務,優先考慮單體服務。
不應使用資料整合。
微服務應面向業務建模,而非面向技術建模;應