~/brunosong

송호식 · 백엔드 개발자

만드는 것까지가 아니라
운영되는 상태까지 만듭니다.

에듀테크와 보험 도메인에서 서비스를 설계하고 레거시를 옮겼습니다. 그 시스템이 실제로 돌아가도록 관측과 배포 기반까지 함께 세웠습니다.

AI에게 물어보세요

준비 중

이력, 기술 선택의 이유, 홈랩 운영 방식까지, 제 자료를 학습한 봇이 대신 답합니다.

질문에 답하는 봇을 붙이는 중입니다. 준비되면 이 자리에서 바로 물어볼 수 있게 하겠습니다.

아키텍처 설계

도메인 경계를 긋고, 그 경계가 시간이 지나도 무너지지 않게 설계합니다.

원인까지 파고드는 방식

같은 패턴 6건

증상에 맞춰 대응하지 않고, 왜 그렇게 됐는지까지 보고 고칩니다.

프로젝트

5개

구인구직 시스템

외주 프로젝트

2025.09 – 2026.07 · 백엔드 · 전체 아키텍처 설계

보험설계사 구인구직 플랫폼입니다. 바운디드 컨텍스트 15개를 헥사고날 레이어 모듈로 갈라, 의존 방향을 사람이 아니라 Maven 이 컴파일 타임에 막게 만들었습니다.

개발자 2명이 만들었고, 포털과 어드민 백엔드 설계를 전부 맡았습니다. 개발은 마무리했고 서비스는 운영 중입니다.

BC 15개 · Maven 모듈 102개 · Entity 125개
도메인 7개 MSA 전환 설계 및 검증
3계층 데이터 레이크 기반 인재추천 에이전트 구축
Spring Boot헥사고날모듈러 모놀리스MSAPostgreSQL

비바샘 시스템 안정화

실무 프로젝트

비상교육 · 2026.04 – 2026.10 · 백엔드 · 안정화 전반

교사용 수업지원 서비스의 안정화를 맡았습니다. 대용량 문서변환 시스템 구축이 중심이고, 관측, 회귀 검증, 스키마 관리, 인증 개선을 함께 진행하고 있습니다.

대용량 문서변환 시스템 구축
Prometheus 관측 체계 구축
Playwright E2E 회귀 테스트 자동화 구축
Spring BootPrometheusPlaywrightFlywayMySQL

차세대 시스템 출력물 재설계

실무 프로젝트

삼성화재 · 2024.12 – 2026.02 · 백엔드 · 출력물 단독 설계 및 구현

대규모 차세대 프로젝트에서 일반보험 출력물 전체를 맡아, 1만 줄 규모의 레거시를 단독으로 재설계했습니다.

12개+ 상품군 출력물 단독 설계 및 구현
핸들러 구조 재설계, 메인 흐름 1,300줄 → 50줄
어노테이션 기반 자동 라우팅 설계
JavaSpring BootJPAMyBatisOracle

관측 체계 구축과 레거시 현대화

실무 프로젝트

웅진씽크빅 · 2022.10 – 2024.12 · 백엔드 · 현대화 및 관측 체계 주도

레거시 20개+ 를 Spring Boot 로 옮기고, 관측 체계를 작은 범위에서 먼저 검증해 공식 도입시켰습니다. 장애를 겪고 나서 아는 구조를 지표로 먼저 보는 구조로 바꿨습니다.

Observability 체계 구축, 장애 월 0건
레거시 20개+ Spring Boot 전환 단독 수행
Jenkins CI/CD 파이프라인 구축
Spring BootKubernetesKafkaOpenTelemetryGrafana

온프레미스 배포·모니터링 현대화

실무 프로젝트

비상교육 · 2020.07 – 2022.10 · 백엔드 · PL(4명)

윈도우 파일서버에 묶여 있던 구조를 리눅스 독립 구조로 옮기고 무중단 배포를 도입했습니다. PL 로 서비스 분리를 리딩했습니다.

Nginx 블루-그린 무중단 배포 구축
프로시저 50개+ 애플리케이션 이관, DB 락 해소
Scouter + ELK + Sentry 모니터링 체계 구축
Spring BootNginxRedisSpring BatchELK

경력

  1. 2024.12 – 현재

    프리랜서

    • 비상교육대용량 문서변환 시스템 구축, 비바샘 안정화2026.04 – 현재자세히 →
    • 삼성화재차세대 일반보험 출력물2024.12 – 2026.02
  2. 2022.10 – 2024.12
    웅진씽크빅스마트올 백엔드, 레거시 현대화 · 과장프로젝트 +
    • 스마트올 콘텐츠 관리 서비스(CMS) 구축과 운영2022.10 – 2024.12
    • 스마트올 학습커리큘럼과 문항 업로드 시스템 구축2023.10 – 2024.03
    • 스마트올 레거시 현대화와 시스템 안정화2023.04 – 2023.09
  3. 2020.08 – 2022.10
    비상교육비바샘 백엔드, 초등 서비스 분리 PL · 과장프로젝트 +
    • 비바샘 서비스 개발과 운영2020.08 – 2022.10
    • 사내 시스템 환경개선과 CI/CD 구축2020.10 – 2021.02
    • 모니터링 체계 구축2021.02 – 2021.04
    • 비바샘 초등 서비스 분리2021.04 – 2021.09
  4. 2018.06 – 2020.07
    아이스크림에듀홈런 중등 서비스 백엔드 · 대리프로젝트 +
    • 홈런 중등 서비스 구축과 운영2018.06 – 2020.07
  5. 2017.03 – 2018.06
    리치앤코굿리치 비즈니스 시스템 백엔드 · 대리프로젝트 +
    • 굿리치 비즈니스 시스템 개발과 운영2017.03 – 2018.06
  6. 2014.07 – 2016.07
    메디카코리아웹 ERP 전환, 물류 앱 · 주임프로젝트 +
    • 물류관리 웹 ERP 전환과 모바일 앱 개발2014.07 – 2016.07

코드 스타일펼치기 +

데이터 이관 시스템 (창작 프로젝트)

DB 커밋과 메시지 전송은 한 트랜잭션으로 묶이지 않습니다. 보내고 커밋이 깨지면 없던 일을 알린 것이고, 커밋하고 보내다 죽으면 아무도 모릅니다. 그래서 보내지 않고 같은 트랜잭션에 적어 두고, 나중에 따로 집어 보냅니다. 상태를 닫는 시점을 어디로 잡느냐가 이 구조의 전부입니다.

전송 로그와 아웃박스 행을 한 트랜잭션에서 같이 적습니다. 여기서는 카프카를 부르지 않습니다. 이 메서드가 커밋되면 보낼 것이 남았다는 사실까지 함께 남습니다.

transfer-application-service/…/handler/TransferExecutionHandler.java
@Component
@RequiredArgsConstructor
public class TransferExecutionHandler {

    private final TransferPersistHelper transferPersistHelper;
    private final DataTransferOutboxHelper dataTransferOutboxHelper;
    private final TransferDataMapper transferDataMapper;


    @Transactional
    public Transfer sendData(Transfer transfer, SourceContentData sourceContentData) {

        List<TransferRequestEvent> transferRequestEvents = transferPersistHelper.persistTransferLog(transfer,sourceContentData);

        for (TransferRequestEvent transferRequestEvent : transferRequestEvents) {

            DataTransferEventPayload dataTransferEventPayload =
                    transferDataMapper.transferRequestEventToDataTransferEventPayload(transferRequestEvent);

            dataTransferOutboxHelper.saveDataTransferOutboxMessage(dataTransferEventPayload,
                    UUID.randomUUID());

        }

        updateTransferSendResult(transfer);

        return transfer;
    }


    public void updateTransferSendResult(Transfer transfer) {
        transferPersistHelper.updateTransferSendResult(transfer);
    }

}
직접 만든 창작 프로젝트의 실제 소스입니다. package 와 import, 그리고 다음 줄을 그대로 옮겨 적은 주석을 걷어냈습니다. 길이 때문에 뺀 자리는 코드 안에 표시했습니다. 판단이 담긴 주석은 원본 그대로입니다.

소개

백엔드 개발자

송호식

기능을 붙이는 일보다, 그 기능이 새벽에 멈췄을 때 무슨 일이 벌어지는지 보이게 만드는 일을 주로 해왔습니다. 관측 체계와 배포 파이프라인을 세우고, 레거시를 옮기고, 프로시저에 갇힌 로직을 애플리케이션으로 꺼내는 일들입니다.

기술은 근거가 설 때만 고릅니다. 데이터 이관 방식을 정할 때는 CDC와 서비스 자체 처리를 먼저 검토해 왜 맞지 않는지 확인한 뒤에 Kafka를 골랐고, 도입 승인이 나지 않았을 때는 작은 범위에서 효과를 먼저 증명하고 공식 도입을 받아냈습니다. 이 사이트에 올린 것들도 같은 방식으로 만들었습니다. 무엇을 골랐는지보다 무엇을 버렸는지를 남겨 두려고 합니다.

더 궁금한 것이 있다면 AI에게 물어보세요 →

Spring Boot레거시 현대화ObservabilityKubernetes
GitHub
github.com/brunosong
Email
playprogramer@gmail.com