안녕하세요 강정호 입니다.이번 포스팅에서는 콘서트 예약시스템을 구현하면서 고민했던 내용에 대해서 정리해보려고 합니다. [동시성 이슈에 대한 Lock 처리]콘서트 예약시스템에서 동시성 이슈가 발생하는 지점은 "좌석 임시예약" 기능에서 발생합니다.1) 좌석 테이블에 Lock이 걸리지 않은 경우Lock이 걸려있지 않으면 모든 사용자가 좌석 예약이 가능하게 됩니다. 그렇게 되면 가장 마지막에 처리한 사용자의 ID로 예약이 됩니다.이는 예약시스템에서 절대 발생하면 안되는 오류이므로 동시성을 제어할 수 있는 Lock은 반드시 필요합니다 2) Optimistic Lock(낙관적락)을 이용한 동시성 제어낙관적 락은 아래 조건에서 사용하기가 좋은데요- 여러개의 요청 중 1건만 성공시켜야 하는 경우- 충돌 빈도가 낮은 경..
오늘은 콘서트 예약시스템의 부하테스트를 위한 테스트 시나리오에 대해서 설계해봅니다. 장애대응, 부하테스트가 중요한 이유?실제 운영환경에서 대량의 트래픽이 몰려서 서버가 다운되거나, DB Connection 부족으로 장애가 발생할 수 있습니다. 장애가 없는 완벽한 프로그램은 없기에 사전에 부하테스트를 통해서 개선점을 파악할 수 있습니다. 그리고 미리 장애대응 훈련을 하면서 실제로 장애가 발생했을 때 빠르게 조치할 수 있습니다. 부하테스트에서 반드시 확인할 것1. 예상 TPS(Transaction Per Second)2. 평균/중간/최대 응답시간(P50, P99, P999)3. 다량의 트래픽 유입시 동시성 이슈 확인위 3가지에 대해서 성능을 비교하고, 성능이 목표치에 도달하지 못하는 경우 원인을 분석하고 성..
[9주차 과제]내가 개발한 기능의 트랜잭션 범위에 대해 이해하고, 서비스의 규모가 확장된다면 서비스들을 어떻게 분리하고 그 분리에 따른 트랜잭션 처리의 한계와 해결방안에 대한 서비스설계 문서 작성실시간 주문, 좌석예약 정보를 데이터 플랫폼에 전달하는 요구사항을 기존 로직으로 구현했을때 발생하는 문제와 해결방안에 대한 문서 작성 [트랜잭션 분리의 중요성]서버 어플리케이션에서 트랜잭션의 범위를 어떻게 잡는지에 따라서 성능에 영향을 줄 수 있다.문제상황 1번 : 1개의 트랜잭션에 너무 많은 작업이 있거나, 조회가 Slow Read 쿼리가 포함되어 있는 경우트랜잭션 내에서 테이블의 데이터에 Lock을 잡은 상황이라면 다른 사용자는 트랜잭션이 모두 끝날 때까지 대기해야 하는 문제Slow Read 하는 쿼리가 있는..
안녕하세요 강정호입니다. 이번 포스팅은 제가 콘서트 예약시스템에서 구현한 대기열에 대한 설계에 대해서 작성해보겠습니다. [대기열이란?]대기열은 서버에 대용량 트래픽이 몰릴 때를 대비해서 서버의 부하를 일정 수준으로 유지하기 위해 만듭니다.1000명이 동시에 좌석 예약을 하기 위해 요청을 보냈을 때, 선착순 50명만 예약이 가능하도록 하고 나머지 사용자는 대기열에 들어가게 됩니다. 이렇게 되면 서버의 부하를 줄여서 트래픽을 제어할 수 있다는 장점이 있습니다. 대기열에 있는 사용자의 요청은 일정 시간이 지나면 예약이 가능한 상태로 변경되어 고객들은 콘서트 예매를 할 수 있습니다. 이렇게 하여 단시간에 서버에 발생하는 부하를 줄여서 안정적으로 서버를 유지할 수 있습니다. [대기열 구현 방법]제가 생각한 대기열..
오늘은 트러블 슈팅에 대해서 포스팅 하려고 합니다. [문제 상황]비관적 락을 사용해서 좌석 예약시 동시성 제어를 할 수 있도록 프로그램을 개발했습니다.그러나 5개명의 사용자가 1개의 좌석 예약을 했을 때, 5명 모두 좌석 예약에 성공하는 현상이 발생했습니다. 이론상 1개의 좌석이 먼저 선점되어 예약이 되면 나머지 4명은 좌석 예약 불가해야 합니다. [문제가 발생한 코드] /** 좌석 예약 */ @Transactional public ReservationResponse reserve(ReservationRequest request) { // 1. 사용자를 조회한다. User user = userManager.findUserById(request.getUserId()); if(user ..
콘서트 예약시스템에서 사용하는 쿼리 중에서 인덱스로 성능을 개선할 수 있는 부분에 대해서 알아보자. [콘서트 예약시스템에서 성능개선의 여지가 있는 쿼리] 특정일자에 대한 예약 가능한 좌석리스트 조회@Query("SELECT s FROM Seat s WHERE s.seatNo = ?1 AND s.concert.concertId = ?2 AND s.concertSchedule.concertDate = ?3") public Seat findSeatBySeatNoAndConcert(Long seatNo, Long concertId, LocalDate concertDate); 위 쿼리를 보면 Seat 번호를 조회하기 위해서 Concert, ConcertSchedule 테이블과 조인을 한다.만약에 좌석갯수가 3만..
대용량 트래픽 처리 서버를 구축할 때 동시성을 제어하는 것은 매우 중요하다.왜냐하면 대량의 트래픽이 몰릴 때 데이터의 정합성을 유지하는 것이 필수적인 요소이기 때문이다. 내가 직접 개발하면서 경험한 동시성 제어 프로그래밍에 대해서 작성해본다. [동시성 제어 프로그래밍 방식]동시성 제어 프로그래밍은 트랜잭션, 트래픽, 분산 환경 여부 등에 따라 다르게 채택하여 사용할 수 있다.콘서트 예약시스템에서 동시성 이슈가 발생하는 지점은 아래 2가지이다.1) 좌석 예약2) 포인트 충전, 사용 좌석 예약 기능 동시성 제어 프로그래밍1. synchornized - 부적합Java에서 제공하는 가장 기본적인 동시성 제어 프로그래밍 방법이다.좌석 예약 메서드에 synchronized를 걸면 싱글 스레드 방식으로 좌석 예약을 ..
1. 문제와 해결방법 **(과제, 프로젝트를 진행하면서 부딪혔던 기술적인 문제)** 1) 이번주에 겪은 문제는 환경변수에 따라서 다르게 CD 하는게 이해가 안되었다.application.yml을 환경별로 어떻게 다르게 하여 CI/CD 하는지 이해가 안됨.=> 해결방안 : secret에 환경별로 application.yml을 저장하고, github-action 코드에서 빌드시마다 src/main/resources 폴더에 생성하여 프로젝트를 빌드하는 방식으로 진행 예정. 2) github secret 사용법을 이해하지 못했다어디에 application.yml을 넣는지 등등=> 해결방안 : github secret에서 application.yml을 base24 인코딩 하여 사용하는 방식으로 해결 예정https..
[낙관적 락 vs 비관적 락] 동시 요청 중 한개만 성공해야 하는 경우에는 낙관적 락을 사용한다.상황에 따라 다른데, 재고 수량 차감하는 상황에서 2개의 요청이 들어왔을 떄 하나를 실패시키는게 맞나?아니다 두 요청을 모두 처리하는게 맞기 때문에 이건 낙관적 락보다는 비관적 락.반면에 좌석 예약은 한개의 요청은 떨어트려야하기 때문에 낙관적 락이 유용. 낙관적 락 => 1개의 요청만 성공시키고, 나머지는 다 실패시켜도 괜찮아. 이러면 낙관적 락을 사용한다.(예 : 좌석 예약)비관적 락 => 동시 요청시에 순차적으로 처리해야 하는 경우(예 : 재고 차감) 분산락 : 분산시스템에서 일관된
지난 5주간 무엇을 했나? 5주간 쉼 없이 달려왔다. 내가 맨 처음에 개발자로 공부할 때의 느낌처럼 지난 5주간 많은 양의 지식을 머리에 밀어 넣었다. 그리고 몰입해서 코딩을 하고 피드백을 받고 다시 수정하는 과정을 진행했다. 1주차에는 TDD 방식으로 포인트 충전, 사용을 할 수 있는 간단한 API를 구현했다. API 자체는 간단했지만 ConcurrentHashMap을 이용해서 동시성을 제어하는 부분이 있었다. 1주차를 통해서 TDD 방식을 익히고, 테스트코드 작성하는 방법에 대해서 연습이 많이 되었다. 그래서 이것을 기반으로 이후 과제부터 테스트코드 작성이 한결 수월해졌다. 2주차에는 클린아키텍쳐 + 레이어드 아키텍쳐를 공부하고 과제로 특강신청 API를 개발했다. 3주차 ~ 5주차는 본격적으로 서버구..
[테스트 코드는 왕이다] 내가 개발한게 잘 동작하는지 확인하기 위해서는 e2e, 통합테스트를 해야한다. 현재 한상진 코치님 사내에서 거대한 리팩토링을 진행중. 테스트코드가 완벽하게 구현되어 있고, 심지어 if문마다 테스트코드가 있다. 그래서 리팩토링하는 개발자가 리팩토링하면서 기능의 정확성이 보장되는지 판단할 수 있다. 테스트코드를 잘 작성하고, 꼼꼼하게 작성하는것은 매우 필요하다. 테스트코드 작성하는게 시간이 오래 걸린다? => 장기적으로 테스트코드를 작성하는게 시간을 절약해준다. 그렇지 않다면 PostMan으로 매번 수동으로 해야한다. [소프트웨어 아키텍쳐의 핵심은 책임과 의존이다] 책임 : 해당 프로그램의 기능 [서버구축 마무리 하면서] 맛집검색 서비스에 대한 리뷰 - API 1개에만 의존하다보면 ..
3주간의 콘서트 예약시스템 프로젝트가 눈 깜짝할 사이에 지나가버렸다. 퇴근하고 와서 코딩하고, 같은 조원들과 리뷰하고, 주말에 수업 듣고 복습하고 했던 과정들이 쉽지는 않았지만 개발에 몰입할 수 있는 기회여서 즐거웠다. 매번 멘토링 때 열정적으로 도움을 많이 주신 허재 코치님께 감사의 인사를 전합니다. 1. 프로젝트 소개 내가 개발한 프로젝트는 콘서트 예약시스템이다. 많은 사람들이 동시에 접속하여 콘서트 티켓 예매를 가정한 시스템을 개발하는 것이다. 콘서트 일정 조회, 토큰 발급, 좌석 예약, 결제 처리에 이르는 모든 기능을 종합적으로 구현해야 하는 프로젝트이다. 대용량 트래픽을 견뎌야 하는 시스템이기 때문에 동시성 제어 등 고민이 필요한 기능들이 있었다. 대용량 트래픽을 견디고, 동시성을 제어하는 시스..
1. 문제 (과제, 프로젝트를 진행하면서 부딪혔던 기술적인 문제) 1) 예약가능한 콘서트의 일자를 모두 조회하는 기능 위와 같이 Concert 테이블을 만들었다. Concert - Seat 테이블이 1:N 관계를 가지고 있는 ERD 설계를 했는데, 여기에 한계점이 있다. 각각의 concertDate마다 고유의 concertId가 있다. 그래서 concertId 1개로 여러개의 예약 가능한 콘서트 일자를 조회해 오는 것이 불가능. 중간에 ConcertOption 같은 테이블을 둬서 일자를 여러개를 동시에 조회해 올 수 있도록 Entity를 수정해야 함. 2) Jpa Repository로 조회시 Null과의 사투 JpaRepository로 객체를 조회해왔을 때 Null값이 많았다. 예를 들면 User use..
[문서를 작성하는 방법] 우리가 주니어 때 많은 글을 쓰지만 그것을 다시 보는 사람은 많지 않다. 다시 보는 글이 되려면 글이 컴팩트 해야 하고, 제목도 목적에 맞게 쓴다. 글을 툴처럼 만들어야 한다. [Loggin & Exception] 로그의 중요성 적절한 지점에 로그를 설정해놔야 운영상황에서 발생하는 에러나, 발생한 문제에 대해서 훌륭한 단서를 제공한다. 그럼 로그는 어느 지점에 달아야 하는가? 1. Request/Response를 받는 지점 입력값, 출력값이 최초에 어떤 값이 들어왔는지 알아야 하기 때문이다. Request 객체를 로깅하려면 Controller 부근에서 로깅처리 해야 입력값을 볼 수 있다. 그리고 Response의 경우도 Controller단에서 로깅처리를 해야 어떤 값으로 나갔는..
[1주차에 대한 회고] 테스트코드 짜는게 어렵다!! 1주차는 테스트 코드 짜는게 익숙하지 않아서 어려웠어요. 어떨 때 @SpringBootTest를 사용하고 어떨 때 @Mock을 사용하는지 몰랐습니다. 단위테스트와 통합테스트의 개념도 명확하지 않은 상태에서 테스트 코드를 작성했습니다. 테스트코드 작성방법에 대해서 찾아보고 해서 결국 테스트를 완성했습니다. 동시성 제어라는 것을 고민해보고 코드로 구현해볼 수 있는 기회가 있어서 유익하고 재미있었습니다. [2주차에 대한 회고] 사실 아키텍쳐에 대해서 생각을 안하고 늘 하던대로 패키지구조를 controller, service, repository를 만들어서 사용했어요. 그런데 아키텍쳐 구조에 따라서 각 프로그램 모듈의 성격이 달라지고, naming 방법도 달라..
[하헌우 코치님 과제 Summary] [E-커머스 과제] 1. 주문 결제할 때 Order Table, Order Item Table이 사실상 필수도. 2. ERD, 시퀀스 다이어그램 => 노션 머메이드 툴로 사용한다 3. 시스템 아키텍쳐 => 이레이져로 하면 멋있게 나온다. 4. PG연동 문서작성능력 > 코딩능력 [콘서트 예약 과제] 대기열은 어떤 부하를 낮추기 위해서 작업하나...? = DB 부하!(서버 부하X) 2. 좌석에 접근할 수 없도록 하는 경우 락을 사용하는데 실제 현업에서는 안정성을 위해서 비관적락을 사용하는 편이다. 낙관적락은 오류의 가능성이 존재. 3. 도메인은 무조건 테스트를 빡빡하게 할 수 있어야 한다. DDD는 추세다. 4. 다수의 인스턴스로 어플리케이션이 동작하더라도 기능에 문제가..
3주차에는
[질문] 1. 콘서트 예약시스템에서 대기열 시스템 구현시 RDBMS인지, REDIS 같은 것인지 구현하는 방식을 어떻게 의도하고 문제를 내신건지 궁금합니다 트래픽이 엄청 많지 않으면 DB 레벨에서 대기열을 구현이 가능하다. 그리고 DB에서 대기열을 구현하니 이게 한계가 있네, 그래서 REDIS를 사용하는구나에 대해서 꺠닫는데 의도. [질문2] [질문3] 폴링으로 대기열을 확인한다는 것은 배치작업 같은게 떠 있어야 하는걸까요? [질문4] 만약에 몇천명이 폴링으로 현재 대기자수를 DB로 갔다와서 알 수 있다면 부하가 심할 것 같은데요. 그러면 그 중간에 뭔가를 둬서 부하를 줄일 수 있어야할까요? private 메서드를 선언하는 케이스 - 허재코치님 : private 메서드는 잡다한 것을 프라이빗으로 선언. ..
안녕하세요 강정호입니다. 2주차 클린아키텍쳐를 끝내고 회고를 작성해봅니다. [잘하고 있는 점] 1. 어떻게 하면 효율적인 아키텍쳐로 설계를 가져갈까? 라는 고민을 하기 시작 2주차에는 허재 코치님이 레이어드 아키텍쳐, 클린 아키텍쳐에 대해서 설명해주셨어요. 2주차 특강신청 프로젝트에 해당 내용을 적용해서 아키텍쳐를 어떻게 짜면 가장 효율적일까? 라는 생각을 많이 하면서 과제를 진행했어요. 과거에는 아키텍쳐에 대한 생각없이 그냥 짰는데, 이제는 효율적인 방법의 아키텍쳐에 대해서 고민하며서 작성하게되었어요. 2. 다른 사람의 코드를 보고 내 것으로 차용하는 것 다른 사람들이 작성한 코드들을 보고 해석하여 내것으로 만드는 과정을 진행했습니다. 다른 조원, 6조 팀원들의 코드를 보고 의도를 생각하고 괜찮은 부분..
[허재 코치님이 깨달은 것] - "나는 지금까지 뭘 하고 있었던거지??" 라는 생각을 했다고 함. - 조금 더 체계적으로 개발을 하도록 미리 알았으면 좋지 않을까라는 생각을 했다고 함. - 체득을 하고 나서 개발하는 속도나 역량은 기하급수적으로 늘어났다. - 핵심 : 아키텍쳐, TDD 방식 등 체계적으로 개발하는 방법을 알면 더 코딩 실력을 높일 수 있다. [우리가 말하는 도메인이란 무슨 뜻이지????] 1. 도메인 : 특정 기능과 관련된 속성, 기능들을 "응집화" 시켜 놓은 개념. 예시1 : 도메인 이해도가 높아야 한다 ==> 해당 기능을 구성하는 응집화된 비즈니스 로직들에 대한 이해가 깊어야 한다. 예시2 : 도메인 모델 ==> 일반적으로 기능을 군집화 시킨 도메인의 객체, 엔티티 등을 의미 예시3 ..
- Total
- Today
- Yesterday
- 인셉션
- 재테크공부
- Use case
- github
- 유즈케이스
- 열반스쿨기초반
- 깃허브
- push_back
- 항해플러스백엔드
- Spring boot
- pop_back
- 파라메터
- resize
- 항해솔직후기
- 관계대수
- docker
- ```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
- 개발자 회고
- 폭포수
- 깃
- Inception
- 월부닷컴
- 2023년
- 내년은 빡세게!!
- 도커
- 부동산공부
- GIT
- 항해플러스후기
- front
- 월급쟁이부자들
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |