《Spring微服務實戰》讀書筆記——構建微服務
設計微服務架構
構建程式碼的腳手架
分解業務問題
- 描述業務問題,安裝名詞來描述問題
- 注意動詞
- 尋找資料內聚性
確定服務粒度
使用資料模型作為將單體應用分解到微服務的基礎。
可以通過下面的概念來確定正確的服務粒度:
- 廣泛的使用微服務和重構為更小的服務
- 關注你的服務如何與其他服務互動
- 隨著你對問題領域的理解不斷增長,服務職責將不斷變化
感受不好的微服務設計
服務粒度太粗:
- 服務具有太多的職責
- 服務通過大量的表管理資料
- 測試用例過多
服務粒度太細:
- 在部分問題領域有太多微服務
- 微服務彼此嚴重依賴
- 微服務組成一個簡單的CRUD服務集
微服務應該負責一種業務邏輯
定義服務介面
/**
* @RequestMapping 暴露Controller的根URL
* {organizationId}是一個佔位符,表示URL在每次呼叫會傳遞一個organizationId引數
*/
@RestController
@RequestMapping(value = "/v1/organizations/{organizationId}/licenses")
public class LicenseServiceController {
/**
* @RequestMapping(
* method = {RequestMethod.GET}
* )
*
*
* @param organizationId 通過@PathVariable來訪問
* @param licenseId
* @return
*/
@GetMapping(value="/{licenseId}")
public License getLicenses(
@PathVariable("organizationId") String organizationId,
@PathVariable("licenseId") String licenseId) {
return License.builder()
.id(licenseId)
.productName("Teleco")
. licenseType("Seat")
.organizationId(organizationId)
.build();
}
}
端點的名稱問題
微服務的URL應該能清楚的表達服務的目的,儘量使用下面的準則:
- 使用明確的URL名稱建立服務所代表的資源
- 為URL建立早起版本控制方案
URL 及其相應端點表示服務所有者和服務消費者之間的契約。一個常見的模式是在所有端點前使用一個版本號。及早建立你的版本控制計劃並堅持下去。在已經有好幾個使用者使用它們之後,為 URL 升級版本是非常困難的。
微服務開發的四項原則
- 微服務應該是獨立和單獨可部署的,多個服務例項作為單獨的軟體構件啟動和停止。
- 微服務是可配置的,當服務例項啟動時,它應該從配置中心讀取所需的資料來配置自己,或將其配置資訊傳遞為環境變數。配置服務不需要認為干預
- 微服務例項需要對客戶端透明
- 微服務應該顯示其健康狀況
示例圖
構建微服務應用的十二要素
基準程式碼
所有應用程式程式碼和伺服器配置資訊都應處於版本控制中。每個微服務在原始碼控制系統內有自己獨立的程式碼庫。
依賴
通過使用構建工具如 Maven(java)顯式宣告你的應用程式的依賴。第三方 JAR 依
賴性應該使用其特定版本號宣告。這允許你的微服務總是使用相同版本的 lib 庫進行構建
配置
獨立於程式碼儲存應用程式配置。你的應用程式配置不應該與原始碼在同一個儲存庫中
後端服務
你的微服務往往會通過網路與一個數據庫或訊息系統迚行通訊。當它這樣做時,
你應該確保在任何時候,你都可以將資料庫的實現從內部管理的服務轉換為第三方服務。
構建,釋出,執行
將你的構建,釋出,和執行部署的應用程式各部分完全分離。一旦程式碼
被構建,開發人員就永遠不應該在執行時對程式碼進行更改。 任何修改都需要重新執行構建
過程和重新部署。構建的服務是不可變的,不能更改。
程序
你的微服務應該是無狀態的。它們在任何時候都可以被殺死和取代,而不必害怕一個受損的服務例項將導致資料丟失。
埠繫結
一個微服務對服務的執行時引擎(打包在服務的可執行檔案)是完全獨立的。
你將能執行該服務而不需要分離的 Web 或應用伺服器。服務應該在命令列中獨立啟動,並通過暴露的 HTTP 埠立即被訪問。
併發
當需要進行伸縮時,不要依賴於單個服務中的執行緒模型。相反,載入更多的微服務
例項和在水平方向擴充套件。這並不排除在你的微服務使用執行緒,但別指望把它作為你伸縮的唯一途徑。規模擴大,而不是上升。
通用性
微服務是一次性的,一經要求就可以啟動和停止。啟動時間應儘量減少,當接收到
作業系統的一個終止訊號時,程序應該優雅地關閉
開發環境不線上環境等價
最小化服務執行的所有環境之間的差距(包括開發人員的桌面)。
開發人員應該在本地使用與實際服務將執行的相同的基礎設施來進行服務開發。它還意味著服務在環境之間部署的時間應該是幾個小時,而不是幾個星期。一旦程式碼被提交,它應該已經被測試和從開發一直到生產儘快升級。
日誌
日誌是一個事件流。一旦日誌被輸出,它們對工具將是可流化的,如 Splunk或Fluentd ,它們將聚合日誌並將其寫入到中心儲存裝置。微服務不應該關心這項技術是如何出現的,當日志正在被輸出的時候,開發人員應該在視覺上通過 STDOUT看日誌。
管理程序
開發人員常常不得不針對他們的服務(資料遷移或轉換)執行管理任務。 這些任
務不應該是臨時的,而應該通過原始碼儲存庫管理和維護的指令碼來完成。這些指令碼應該是可重複的,並且在它們執行的每個環境中都不改變(在每個環境中都不修改指令碼程式碼)。