목록전체 글 (66)
supernovaMK
비동기를 도입하게 된 배경GiveMeTicket 선착순 예매 서비스를 구축 중이다. 오픈 직후 몰리는 트래픽의 대부분인 '매진 요청'이 DB 커넥션을 낭비하는 현상을 막기 위해서 조회 병목을 캐시로 완화하고 재고 차감 로직을 Redis Lua 스크립트를 사용해 MySQL 부하 최소화를 적용하였다. 하지만 apply(티켓팅 신청) 코드를 다시 리뷰하는 과정에서 문제점을 발견했다.public ApplicationResponse apply(Long campaignId, Long userId) { CampaignState state = campaignStateRepository.find(campaignId) .orElseThrow(CampaignApplicationException::n..
소프트웨어 개발 동아리인 그리디 동아리에서 운영과 활동을 하며 회고를 담은 글입니다.그리디 소개 홈페이지우테코는 끝났는데 학교로 가서 뭐하지?우아한테크코스에서의 10개월 간의 몰입이 끝난 후 학교로 돌아오게 되었다. 당시에 주위에서 함께 공부하던 크루들은 취업을 바로 준비하게 되었고, 나는 자격 요건등이 맞지 않아 졸업을 먼저하고 돌아와야겠다는 생각으로 가득 차 있었다. 취업에 바로 성공하는 크루들을 보면서 내심 부럽기도하고 나도 할 수 있을까? 라는 걱정만 많았던 겨울이었다. 나의 길을 찾기 위해서 학교로 돌아가 어떤 것들을 할 수 있을지들을 생각해보았다. 학교로 돌아가서 경험할 수 있는 것들 중에 가장 큰 것은 사람들을 만나는 것이었다. 새로운 사람들을 만나 새로운 환경에 노출되는 것이 내가 지향하는..
내가 진짜 겪은 AI Agent의 병목지점은 무엇일까..?AI 에이전트를 잘 사용하기 위해 최근 여러 방식이 나오고 있는 것 같다. 프롬프트를 잘게 쪼개거나 에이전트를 역할별로 나누는 등 다양한 기법이 존재한다. 나는 에이전트 활용에서 가장 중요한 것은 그저 '내가 원하는 결과를 잘 만들어냈는가?'라고 생각한다. 에이전트를 어떤 방식으로 사용하든, 프롬프트를 얼마나 잘 다듬었든, 결국 본질적인 평가는 원하는 결과물의 완성도로 결정될 것 같다. 가령 프롬프트를 길게 적어 AI에게 현재 상황과 맥락을 구구절절 이해시키는 것보다, 그냥 "~이렇게 해줘"라고 던졌을 때 토큰도 덜 쓰고 원하는 결과를 더 빨리 얻게 되는 상황도 오지 않을까 생각한다. 지금까지 AI 에이전트를 사용해보면서, 에이전트를 역할별로 나누..
선착순 서비스에서의 조회현재 givemeticket 선착순 서비스를 구현하고 있다. 선착순 서비스를 보통 생각해보면 예매 직전 사용자들이 엄청나게 몰리게 된다. 실제 수강신청을 했던 내 모습을 보더라도 새로고침을 반복해서 요청하는 과정에서 조회 요청을 여러번 누르고 있다. 그럼 만약 DB 조회 요청이 반복되면? 1인당 3번 x 100명 x 10개의 행사 일때 순간적인 DB 조회 요청이 3000번 요청된다. 주 기능인 선착순 신청이 시작하기도 전에 이미 DB 커넥션이 엄청나게 소요 되는 것이다. 현재 보이는 것으로는 HikariCP 커넥션에서 대기중인 커넥션으로 인해서 병목이 발생하고 있다.DB 인덱싱을 통해서 DB 조회 시간을 단축시켰다고 해서 커넥션의 기본적인 요청량은 줄여지지 않는다. 그럼 해결책은 ..
서론픽잇에는 현재 위치를 기준으로 주변 식당을 가져오는 기능이 있다. 방을 만들 때 한 번 호출되어, 카카오 로컬 API로 주변 식당을 검색하고 그 결과를 저장한다.이 기능은 한식, 양식, 중식, 일식, 패스트푸드, 아시안푸드, 도시락, 분식의 여덟 개 카테고리를 각각 검색한다. 카테고리별로 골고루 담겨야 픽잇의 선택지가 한쪽으로 쏠리지 않기 때문이다. 문제는 이 여덟 번의 호출이 순차로 일어나고 있었다는 점이다.List requests = new ArrayList();requests.addAll(restaurantSearchClient.getRestaurants( new RestaurantSearchRequest(RestaurantCategory.KOREAN, x, y, radius, RE..
서론이번 글에서는 실제로 부하를 걸어보며 인스턴스 한 대 기준으로 안정적으로 처리 가능한 목표 TPS를 측정하고, Tomcat Thread 수와 HikariCP Connection Pool 크기를 조정해 성능을 튜닝한 과정을 정리한다.목표는 단순했다.인스턴스 1대당 안정적으로 처리 가능한 최대 TPS를 측정한다.그 근거가 되는 서버 설정값(스레드 수, 커넥션 풀 크기 등)을 도출한다.핵심 대상 기능은 픽잇의 식당 추천 및 조회 전체 플로우로 잡았고, 측정 지표는 Peak RPS와 p50·p95·p99 응답 시간으로 정했다.어떤 부하를 걸 것인가단순 조회가 아니라 실제 시나리오로처음에는 단순히 조회 API 하나에 부하를 거는 방법도 고민했다. 하지만 그렇게 하면 실제 서비스에서 발생하는 DB 동시성 경합,..
서론이번에 새로운 요구사항을 받았다.인스턴스 한 대 기준으로 핵심 기능의 목표 TPS를 정하고, 서비스가 안정적으로 운영될 수 있도록 관련 값을 설정한 뒤 그 근거를 공유해야 한다는 것이었다.목표 TPS를 정하려면 결국 현재 우리 서버가 얼마나 버틸 수 있는지를 알아야 했고, 그러려면 부하 테스트가 필요했다. 이 글에서는 부하 테스트를 준비하기까지의 과정을 정리해본다.TPS란 무엇인가TPS(Transaction Per Second)는 말 그대로 초당 처리할 수 있는 트랜잭션 수를 뜻한다.서버의 성능 지표이자 확장성 지표로, TPS가 높을수록 더 많은 사용자의 요청을 동시에 처리할 수 있다.왜 TPS를 알아야 할까만약 TPS를 모르고 운영한다면 여러 문제가 생긴다.갑자기 트래픽이 몰렸을 때 서버가 버틸 수..
서론배포를 할 때마다 기존 애플리케이션을 종료하고 새 버전을 다시 띄우는 방식에는 명확한 문제가 있었다. 애플리케이션이 종료되고 새 버전이 뜨기까지의 시간 동안 서비스가 중단되고, 그 사이에 들어온 요청들은 실패하게 된다.픽잇은 사용자가 실시간으로 픽잇(투표)을 생성하고 참여하는 서비스이기 때문에, 배포 시점에 요청이 실패하는 것은 사용자 경험에 직접적인 영향을 준다. 배포는 앞으로도 계속 반복될 작업인데, 그때마다 짧게라도 서비스가 끊긴다면 배포 자체가 부담스러운 작업이 되어버린다.따라서 배포 중에도 사용자가 서비스 중단을 느끼지 않도록 무중단 배포를 적용하기로 결정하였다.무중단 배포 전략 선택현재 우리가 처한 상황무중단 배포 전략을 결정하기 전에 먼저 우리가 처한 인프라 환경을 정리해보았다. 전략은 ..