전체 글 53

[Docker] BuildKit으로 Docker 빌드 80% 더 빠르게 만드는 우아한 방법

이 글에서는 많은 개발자가 CI/CD 파이프라인에서 겪는 문제인 '느린 Docker 이미지 빌드 시간'을 어떻게 단축시켰는지에 대한 과정을 공유하고자 한다.프로젝트 규모가 커지고 의존성이 복잡해질수록 Docker 이미지 빌드 시간은 기하급수적으로 늘어난다. 우리 팀 역시 초기에는 빌드에 7분-9분이 소요되어 개발 생산성에 큰 영향을 미치고 있었다. 여러 단계에 걸친 최적화 작업을 통해 이 빌드 시간을 1분까지 단축하는 데 성공했다. 무려 80% 이상의 시간을 절약한 결과다. 💡 이 내용은 우아한테크코스 7기 테코톡에서도 발표했습니다. 영상으로 보고 싶으신 분들은 참고해주세요!https://youtu.be/8B8jXKaKBrw?si=6W4kqbkkwBthjuT5 이 글에서는 적용했던 다음과 같은 핵심 ..

개발괴발/Docker 2025.11.24

[Spring] 한 번 이긴 유저가 1등? 승리요정 랭킹 공정성 개선기 (45초 → 0.14초)

목차 개요 초기 승리요정 랭킹의 문제점 성능 문제 - 비효율적인 쿼리 구조 공정성 문제 - 불합리한 랭킹 기준 공정한 랭킹을 위한 베이즈 정리 도입 기존 해결책들의 한계 베이즈 정리란? 베이즈 평균을 코드에 적용하기 부하테스트와 인덱스 최적화 첫 번째 부하테스트 - 충격적인 결과 인덱스 튜닝으로 개선 시도 통계 테이블로 근본적인 해결 Redis를 선택하지 않은 이유 통계 테이블 설계 스케줄러 기반 데이터 관리 통계용 테이블 조회 성능 최적화 초기 통계 테이블 조회 쿼리 인덱스 실험들 서브쿼리 + FORCE INDEX..

공뷰/Spring 2025.11.22

[Spring, MySQL] 야구보구 현장톡의 모든 것 - 1편 (Polling, Cursor Pagination, 인덱스 튜닝)

이 글은 야구보구의 현장톡 기능을 설계하고 구현한 과정을 기록한 것이다.현장톡 기능을 어떤 방식으로 만들었는지부터, 인덱스 튜닝을 통해 성능을 개선한 과정까지 정리해두었다. 참고로 현장톡에는 ‘좋아요’ 기능도 포함되어 있는데, 이 부분은 내용이 길어져 다음 글에서 따로 다루려고 한다. 완성된 야구보구의 현장톡아래는 완성된 현장톡 화면이다.실제 서비스에서는 좋아요 광클, 실시간 메세지, 신고 기능까지 포함된다. 왜 polling인가?현장톡 기능을 맡고 처음 고민했던 건 어떤 방식으로 채팅을 구현할지였다.일반적으로 채팅은 세 가지 방식이 많다pollingWebSocketsse우리 팀도 처음엔 야구 경기 중엔 사람이 몰리니까 WebSocket이 맞겠다고 생각했다.하지만 현실적인 판단 기준은 다음과 같았다 👇..

공뷰/Spring 2025.11.18

[Spring, HikariCP] 커넥션 풀 고갈로 인한 서버 병목 해결하기

야구보구를 개발하면서, "현장톡"이라는 실시간 채팅 기능을 만들었다. 경기 중에 홈런이나 역전이 터지는 순간에 채팅방이 폭발적으로 올라가는 상황을 상상하면서 부하테스트를 돌렸는데, 생각보다 빨리 DB 커넥션 풀(hikariCP)이 다 찼다. 이 글은 그 과정에서 겪었던 커넥션 풀 고갈 패턴을 어떻게 재현하고, 모니터링으로 상태를 관찰하고, 설정을 조정해서 TPS를 71 → 91(약 28.6% 향상)까지 끌어올렸는지 정리한 글이다. 문제가 된 요청 POST /api/v1/talks/{gameId}문제가 된 요청은 POST /api/v1/talks/{gameId} 현장톡을 생성하는 API였다.톡이 생성되면, 처음으로 톡을 작성한 조건을 만족하는 유저에게 뱃지를 발급하는 비동기 로직이 함께 동작한다. 뱃지 ..

공뷰/Spring 2025.11.08

[Prometheus, Grafana] 야구보구 부하테스트 모니터링 구축기 (k6 → Prometheus → Grafana)

야구보구 모니터링현재 야구보구 모니터링 스택은 Grafana, Prometheus, Loki, Promtail, Tempo로 구성되어 있다.기존에는 cloudwatch를 사용했는데, cloudwatch의 여러 한계점을 만나게 되었다. cloudwatch를 사용하면 Log Insights로 엔드포인트별 응답 시간 정도는 볼 수 있었지만, 상태 코드나 비즈니스 지표(구장별 실시간 톡 메시지 수, 하루 동안 전체 체크인 발생 수, 승리요정 랭킹 등) 같은 세밀한 커스텀 메트릭을 코드 단에서 커스텀하기가 어려웠다.또한 인프라, 데이터베이스, 애플리케이션 로그가 각기 다른 대시보드에 분산되어 있어 하나의 화면에서 통합적으로 관찰하기 어려웠고,API가 느려질 때 DB 쿼리/외부 API/서버 중 어디가 원인인지도 알..

개발괴발/Devops 2025.11.04

우아콘 2025 솔찍 후기

우아한 형제들에서 주최하는 우아콘에 우아한테크코스 소속으로 운 좋게 당첨되어서 컨퍼런스에 다녀왔다. 작년에는 신청했는데도 광탈했는데 이번엔 우테코 크로 자격으로 초대받아서 기뻤다. 내가 속한 '야구보구'팀은 운 좋게 7명 모두 당첨되어 다 같이 컨퍼런스에 참석할 수 있었다. 인상적이었던 발표고객의 편리함을 완성하는 프로세스, 배민 사용자경험관리(우미라 님, 유진주 님)처음 들었던 강의이다. A세션에 참가하려다가 사람이 너무 많아서 두 번째로 듣고 싶던 강의를 찾아갔는데, 오히려 훨씬 인상 깊었다. 우미라 PM님은 고객을 놓쳤던 실제 경험을 바탕으로, 어떤 기준으로 서비스를 바라봐야 하는지를 이야기해주셨다.야구보구를 만들 때 “최대한 사용자 관점에서 개발하고 싶다”는 생각으로 고민했던 내 경험이 떠올라 공..

회고 2025.10.29

[Spring] 야구보구의 실시간 기능, 배포 후 발생한 SSE 문제 정리(nginx 설정)

야구보구 홈 화면에서는 오늘 인증된 구장별 팬 현황을 실시간으로 보여주는 기능을 구현하고 싶었다.이를 위해 여러 방식을 고민했고, 그중 SSE를 선택했다. SSE를 도입하게 된 이유와 구현 과정은 아래 글에서 자세히 정리해 두었다.이 글에서는 SSE를 실제로 배포하는 과정에서 발생했던 문제점과 해결 과정을 중심으로 다룬다. [Spring] 야구보구 홈 화면 SSE(Server-Sent Events)로 실시간 팬 현황 갱신하기왜 SSE를 선택했는가야구보구 홈 화면에서는 오늘 인증된 구장별 팬 현황을 실시간으로 보여주고 싶었다.현재 홈 화면은 다음과 같다. 이를 위해 몇 가지 방법을 고민했었다. Polling클라이언트가nourzoo.tistory.com 🔧 dev 서버에서의 테스트SSE는 아래와 같은 방식..

공뷰/Spring 2025.10.05

[Spring] Soft Delete와 영속성 컨텍스트 (flush, clear, JPA 엔티티 상태)

📖 배경우리 프로젝트는 Member와 Talk 모두 soft delete로 설계한다. 멤버가 탈퇴하더라도 프로필만 “알 수 없음”으로 노출하고, 현장톡 메시지 자체는 보존해야 하기 때문이다. 따라서 다음과 같이 매핑했다.🧑‍🤝‍🧑 Member: 탈퇴하더라도 db상엔 정보 존재💬 Talk: 메시지는 삭제하지 않고 보존// Member@SQLDelete(sql = "UPDATE members SET deleted_at = now() WHERE member_id = ?")// Talk@SQLDelete(sql = "UPDATE talks SET deleted_at = now() WHERE talk_id = ?")@SQLRestriction("deleted_at IS NULL") // 조회 시 자동 필..

공뷰/Spring 2025.09.29

[Spring] 야구보구 홈 화면 SSE(Server-Sent Events)로 실시간 팬 현황 갱신하기

왜 SSE를 선택했는가야구보구 홈 화면에서는 오늘 인증된 구장별 팬 현황을 실시간으로 보여주고 싶었다.현재 홈 화면은 다음과 같다. 이를 위해 몇 가지 방법을 고민했었다. Polling클라이언트가 n초마다 서버에 “변경 있오?”라고 묻는 방식이다.하지만 변화가 없어도 계속 요청이 날아간다. 사용자가 늘어날수록 불필요한 요청이 폭발적으로 증가하고 서버 리소스 낭비가 심해진다. WebSocket양방향 실시간 통신에 적합하지만 별도 프로토콜이라 서버/인프라 설정이 복잡해진다.이 프로젝트는 “서버 → 클라이언트 알림”만 필요했기 때문에 과한 선택이었다. SSE(Server-Sent Events)클라이언트는 연결만 유지하면 되고, 서버는 변화가 생겼을 때 이벤트를 발행하기만 하면 된다.HTTP 기반이라 브라우저..

공뷰/Spring 2025.09.15

[AWS] CloudWatch 알람 Discord로 보내기 (SNS + Lambda 활용)

이 글은 야구보구 프로젝트에서 서버 헬스체크 알림을 Discord와 연동해 운영한 경험과 시행착오를 작성한 글입니다. 📌 왜 Discord를 선택했는가?많은 팀이 알림 툴로 Slack을 사용합니다. 하지만 Slack 무료 요금제는 90일 이전 메세지를 못 보는 큰 단점이 있었습니다. 반면 Discord는 메세지 보존 기간에 제약이 없고, 메시지 형식도 Slack보다 깔끔하다고 판단했습니다.그래서 저희는 알림 채널을 Discord로 통일하기로 결정했습니다. 🏗️ 전체 구조저희는 AWS EC2 서버를 사용하고 있었기 때문에, AWS의 CloudWatch + SNS + Lambda 조합을 이용했습니다.전체 흐름은 다음과 같습니다.CloudWatch Alarm이 서버 상태 임계치를 감지한다.감지된 이벤트..

개발괴발/Devops 2025.09.08