不久前,我終于決定深入到微服務的世界了。我確實花了相當長的時間尋找使用這種架構模式的機會,并最終找到了。在經過三個月的嘗試和學習,其中大部分都是自學(困難的方式),我相信是時候分享一些經驗了。
他從講述一些核心的系統設計方面開始,其中包括API管理(gateway)。他引入了“服務總線”的概念,而沒有真的定義它。他還討論了存儲服務的添加:
[...] 為了在只讀數據庫(這里就是CQRS一類的東西)中存儲對象,你很可能需要訂閱所有類型的事件,像UserCreated和InvoicePaid等等。然后你需要與特定的(微)服務通信獲取數據,然后將它存入數據庫中。在這種場景下,你的API需要負責訂閱事件、映射數據和保存數據到數據庫。這有問題嗎? 多數情況下當然沒有。但是,我更傾向于下述解決方案。它將API和微服務完全分離。這樣,就出現了所謂的存儲服務,由它來訂閱事件,從(微)服務獲取數據等等。存儲服務知道怎樣扁平化數據。API只需要給存儲服務發送HTTP請求來獲取數據。它并不需要關心數據是從哪里來的,是內部的數據庫,還是緩存,還是處于天涯海角的某個服務。
最后在給出他的經驗和教訓(他稱為“小貼士和竅門”)之前, 他用對服務的定義總結了設計方面。服務的部分定義包括:
每個(微)服務處理自己的領域模型、倉庫、業務邏輯等等。整個基礎服務唯一共有的是服務總線和一套命令和事件集合。
那么回到小貼士和竅門。我們這里只包含其中一部分。對那些認為微服務的大小重要的人,首先是“讓服務盡量小”。
創建多個小型的專注于單一領域的微服務比創建少量臃腫的執行完全不同任務、在相同的范圍內管理不相干職責的微服務要好。最常見的例子有:創建/驗證用戶賬戶、 發送消息、管理產品、處理支付等等。每個領域納入到單獨的有獨特實體的服務中。
從別人對微服務、事件溯源和CQRS的說法展開,Piotr認為CQRS至關重要:
遵循CQRS,你需要做的全部事情是發送無返回值的命令和執行冪等的查詢。如果你遵循這一模式,你會很快發現擴展應用程序簡單多了,只需要分離讀寫操作。
接下來回到數據。為服務選擇數據庫的方式至關重要。這再次和其他人討論的相似:
每個服務(不是單個服務實例,因為你可能有許多同一服務的實例運行在不同的節點上)都應該有自己的數據庫。這樣你不僅能消除單點故障(整個系統使用單一的龐大數據庫) ,最重要的是還能自由選擇最適合特定任務的數據庫。你可能想使用SQL執行嚴重依賴事務的金融操作,或者使用NoSQL數據庫存儲數十億JSON文檔。
Piotr提到了其它一些事情,如請求追蹤(他舉例說明了在他的學習之旅中的實現方法 )、使用異步消息方法(使用HTTP)、確保新服務易于部署(可能隱晦地引用到持續集成和持續部署)以及編寫端到端測試。最后提到的是“包含故障恢復、服務發現和其它一些有用的機制"。
任何時候出錯了,你可能希望保證整個系統不會崩潰或者至少其中一部分不會崩潰。確保你引入了重試機制(比如Polly)、服務發現工具,如Consul以及集中保存證書,比如使用Vault、Azure Key Vault或者我的開源項目Lockbox。
Piotr討論的大部分和過去這些年別人說的非常相似,所以在使用微服務開發時我們很可能正趨向一個關于方法有效還是無效的共識。但是需要注意的是,盡管Piotr討論了他的一些經驗和教訓,但是沒有任何關于他開發的應用程序表現如何的說明(負載下擴展、恢復能力等等)。可能后期會有,我們拭目以待。