--- 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.?