
들어가기에 앞서
2024.12.14 ~ 2025.3.1 항해플러스 백엔드 7기 과정을 수료했습니다.
10주 동안 어떤 것을 배우고 경험했는지, 과정 중 했던 기술적 고민들과 좋았던 부분들을 돌아보며 마지막으로 이 과정을 추천하고 싶은 분들에 대해 이야기하고자 합니다.
항해플러스 관련 이전 글
돌아보면 짧은 10주, 수료하다!
무엇을 했나요?
- TDD & 메모리 기반 동시성 제어 기본 학습 및 과제 진행 (깃허브 링크)
- 특강 신청 서비스 – 클린 + 레이어드 아키텍처, 동시성 제어, TDD 적용 (깃허브 링크)
- 대규모 트래픽을 고려한 대기열 기반 콘서트 예약 서비스 구현 (깃허브 링크)
- "CDC를 통한 안전한 메시지 전달" 주제 발표
어떤 결과를 만들었나요?
- 20개의 주차별 과제 중 19 Pass (
- 상위 1% 실력 인증 블랙뱃지 수여
- Best Team 선정

무엇에 집중하며 임했는가?
항해 플러스 과정에서 다루는 기술 스택들은 이미 업계에서 "핫한" 기술들이며, 나 또한 과정 이전에도 모두 이론적으로 공부해보고 간단히 적용해본 경험이 있었다.
그러나 공부하는 것과 실무에서 활용할 수 있는 것은 전혀 다른 문제이다.
따라서 주차별 과제를 수행할 때마다
- 실무에서 적용하려면 어떻게 해야 할까?
- 트레이드오프는 무엇일까?
- 이 기술을 도입하기 위해 다른 팀원들을 설득할 수 있을까?
등의 질문을 스스로에게 던지며, 단순하게 과제를 통과하는 것이 아닌 실제 현업에서 활용할 수 있는 수준까지 깊이 고민해보는 것에 집중하며 과제를 진행했다.
기술적 고민들
Kotlin + JPA Entity 유일 ID 전략 적용
데이터베이스의 샤딩과 파티셔닝까지 고려하여 유일 ID 생성 전략을 사용하고자 했다.
유일성과 정렬 가능성을 모두 만족하는 ID 생성 방식으로 UUID, ULID, TSID, Snowflake 등을 검토한 결과,
간단하게 적용하기 쉽고 UUIDv7(128비트)보다 TSID(64비트)가 더 효율적이라고 판단하여 TSID 방식을 선택하였고, 아래와 같이 적용했다.

JPA의 @Id 필드는 값이 null 또는 0인지 여부를 기준으로 새로운 엔티티인지 판단한다.
그러나 위 사진처럼 nullable이 아닌 필드를 선언하면 null을 할당할 수 없기 때문에,
JpaRepository.save() 호출 시 isNew()가 false로 반환되어 INSERT 쿼리가 정상적으로 실행되지 않는 문제가 발생했다.
그렇다고 ID 필드를 nullable하게 선언하는 것은 Kotlin의 철학과 맞지 않아 근본적인 해결책이 아니라고 판단했으며,
더 엣지있는 해결 방법을 고민하던 중, 스포카에서 Kotlin으로 JPA Entity를 정의하는 방법 이라는 아티클이 큰 도움이 되었다.
위 아티클을 참고해서 Persistable<T> 인터페이스의 isNew()를 오버라이드하고,
`@PostPersist`, `@PostLoad` 어노테이션을 활용하여 엔티티가 영속화되거나 로드된 이후에는 isNew()가 false를 반환하도록 구성했다.
이를 공통 BaseEntity에 적용하여, 각각의 JPA 엔티티가 이를 상속받아 사용하도록 구성함으로써 초기에 달성하고자 했던 목표인 코틀린 + JPA 환경에서 Null-Safety하게 유일 ID 전략을 채택하여 사용하는 것을 달성할 수 있었다.
대기열 유량 제어 방식 선정 (은행창구 방식 vs 놀이공원 방식)
대기열은 크게 은행창구 방식과 놀이공원 방식으로 구현할 수 있는데, 각각의 장단점이 있고 딱 잘라서 어느 방식이 더 좋다고 할 수 없어 처음에는 RDB를 통해 은행창구 방식으로 구현해본 뒤 이후 레디스를 적용하며 놀이공원 방식으로 전환해보았고, 두 가지 방식 모두 구현하며 느낀점에 대해 문서를 작성하였다.

범용적으로 사용할 수 있는 분산 락 컴포넌트 개발
분산 락에는 여러 가지 종류가 있지만, 기본적으로 락 획득 → 로직 수행 → 락 해제의 순서로 동시성을 제어한다.
그러나 락의 획득과 해제는 비즈니스 로직과 관심사가 다르므로, AOP와 커스텀 어노테이션을 활용해 이를 분리했다. 또한, 다양한 분산 락 방식을 추상화하고, 전략 패턴을 적용하여 상황에 맞는 락 전략을 유연하게 선택할 수 있도록 분산 락 컴포넌트를 개발했다.
그 결과, 이후 다른 프로젝트에서도 쉽게 적용할 수 있는 범용적인 분산 락 모듈을 완성할 수 있었다.
어느 프로젝트에나 쉽게 적용 가능한 분산락 컴포넌트 개발 (feat. Spring)
Intro항해플러스에서 진행중인 프로젝트인 콘서트 예약 서비스를 분산환경이라고 가정하고, 기존에 DB 락을 통하여 동시성 제어가 되어있던 부분을 분산락을 통해 제어하도록 리팩토링하고자 하
sandcastle.tistory.com
인덱스 개선을 통한 조회 성능 개선
서비스에서 발생하는 조회 쿼리들의 실행 계획을 수집·분석한 뒤, 더미 데이터를 삽입하여 조회 속도가 얼마나 개선되었는지 검증해본 뒤 문서를 작성하는 과제를 진행했다. (문서 링크)
이전에 인덱스를 추가하면서 조회 성능이 향상되는 경험을 해본적은 있으나, 정확한 동작 원리에 대해서는 알지 못한 채 인덱스를 추가했었다.
따라서 과제를 진행하면서 단순히 인덱스 추가 -> 조회 쿼리 실행 -> 와 빨라졌다!의 결론만 내리는 것이 아니라, 동작원리에 대하여 깊게 공부해봐야겠다고 생각했고, B-Tree 자료구조부터 공부하며 다양한 상황에서 어떤 인덱스가 적절한지 깊이 탐구하는 시간을 먼저 가진 후 과제를 진행했다.
분산 환경에서 안전한 메시지 전달
분산 환경에서 메시지 유실을 방지하기 위한 기법으로, Transactional Outbox 패턴을 적용해보는 과제를 진행했다.
설계했던 outbox 테이블
create table outbox
(
`id` varchar(13) not null comment 'PK'
primary key,
`idempotency_key` varchar(255) not null comment '멱등성을 보장하기 위한 키, 중복 처리를 방지',
`topic` varchar(255) not null comment '메시지가 발행될 토픽명',
`event_key` varchar(255) null comment 'Kafka 메시지의 Key (파티셔닝에 사용 가능)',
`message` mediumblob not null comment '이벤트 메시지 본문',
`status` varchar(255) not null comment '이벤트 처리 상태 (PENDING / DELIVERED)',
`created_at` timestamp(6) not null comment '생성 시점',
`updated_at` timestamp(6) not null comment '마지막 수정 시점'
)
comment '아웃박스';
OutboxScheduler
@Component
class OutboxScheduler(
private val outboxService: OutboxService
) {
private val log: Logger = LoggerFactory.getLogger(javaClass)
@Scheduled(fixedRate = 10000)
fun processOutbox() {
// 'PENDING' 상태의 아웃박스 데이터 목록 조회
val outboxList = outboxService.readPendingMessages()
outboxList.forEach {
outboxService.send(it)
}
}
}
스케줄러를 이용해 10초마다 테이블에서 'PENDING' 상태의 아웃박스 데이터를 조회한 뒤, 각 항목을 순회하며 메시지를 전달하도록 구성했다. 하지만 실시간성이 중요한 경우, 스케줄러의 주기를 짧게 설정해야 하므로 데이터베이스에 과부하가 발생할 수 있다는 문제가 있었다. 또한, 메시지가 중복 발행될 가능성이 있어 멱등 키를 활용해 이를 방지해야 했다.
이를 보완하기 위해 CDC(Change Data Capture)를 활용한 메시지 전달 방안을 검토했으며, 매주 토요일마다 진행하는 "토요지식회"에서 "CDC를 활용한 안전한 메시지 전달"이라는 주제로 발표까지 진행했다.

문서화
좋은 개발자가 되기 위해 빠질 수 없는 중요한 역량 중 하나가 바로 문서화하는 능력이다. 항해 플러스에서도 이를 의식한 듯, 대부분의 주차별 과제가 문서화와 관련된 내용이었다.
그럼에도 불구하고 많은 개발자들은 문서화를 귀찮아하거나, 문서화의 필요성을 크게 느끼지 못하는 경우가 많다. 나 또한 지금까지는 하드 스킬을 익히는 데 집중하면서, 글을 잘 쓰는 능력이나 문서화하는 능력은 후순위로 미뤄왔다. 하지만 우주님의 '테크니컬 라이팅' 영상을 보고 더 이상 미룰 수 없다고 생각했다.
과제를 하면서 문서화를 완벽하게 잘했다고는 할 수 없지만, 문서화를 잘하기 위해 노력했는가? 라는 질문에는 자신 있게 "그렇다"라고 답할 수 있다.
앞으로도 문서화 역량을 꾸준히 키워나갈 것이며, 이를 나만의 강력한 무기로 만들고 싶다.

아고라에서의 경험
항해플러스 슬랙의 아고라 채널에서는 자유롭게 질문을 주고받으며, 과제를 하면서 고민했던 포인트를 공유할 수 있다.
나 역시 우아하게 분산 락을 적용하는 방법에 대해 고민한 내용을 블로그 글로 작성하고 공유한 적이 있었는데, 예상보다 좋은 반응을 얻었다. 특히, 댓글을 통해 내가 미처 고려하지 못했던 부분을 짚어주신 분들이 있어, 새로운 시각을 얻고 생각이 확장되는 계기가 되었다.
이렇게 같은 주제로 함께 고민해보는 경험은 앞으로 개발자 커리어를 이어 나가면서도 큰 의미가 있을 것이라 생각한다. 개발은 혼자만의 고민으로 해결하기 어려운 문제들이 많고, 서로의 경험과 인사이트를 공유하는 과정에서 더 나은 해결책을 찾을 수 있기 때문이다.
항해플러스 과정을 한다면 반드시 아고라는 적극적으로 활용해볼 것을 권장한다.


소중한 인연들
무엇보다 열정 있는 개발자 동료들을 많이 만나게 된 것이 이번 과정에서 얻은 가장 큰 자산이 아닐까 싶다.
처음에는 낯을 많이 가리는 성격이라 어색하기도 하고 걱정도 되었지만, 주차별 과제에 대해 온라인에서 피드백을 주고받으며 점점 익숙해졌다. 또한, 네트워킹 파티와 같은 세션을 통해 자연스럽게 동기들과 친해질 수 있었다.
비록 항해플러스 7기 과정은 끝났지만, 여기서 만난 인연들은 앞으로도 이어질 것이기에 아쉬움보다는 기대가 더 크다.
더욱이 다음 기수의 학습 메이트로 선발되면서, 앞으로 만나게 될 새로운 개발자들과의 교류도 기대된다. 배움과 성장을 함께할 소중한 인연들이 앞으로도 계속해서 이어지길 바란다 :)

이런 분들께 추천합니다.
- 개발 공부를 체계적으로 하고 싶지만, 무엇을 어떻게 공부해야 할지 막막한 분들
→ 항해플러스는 실무에서 자주 사용되는 기술과 개념을 중심으로 커리큘럼이 구성되어 있어, 방향성을 잡고 집중적으로 학습할 수 있습니다. - 이론적으로 공부한 내용을 실무에 적용하는 경험이 부족한 분들
→ 단순히 문법이나 개념을 배우는 것이 아니라, 프로젝트를 개발하며 학습하기 때문에 실무에서의 적용 방법을 자연스럽게 익힐 수 있습니다. - 코드 품질과 아키텍처에 대해 깊이 고민해보고 싶은 분들
→ 단순히 기능 구현을 넘어서 클린 아키텍처, 도메인 주도 설계(DDD), 테스트 주도 개발(TDD) 등을 실습하며 코드의 유지보수성과 확장성을 고려해보는 경험을 할 수 있습니다. - 성능 최적화와 트러블슈팅을 경험해보고 싶은 분들
→ 동시성 제어, 대규모 트래픽 대응, 쿼리 튜닝 등 실무에서 필수적인 최적화 기법들을 직접 적용하며 학습할 수 있습니다. - 주변에 개발자가 많지 않아 자신의 실력과 방향성이 궁금한 분들
→ 동기들과 함께 공부하며 피드백을 주고받고, 실력 있는 멘토들의 코드 리뷰를 받으며 성장할 수 있습니다. - 혼자 공부하는 것이 쉽지 않아, 강한 동기 부여가 필요한 분들
→ 10주 동안 몰입해서 공부할 수 있는 환경이 조성되어 있고, 꾸준히 과제를 수행하면서 성장하는 과정을 경험할 수 있습니다.
※ 주의
어떤 과정이든 단순히 참여하는 것 만으로는 원하는 결과를 얻기 어렵습니다. 가장 중요한 것은 "과정에 어떻게 임하는가"입니다.
적극적으로 고민하고, 질문하며, 직접 적용해보는 과정이 수반될 때 비로소 의미 있는 성장으로 이어질 수 있다는 점을 유의해야 합니다.
현재 항해플러스 백엔드 8기 모집중이며, 아래의 코드로 등록 시 20만원의 할인 혜택을 받으실 수 있습니다.
-> UUsaDg
https://hanghae99.spartacodingclub.kr/plus/be
항해 플러스, 도전을 넘어 개발자 커리어 도약으로
백엔드 주니어 개발자로서 성장의 한계를 느끼고 있다면, 시니어 코치진과 함께 10주 몰입을 통해 도약하세요.
hanghae99.spartacodingclub.kr
관련해서 궁금한 점이 있으신 분들은 댓글로 남겨주시거나, 아래 남긴 링크드인 주소로 메시지 주시면 성실하게 답변 드리겠습니다 :)
'외부활동 > 항해플러스' 카테고리의 다른 글
항해플러스 3~5주차 회고 (0) | 2025.01.17 |
---|---|
항해 플러스 백엔드 2주차 회고 - Clean Architecture (0) | 2024.12.30 |
항해 플러스 백엔드 1주차 회고 - TDD (2) | 2024.12.22 |
항해플러스 백엔드 7기를 시작하며... (1) | 2024.12.20 |
개발을 하며 만났던 문제들과 해결 과정, 공부한 내용 등을 기록합니다.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!