---
tags: jubo, tutorials
title: 微服務實踐
---
###### tags: `jubo` `tutorials`
[TOC]
## 前言
### 微服務的「大小」重要嗎?
:::spoiler **EXPAND**
- 「微服務」這個術語,無可厚非地會將我們的關注點錯誤地聚焦在「微」上。**但大小從來不是一個重要的考量因素**
- 微服務架構的目標是要將應用程式通過一些小的、**鬆散耦合**的服務組織在一起,藉此**提高開發效率**,特別在:
1. **可維護性** (maintainability)
2. **可測試性** (testability)
3. **可部署性** (deployability)
4. **可擴展性** (scalability)
:::
### 我們「需要」微服務架構嗎?
:::spoiler **EXPAND**
- 重點其實不是我們「需不需要」,而是**我們已經在用了!**
- 以 NIS 主體,周邊有許多衛星服務,難道不是為了實現鬆散耦合、可獨立維護、獨立部署等目的而開發的嗎?
- Jubo Space 與北美專案,看似可以與 NIS 無關,但我們總會考慮到任何可能再利用我們 NIS 所累積的資料或與 NIS 本體做交互的可能性。這難道不也是考慮上述四點而進行發展的嗎?
- 又考慮到我們採用 [SaaS](https://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E5%8D%B3%E6%9C%8D%E5%8A%A1) 為主要商業模型,且積極採用 [Cloud Native](https://docs.microsoft.com/zh-tw/dotnet/architecture/cloud-native/definition) 的方法論在構築我們的商業產品
- 故本質上,我們已經跟微服務緊密耦合了
- 且我們的確有一些問題可以透過微服務架構來解決:
- NIS 單體架構搜集到的 logs/metrics 雜訊過多無法聚焦問題,阻礙排錯作業
- 各模組、應用情境不同,但單體應用的可擴展手段有限
- 難以理解與維護,隱性地降低開發速度
- 不易寫測試,阻礙鍛鍊更廣泛技術能力的機會
:::
### 為何要談微服務架構?
:::spoiler **EXPAND**
- 需要了解在討論「微服務架構」時,真正**需要考慮的各方面**,以及**哪些技術方案應可積極採用**,也**確立更多的溝通術語**在我們的架構討論上
- 了解更多之後,我們**才能知道還有哪些落差**,在實現商業目標的同時才能更佳地**瞻前顧後**
:::
### 微服務架構下最契合的「組織溝通模型」?
:::spoiler **EXPAND**
- 坊間討論這件事時,都提到最契合的組織架構是:**每一個微服務**都明確**有一個團隊**負責
- 但我們 **only one engineering team**,還能把微服務架構玩好嗎?
- 我個人覺得:邊做邊調整
- 或當成,提前打造好適合組織人力擴充時的架構
- 我們還是試著提出一個漸進式策略:拉出「微服務強固 (reinforcing) 工作小組」開始展開一些前期工作及試著拆分 NIS 單體應用
- 此時,**新開發的微服務**能明確地**由此工作小組負責**
- 個人想像的中後期發展:
1. 全端小夥伴接到商業需求,需要去迭代微服務時,由工作小組的人確實 review
2. 工作小組的人員在人力資源調度面允許固定下來,那就真的穩定接收後端需求、負責迭代所有微服務囉
:::
### 如何「使用」微服務架構?
:::spoiler **EXPAND**
- 採納微服務架構,需要我們備妥所有**可觀測性基礎建設**,及梳理出**標準排錯步驟**,發揮此架構真正的價值
- 也需要我們在新建的(後端)服務滿足可觀測性的要求,及撰寫足夠的自動化測試例,以對齊用微服務來重構單體應用的目標
:::
## 單體架構 vs. 微服務架構
![](https://i.imgur.com/qBNIQbF.png)
### Applications/Microservices 的抽象架構
|||
|---|---|
|![](https://i.imgur.com/19VDVra.png)|![](https://i.imgur.com/Huw7oaf.png)|
| | |
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
- (左) 單體應用中常見的 [3-tier](https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures#traditional-n-layer-architecture-applications) 架構
- (右) 微服務架構中,每一個微服務基本上也是此架構
### 微服務應用的「四層架構」
![](https://i.imgur.com/OYJlhis.png =600x)
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
- 微服務應用則會進一步用此模型來討論整體的概念:
- **客戶層 (Client)**: 與整個微服務應用後端互動的用戶端應用。Web applicationa, mobile apps... etc.
- **邊界層 (Boundary)**: 暴露給用戶端進行互動的服務。通常在這層做一些滿足用戶端需求的聚合操作
- **服務層 (Services)**: 我們大部分時間都在開發這一層的服務。這層的服務區通常又可明確地區分成
1. 業務服務 (business service): 職責是**直接實現業務目標**
2. 技術服務 (technical service): 職責是**實現服務間共享的技術功能**
- **平台層 (Platform)**: 支援微服務快速開發、運行、通訊、部署的元件、基礎建設
:::warning
:thinking_face: 其中比較陌生的應該是:**平台層**負責了什麼?
![](https://i.imgur.com/a8ttWL8.png)
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
- 圍繞在 Service 周圍的 Observability, Deployment pipeline, Communication, Service discovery...etc.,都可被歸類在平台層的範疇
- 而這些平台層的基礎建設,都已有完善的解決方案。直接對照我們目前採用的 tech stacks:
![](https://i.imgur.com/r0OaIwp.jpg)
:astonished: 啊~ 所以其實「四層架構」,比較像是下圖:
![](https://i.imgur.com/Qd0bBZp.png)
:::
## 溝通模式 (Communication Patterns)
### 同步訊息傳輸 (Synchronous Messages)
![](https://i.imgur.com/4xN2vp6.png)
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
- 是最熟悉、最容易理解與測試的溝通模式
- 內部服務的溝通流行使用 gRPC (with protobuf contracts),視情況繼續使用 RESTful HTTP (with JSON contracts)
:name_badge: 缺點
- 服務間的耦合仍然高。過度使用的情況,會造成調用路徑非常脆弱
- ![](https://i.imgur.com/ylDfzdS.png)
> source: [docs.microsoft.com](https://docs.microsoft.com/en-us/dotnet/architecture/microservices/architect-microservice-container-applications/communication-in-microservice-architecture#asynchronous-microservice-integration-enforces-microservices-autonomy)
- 在等待下游服務時,上游服務的程式通常是被阻塞的 (blocking)。此時若流量過大,會造成資源耗盡、連鎖故障
- :::success
:bulb: Solution: [Pattern: Circuit Breaker](https://microservices.io/patterns/reliability/circuit-breaker.html), 後面會再探討實作面怎麼善用 [Istio](https://istio.io/latest/docs/tasks/traffic-management/circuit-breaking/) 來完成
:::
:::warning
:thinking_face: **Does gRPC faster than RESTful HTTP?**
其實 gRPC 很多效能上的優勢是利基於 HTTP/2 的結果。所以許多文章比較的 gRPC 與 RESTful HTTP,反而是在比較 HTTP/1.1 與 HTTP/2,不太公平。
故若我們不探討執行效率的問題,採用 gRPC 還能帶來什麼益處?
我覺得是「開發體驗」的提升,尤其當業務持續發展,內部越來越多服務的時候,能夠保持較良好的開發與團隊內的溝通效率。
我認為關鍵有二:
1. 利用 protobuf 定義 contracts 後,就是一種 code as a document,不用額外維護 API 文件
2. 透過自動生成的 [client stubs](https://en.wikipedia.org/wiki/Stub_(distributed_computing)),作為 package 被你的程式引用。你的程式碼就變成一堆 function call 去調用 remote server,IDE 也能利用 [IntelliSense](https://code.visualstudio.com/docs/editor/intellisense) 這類功能幫你自動補全、參數提示、member lists、method lists 等
References:
- [gRPC recommended scenarios - docs.microsoft.com](https://docs.microsoft.com/en-us/aspnet/core/grpc/comparison?view=aspnetcore-6.0#grpc-recommended-scenarios)
- [gRPC vs. REST: How Does gRPC Compare with Traditional REST APIs?](https://blog.dreamfactory.com/grpc-vs-rest-how-does-grpc-compare-with-traditional-rest-apis/)
- [Is gRPC(HTTP/2) faster than REST with HTTP/2?](https://stackoverflow.com/a/44937371/8694937)
- [Why milliseconds matter](https://www.yonego.com/nl/blogs/why-milliseconds-matter/)
:::
:::warning
:thinking_face: 用戶端 (Clients) 與邊界層 (Boundary) 之間也有機會使用 gRPC 嗎?
Of course!有興趣的人可先了解一下,一起逃離文件維護地獄:
- [grpc-web - gRPC for Web Clients](https://github.com/grpc/grpc-web)
- [The Dart implementation of gRPC](https://pub.dev/packages/grpc)
:::
### 非同步訊息傳輸 (Asynchronous Messages)
![](https://i.imgur.com/msQJc81.png)
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
- 有一個**事件代理人 (event broker)**,儲存 producers 產生的「事件」;有興趣的 consumers,向代理人訂閱、取得那些事件
- **最適合用在微服務溝通的模式,使得服務之間交換訊息更有彈性**
- 發布訊息的上游服務不需要擁有下游服務的知識,徹底將服務解耦,避免服務越來越多陷入相互依賴地獄
:::info
:information_source: 在 [Communication in a microservice architecture - docs.microsoft.com](docs.microsoft.com) 甚至提到:
> *If possible, **never depend on synchronous communication** (request/response) between multiple microservices, not even for queries.*
且說 sync mode 是 anti-pattern 呢 :thinking_face:
![](https://i.imgur.com/LiMRV70.png =500x)
:::
- 而在非同步傳輸中,還有**兩種最常見的基本模式**需要明確做出區別,分別是:**Job queue** 與 **Publish-subscribe**
#### :point_right: Job queue
![](https://i.imgur.com/XAciJAo.png)
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
- 多個 workers 消化同一個 job queue;i.e. **一個 job 只被一個 worker 處理到 (沒有重工)**
#### :point_right: Publish-subscribe
![](https://i.imgur.com/w1nfb05.png)
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
- 一個事件可以發送給任意個監聽者;每個監聽者都能拿到發布的事件並自己做處理
## 測試策略 (Testing Strategies)
![](https://i.imgur.com/6LCTrSh.png)
> source: https://martinfowler.com/articles/microservice-testing/#conclusion-test-pyramid
- 很直覺地,在此架構上若要對整體系統做到完善的測試,是比單體架構更有挑戰的
- 以下以微服務架構的角度,再回顧各種測試的守備範圍 (及實務上的可執行策略),最後也簡介一下 Load Testing
### 單元測試 (Unit Testing)
:::success
:bulb: *A unit test exercises the smallest piece of testable software in the application to determine whether it behaves as expected.*
> source: https://martinfowler.com/articles/microservice-testing/#testing-unit-introduction
:::
![](https://i.imgur.com/Py027K6.jpg =400x)
:::info
:information_source: 何謂「一個 unit」?
其實它就像**單一職責原則**一樣,是一個無法量化並明確界定範圍的概念,範疇取決於你要服務的對象。那麼就表示它可以小到是一個 **pure function**、或是一個 [express](https://expressjs.com/zh-tw/4x/api.html#req)/[Gin](https://gin-gonic.com/docs/quickstart/#getting-started) 的 **request handling function** 的實作。
:::
#### 不執行 Network Communication
- 被歸類在 unit testing 的 test cases 中,**不真的執行 network communication**
- e.g. external services、3-rd party services、databases
:::info
:information_source: 那些對外部服務的依賴,在你的實作上可採用[**依賴反轉原則**](https://www.youtube.com/watch?v=e0UOuQ_lCUY&t=3506s)來實作,就能夠在 test cases 中利用[**依賴注入 (Dependency injection)**](https://en.wikipedia.org/wiki/Dependency_injection#Testing)的方式,用 mock objects 取代,以滿足測試情境的需求。
:::
#### 測試內部重要邏輯
- 測試那些重要的商業邏輯或共用元件
- 人生苦短,關注在那些你覺得容易犯錯,或是複雜的部分就好
:::info
:older_adult: *Kent Beck : “I get paid for code that works, not for tests”*
TDD 之父 Kent Beck 於 [stackoverflow](https://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565) 上一篇詢問「unit testing 該做得多深入」的問題答到:他傾向不花時間去測試那些不容易犯錯的部分。而是花時間去測試自己與他人容易犯錯的部分、擁有複雜的邏輯的部分。
:::
#### 在本地開發環境及 CI 環境中執行
- 此種測試在本地開發應會非常頻繁地被執行
- 提 MR 的**旁支**應在 CI 環境中通過測試後才可要求 review;若旁支測試失敗,不應讓它併入主分支
- 若 CI 環境中的測試失敗,理應中斷 pipeline,避免進入 CD 環節
### 整合測試 (Integration Testing)
:::success
:bulb: *An integration test **verifies the communication paths** and interactions between components to detect interface defects.*
> source: https://martinfowler.com/articles/microservice-testing/#testing-integration-introduction
:::
![](https://i.imgur.com/lVOwQyu.jpg =500x)
> source: https://martinfowler.com/articles/microservice-testing/#testing-integration-diagram
#### 真的執行 Network Communication
- 目標是驗證真的進行 network communication 時,service 內的 **success and error paths** 如期運作
- 記住,仍專注在驗證 service 內部與外部接觸的元件邏輯,而不是驗收外部的服務的正確性
#### 在本地開發環境及 CI 環境中執行
- 此種測試一樣可在 CI 環境中執行完畢
:::warning
:thinking_face: 有資料庫依賴怎麼辦?
- 在 CI 環境中用 docker 運行資料庫的 contianer
- CI 環境的 DB URL 指向該 container 進行測試
- test cases 中免不了得自己撰寫創建假資料、初始化資料庫內容的步驟
:::
:::warning
:thinking_face: 有其他微服務依賴怎麼辦?
- protobuf 會同時生成 server/client stubs
- 故在 test cases 中可以用 server stubs 真的運行一個 mocking server 來滿足測試
![](https://i.imgur.com/aMh5602.png =500x)
:::
:::warning
:thinking_face: 有其他第三方服務依賴怎麼辦?
- 視情況 (工時+效益一起評估),原則上若可以實作一個 mocking server 則優先考慮
- 若成本太大,再考慮僅用 interface 製作 mock objects 做 unit testing
:::
### 元件測試 (Component Testing)
:::success
:bulb: *A component test limits the scope of the exercised software to **a portion of the system** under test, manipulating the system **through internal code interfaces** and using **test doubles** **to isolate the code under test from other components.***
> source: https://martinfowler.com/articles/microservice-testing/#testing-component-introduction
:::
![](https://i.imgur.com/OYlzPp8.jpg)
#### 測試服務的 Public API
- 對微服務架構來說,components 指的就是 microservices 本身
- 故利用服務的 contract of the API 進行測試即可
:::success
:bulb: 以下面的 gRPC contract 為例,元件測試就會測試 rpc `SayHello` 的行為是否如其運作:
```protobuf
// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
```
:::
#### 真的執行 Network Communication
- 與整合測試一樣,對於外部服務的資賴會使用 stubs/mocks 等方式取代
- 對於資料庫的依賴,可考慮實作 in-memory 的版本;但其實我們都在容器化的環境中測試,可直接運行一個拋棄式的資料庫實體即可
#### 在本地開發環境及 CI 環境中執行
- 此種測試一樣可在 CI 環境中執行完畢
### 端到端測試 (End-to-end Testing)
:::success
:bulb: *An end-to-end test **verifies that a system meets external requirements** and achieves its goals, **testing the entire system**, from end to end.*
> source: https://martinfowler.com/articles/microservice-testing/#testing-end-to-end-introduction
:::
- 此種測試**將整體微服務系統視為黑盒子**,也就是說測試的進入點是在**邊界層**,或是直接透過 GUI 介面操作來進行測試
- 當觀點是整體系統時,就會發現涉及到許多 moving parts,故撰寫並維護此類的測試將相當困難。又**若系統有非同步行為**,可能無法期待測試結果具有「確定性 (deterministic)」
- 個人相信的觀點:這類的測試由**測試工程師**來進行會較合適。他們比 develoeprs 更關心真實使用者的利益,且能避免球員兼裁判的盲點,更有機會測出有價值的部分
:::warning
:thinking_face: 有其他替代方案嗎?
其中一種方案:採用 Canary Deployment 的技巧,將特定 users 或一定比例的流量導進新版服務,並透過**可觀測性 (observability) 元件**的輔助了解系統的狀況。
![](https://i.imgur.com/JZNdUiq.png)
> source: https://harness.io/blog/blue-green-canary-deployment-strategies/
:::
### 負載測試 (Load Testing)
![](https://i.imgur.com/C1tcVqM.png)
> source: https://k6.io/docs/test-types/introduction/
- **Smoke Test**:目的是利用最小的負載驗證 test script 是否正確
- **Load Test**:會去了解**併發用戶數**與 **RPS** 對系統效能的影響
- **Stress Test/Spike Test**:給予**極限條件**下,評估系統的穩定性
- **Soak Test**:了解系統沈浸在**長時間負載**時的可靠性和效能
- 以上的測試種類,皆可用同一個 test script,再搭配不同的 test configration 來變換測試種類以達到不同的目標
:::info
:information_source: 可以先在 [k6 的官方介紹](https://k6.io/docs/test-types/introduction/)中找到更多介紹。未來若有更加明確的 [Service Level Agreements (SLAs)](https://en.wikipedia.org/wiki/Service-level_agreement), [Service Level Objectives (SLOs)](https://en.wikipedia.org/wiki/Service-level_objective) 或 [Service Level Indicators (SLIs)](https://en.wikipedia.org/wiki/Service_level_indicator) 的需求,也應會直接採用 k6 這套工具
:::
:::info
:information_source: 也不是所有的 testing types 都適合做自動化,再看看 k6 如何建議 [Automated performance testing](https://k6.io/docs/testing-guides/automated-performance-testing/)
:::
### 個人實務心得
![](https://i.imgur.com/cQZRcJq.png =500x)
- 時間有限的情況下,都直接做 component testing,直接有效
- 覺得有需要做 integration testing 的地方,優先考慮是不是直接做 component testing 來涵蓋
- 需求變動太多,不敢寫太多 unit testing 給自己套上枷鎖。只在重要商業邏輯假設上撰寫
## 可觀測性 (Observability)
![](https://i.imgur.com/KKL4Lg4.png)
- 在微服務架構下,需要思考如何讓開發者對各個**服務間的交互行為**及**基礎建設的運行狀況**有更高的掌握度,也就是提升所謂的**可觀測性**
- 提升可觀測性有兩大目標:
1. 出現不符預期的情況時能儘早發現、介入並處理;
2. 若無法搶先一步,至少要有能力快速指出需要關注的區域
- **可觀測性技術堆疊**提供了搜集、儲存、展示與分析資料的方法。平時會就可能搜集越多的度量指標與資訊,以備不時之需
:::info
:information_source: Prometheus, Loki, Jaeger, Istio, Grafana 及 Profiler 是我們目前使用的可觀測性技術堆疊 (observability tech stack)
:::
### Macro-level: 3 Pillars of Observability
![](https://i.imgur.com/z1GXfwA.png)
> source: [Elastic 的 Observability 解決方案 - ithelp article](https://ithelp.ithome.com.tw/articles/10266276)
- 有三種資訊,需要服務**主動**提供 (via instrumenting),以構築所謂的可觀測性:
1. Logs
2. Metrics
3. Traces
- 這三樣元素都會有各自的 GUI 面板展示它,並讓我們利用它們來分析服務的狀況
![](https://i.imgur.com/iWsGZOu.png =600x)
> source: [Microservices in Action](https://www.manning.com/books/microservices-in-action#toc)
#### Logs
- 簡單來說就是程式輸出的 logs,程式運行時紀錄重要處理步驟,以利未來排錯及分析
- 通常使用**結構化的方式輸出成 JSON format**,讓後面的日誌分析系統做索引、整合
- 同時妥善利用 logging package 提供的**分級 (levels)**,至少將 logs 分成 **Debug**, **Info**, **Warn**, **Error** 等層次,以利建立度量指標及警訊規則
![](https://i.imgur.com/6BRpY8e.png)
> source: our Grafana Explore
#### Metrics
- 利用時間序列資料格式儲存系統運作及服務的資訊。 e.g.
- CPU, Memory, Disk 使用量
- HTTP requests 相關資訊
- 各服務業務領域內的需求
- 大多數警訊規則也是根據這些度量指標來設定閾值
![](https://i.imgur.com/zNFEyuM.png)
> source: our Grafana Dashboard
:::info
:information_source: **The Four Golden Signals** - [*Google SRE Book*](https://sre.google/sre-book/monitoring-distributed-systems/)
Google SRE 團隊根據他們維運雲端系統的經驗,建議可從以下切角去設計度量指標:
1. **延遲 (Latency)**
- 量測 requests 的耗時
- 伺服器**正常回應**與**異常回應**的延遲應分開計算,避免抽樣偏誤
2. **錯誤量 (Errors)**
- 通常會計算 HTTP status code 的數量
3. **流量 (Traffic)**
- 通常會計算 RPS (requests per second)
- response bytes
4. **飽和度 (Saturation)**
- 量測你的服務目前有「多滿」
- 通常在使用量還沒達到 100% 之前就會開始出問題。大概 60% 就需要介入了解並因應
- 而通常,一個小窗口的R99延遲突然升高,會是一個早期飽和訊號
:::
#### Traces
![](https://i.imgur.com/hfOatOP.png =600x)
> source: https://www.oreilly.com/library/view/distributed-systems-observability/9781492033431/ch04.html
- 利用在 request chain 裡傳遞 uuid (e.g. `X-Request-ID` in header),tracing system 可以有效掌握一筆 request 流經各個服務所花費的時間
- application 可以進一步將 `X-Request-ID` 寫在 logs 裡,完整地整合 logs 與 traces 資訊給後續排錯分析
![](https://i.imgur.com/P576xWg.png)
> source: our Grafana Explore
### Micro-level: Continuous Profiling
![](https://i.imgur.com/dO9Tq8e.png)
:::warning
:thinking_face: 為何需要 **Continuous Profiling**?
- 我們總是不方便在產品發生問題後,才去 profiling 我們的 application。因為事後可能很難重現問題
- 前面提到的可觀測性三本柱,能夠採集到的資訊還是過於宏觀,許多問題需要更細微的資訊來排查 root cuase
:::
- 搜集 CPU 執行時間與記憶體使用量的切片,來了解任何一個時刻服務內的詳情
:::info
:information_source: [Google Cloud Profilier]( https://cloud.google.com/profiler/docs/concepts-profiling) 支援的 profiles
![](https://i.imgur.com/oIA0Elm.png)
:::
- 現在很流行使用[火焰圖](https://cloud.google.com/profiler/docs/concepts-flame)來解讀 profiling 的資訊
- 重新組合 call stacks
![](https://i.imgur.com/xzNjeQL.png)
- 解讀火焰圖
![](https://i.imgur.com/G47LE0F.png)
![](https://i.imgur.com/METpn83.png)
> source: https://www.brendangregg.com/flamegraphs.html
:::info
:information_source: Open Source Continuous Profiling Platform - https://pyroscope.io/
![](https://i.imgur.com/r3hdOBC.png)
- 除了支援線上 Continuous Profiling,本身也支援本地端運行的 profiling 模式,有舒服的 GUI 直接玩
:point_right: [Live Demo](https://demo.pyroscope.io/?name=hotrod.python.frontend%7B%7D&query=cart.service.dotnet.cpu%7B%7D)
:point_right: also has [Grafana Plugins](https://pyroscope.io/docs/grafana-plugins/)
![](https://i.imgur.com/sqPVX4O.jpg)
:::
## 結語
- 還有些技術議題沒提到,看我們能走到哪,未來再補充
- :point_right:如何設計高可靠性的服務
- retry strategy
- timeout
- circuit breaker
- rate limiting, ...etc.
- :point_right:微服務的 Transactions 與 Queries (分散式系統的一致性)
- [Saga pattern](https://microservices.io/patterns/data/saga.html)
- [CQRS](https://microservices.io/patterns/data/cqrs.html) (command-query responsibility segregation pattern)
- [Event sourcing](https://microservices.io/patterns/data/event-sourcing.html), ...etc.
- 若目標是建構一個穩固且可靠的微服務架構,當然不可避免要克服設計、開發與維運上的挑戰。但技術問題其實都好解決,**最難的是**建構一個**有責任感且具備維運意識的工程師文化 (responsible and operationally aware engineering culture)**
![](https://i.imgur.com/VBiyqR8.png)
### Vote for next sessions
- 微服務框架下延伸的內容
1. Kubernetes 使用者須知 (high-level architecture, workloads, storage and networking)
2. 可觀測性技術堆疊的架構概觀及微服務如何協作
3. 探索 Message Queue 的可能性 - 以 RabbitMQ 為例
4. 單體架構遷移策略: 以 Domain-Driven Design 進行思考
- 雜談
1. Web Security - Don’t Trust User Input (SQL injection, XSS, CORS, CSRF, CSP, JWT, OAuth?)
2. 探索 RDBMS 的可能性 - (可能)以 Postgres 為例 (ACID, TX, isolation levels, common SQL statements, pratical recommendations)
3. 探索 Caching 的可能性 - 以 Redis 為例 (general rules, pratical issues and recommendations)
- Go
1. Testable project layout (dependency inversion, consistent structure)
2. Go Slices: usage and internals
3. ...etc.?