shape

Dodam - 將架構從單體式(Monolithic)遷移至 MSA

概述

消除服務間耦合與部署低效問題,並建置 K3s 叢集

技術棧

  • Java

    Java

  • Kotlin

    Kotlin

  • Spring Boot

    Spring Boot

  • Spring JPA

    Spring JPA

  • Spring Cloud Gateway

    Spring Cloud Gateway

  • MySQL

    MySQL

  • Redis

    Redis

  • Flyway

    Flyway

  • Kafka

    Kafka

  • gRPC

    gRPC

  • Docker Compose

    Docker Compose

  • AWS

    AWS

  • Kubernetes

    Kubernetes

團隊

9 人(後端 2 人、Web 3 人、Android 2 人、iOS 2 人)

期間

2025.03 ~ 2026.03

相關連結

後端原始碼網頁服務

詳細內容

  1. 概要
    • Dodam 是一個擁有超過 500 名使用者的校內智慧校園平台。過去需要人工逐一處理的作業(外宿核准、深夜自習申請、學務行事曆管理等),現在都透過 Dodam 來完成。
    • 開發並維護了 30 天內最高 162.82k 次請求、平均每日 5.4k 次請求規模的服務伺服器。
    • 此網頁服務僅供校內學生使用。
    概要 1
  2. 單體式架構的限制與轉向 MSA
    • 在既有的單一應用程式中,經歷了服務間耦合與部署效率不彰的問題。
    • 由於所有領域(domain)在單一行程中共用資源,特定領域的故障會波及整個系統。
    • 即使是微小的修改,也需要整體重新建置與部署,存在結構性的限制。
    • 以領域邊界為準,將應用程式拆分為 11 個服務,並將 Spring Cloud Gateway 設為單一進入點,負責路由與 OAuth2 驗證。
  3. 因應服務拆分的通訊架構設計
    • 隨著服務拆分,原本透過方法呼叫處理的邏輯必須改以網路通訊來取代。
    • 對需要即時回應的驗證流程採用 gRPC,對無需等待結果的事件(使用者建立、通知發送等)採用 Kafka。
    • 在 Core 模組中共同定義事件結構(schema)與 Topic,將服務間的訊息契約統一化。
    • 因此得以採用可為各服務使用不同語言的多語言(polyglot)架構。
  4. 解決眾多服務的部署與維運複雜度
    • 隨著服務數量增加,每次都要整體建置與部署變得沒有效率。
    • 採用了只偵測並建置有變更服務的 Delta Build,以及各服務依序進行的 Rolling Update。
    • 建置 K3s 叢集(2 台 Worker Node),並僅針對流量集中的核心服務(Gateway、Auth、User)分散配置副本(replica),在有限的基礎架構內確保高可用性。
    解決眾多服務的部署與維運複雜度 1
  5. 後端基礎架構
    • 主要功能由 Spring Boot 伺服器負責,流量較高的 API 則使用 Redis 進行快取。
    • 為了支援以 Dodam 帳號進行的 OAuth 功能,我們營運了 Token 伺服器、OAuth 伺服器、OpenAPI 伺服器等服務。
    後端基礎架構 1
  6. CI/CD 架構
    • 建立 PR 時,透過 GitHub Actions 自動執行 Gradle 建置與測試,以驗證程式碼品質。
    • 合併至 develop 分支時,建置 Docker 映像檔並透過 Docker Compose 部署至開發伺服器。
    • 合併至 main 分支時,建置 Docker 映像檔並透過 kubectl apply 部署至 K3s 叢集的正式環境。
  7. 心得
    • 在親自營運全校學生都在使用的服務、並快速且準確地回應功能建議與故障的過程中,我體會到穩定服務的重要性,並致力於提升程式碼品質與可維護性。
    • 透過轉向 MSA,得以僅針對流量集中的服務選擇性地水平擴充(scale out),讓我體認到以服務為單位的獨立擴充能為維運效率帶來極大的差異。