Mingyu Park | Backend Developer

Dodam - Migrating the Architecture from Monolithic to MSA

Overview

Eliminating inter-service coupling and deployment inefficiencies while building a K3s cluster

Tech Stack

  • Java
  • Kotlin
  • Spring Boot
  • Spring JPA
  • Spring Cloud Gateway
  • MySQL
  • Redis
  • Flyway
  • Kafka
  • gRPC
  • Docker Compose
  • AWS
  • Kubernetes

Team

9 members (2 Backend, 3 Web, 2 Android, 2 iOS)

Period

2025.03 ~ 2026.03

Details

  1. Overview
    • Dodam is an in-school smart school platform with over 500 users. Tasks that were previously handled manually one by one (overnight-leave approvals, late-night self-study applications, academic schedule management, etc.) are now handled through Dodam.
    • Developed and maintained the service server, which handled up to 162.82k requests over 30 days, averaging 5.4k requests per day.
    • The web service is available only to students within the school.
    Overview 1
  2. Limitations of the Monolith and the Move to MSA
    • Experienced problems with inter-service coupling and deployment inefficiency in the existing single application.
    • Because all domains shared resources within a single process, a failure in one domain affected the entire system.
    • There was a structural limitation in which even small changes required a full build and redeployment.
    • Split the application into 11 services along domain boundaries and placed Spring Cloud Gateway as a single entry point to handle routing and OAuth2 authentication.
  3. Designing the Communication Architecture for Service Separation
    • As services were separated, logic previously handled through method calls had to be replaced with network communication.
    • Applied gRPC for authentication flows that require an immediate response, and Kafka for events that need no waiting for a result (user creation, notification dispatch, etc.).
    • Defined event schemas and topics commonly in the Core module to unify the message contracts between services.
    • This enabled a polyglot architecture in which different languages could be used per service.
  4. Reducing the Deployment and Operational Complexity of Many Services
    • As the number of services grew, building and deploying everything each time became inefficient.
    • Applied a Delta Build that detects and builds only changed services, along with per-service sequential rolling updates.
    • Set up a K3s cluster (2 worker nodes) and distributed replicas only across the core services with concentrated traffic (Gateway, Auth, User), securing high availability within a limited infrastructure.
    Reducing the Deployment and Operational Complexity of Many Services 1
  5. Backend Infrastructure
    • Core features are handled by a Spring Boot server, and high-traffic APIs are cached using Redis.
    • To support OAuth with a Dodam account, we run services such as a Token server, an OAuth server, and an OpenAPI server.
    Backend Infrastructure 1
  6. CI/CD Architecture
    • When a PR is created, GitHub Actions automatically runs the Gradle build and tests to verify code quality.
    • On merge into the develop branch, a Docker image is built and deployed to the development server via Docker Compose.
    • On merge into the main branch, a Docker image is built and deployed to production on the K3s cluster via kubectl apply.
  7. Reflections
    • By operating a service used by the entire student body and responding quickly and accurately to feature requests and incidents, I came to appreciate the importance of a stable service and worked to improve code quality and maintainability.
    • Through the move to MSA, I could selectively scale out only the services with concentrated traffic, which made me realize how much independent, service-level scaling improves operational efficiency.