항해 실전 프로젝트 Day 16 - 멘토링 2회차 노트

박서윤·2023년 12월 16일

지난 주 잘 안 된 것 현황 공유
잘 안 된 것

AWS IAM user로 팀원 모두가 AWS 관리를 하려고 했는데 IAM user에 EC2FullAccess가 있음에도 EC2 Instance Connect할 떄 Access Denied가 발생

왜 안 되는지?

ec2 console을 열 떄, public key를 전달하지 않아서 권한 문제가 발생한 것

그래서 지금은 어떻게 되었는지 or 어떻게 해결했는지?

IAM 정책에 ec2-instance-connect:SendSSHPublicKey 와 ec2:DescribeInstances 를 추가해서 해결

잘 안 된 것

ALB를 통해서 https 적용 실패

왜 안 되는지?

Target group의 ec2가 unhealty로 떠서 안되는 것으로 생각됨

어디까지 해봤는지?

healty check api를 만들어 봤지만 실패

그래서 지금은 어떻게 되었는지 or 어떻게 해결했는지?

대용량 트래픽을 처리하는 관점에서는 L7보다는 L4 로드밸런서가 적합해서 ALB를 사용하지 않고, HAProxy를 통한 로드밸런싱 및 https 적용하는 방식을 고려중

→ EC2/RDS/ALB는 현업에서 가장 많이 쓰이는 구성품이다. NLB(L4 로드밸런서)가 적합하다는 명확한 근거(ex. ALB 이후에 NLB에서 별도의 망을 사용)가 있어야 사용하는데 실제 그런 케이스는 별로 없다.

이번 주 한 일
팀 전체

공통

BE : MVP 코드 리뷰 및 Refactoring(ex. 서비스별 중복된 S3 메서드를 별도의 Handler로 구현),
의도하지 않은 결과를 보인 API 코드 수정(카트 상품 추가시 중복 상품이 별도의 entity로 등록),
ResponseDto 단순화(Paging 처리 중 상품과 이미지들을 별도 Dto로 전송 → 단일 Dto로 병합)

팀원 개인별로 작성해 주세요.

홍준영 : 프론트 일부 구현, (로컬) 프로메테우스 그라파나 적용 및 API 모니터링 Tool 조사 중, 테스트 코드 학습 및 테스트 작성 중

박서윤 : 백오피스 로그인 구현, Redis 스터디, 부하테스트 시나리오 작성, 1차 부하테스트 진행, CI/CD툴 Jenkins 스터디 및 기술 의사 결정 고민

이상휴 : 프론트 일부 구현, 이벤트 알림을 위한 Pub/Sub(Kafka/RabbitMQ/Redis) 및 클라이언트 알림(SSE/WebSocket/STOMP) 개요 스터디 및 기술 의사 결정 고민

의사결정 과정 나열

DTO의 클래스 타입 결정(Class vs Record)

선택지

클래스(Class) : 전통적인 Java 클래스를 사용하여 DTO를 구현.

레코드(Record) : Java 16부터 도입된 기능으로, 데이터를 보유하기 위한 간결한 방법을 제공, 불변의 특성을 가짐.

의사결정

간결성 : 레코드는 필드에 대한 getter, setter, equals, hashCode, toString을 자동으로 제공해서 코드의 간결함을 높임

불변성 : DTO의 경우 객체의 불변성이 요구되는 클래스로서 Record 타입이 적합하다고 판단

이벤트 알림 기술 선정 (Kafka + SSE)

서비스의 목적 : 고객에게 할인이벤트를 알려서 사이트 접속과 상품 구매를 유도하고자 함

이벤트는 한정수량 선착순 이벤트로 소비심리를 자극

서비스의 내용(구현할 기능)

고객이 접속한 상황이면 실시간으로 바로 알림을 준다

서버 → 클라이언트 단방향이므로 SSE 적용이 우선됨

비교: WebSocket, STOMP는 양방향이며 불필요한 자원 소모 발생

고객이 접속했을 때 확인 가능한 메시지를 별도 저장한다(또는 이메일 발송)

이벤트 메시지의 저장이 필요함

비교: Redis는 메시지 발행 후 수신자 확인 여부와 무관하게 삭제함

→ Kafka도 Retention 관리를 하지 않으면 메시지 유실 가능성 있음

이벤트 발생 시 이벤트 관련 처리(유저 알림 발송, 이메일 발송 등)를 위한 다수의 Subscriber(?)가 존재한다

Pub/Sub 모델이 필요함

비교: RabbitMQ는 단일 수신자를 대상으로 하는 MQ 시스템

이벤트 중 상품의 실시간 재고량을 표현하여 소비심리를 자극한다

단시간에 변화하는 재고 감소량의 정합성 보장 필요함

이 부분은 향후 동시성 제어 기술을 적용하여 해결 필요

모니터링 툴(prometheus + grafana)

어떤 선택지가 있었는지?

Prometheus, Pinpoint, Scouter

exporter로 모니터링 대상 시스템으로부터 pull 방식으로 메트릭을 받아오는 방식으로 동작하여 하나의 서비스만 모니터링하는 것이 아니라 연결된 다른 서비스들에 대한 모니터링도 할 수 있다.

쿼리 기능을 제공해서 메트릭에대한 손쉬운 계산 및 집계 가능

grafana - Prometheus와 연결이 간편하고 cpu, 메모리 등의 메트릭 지표를 시각화하는데 특화

→ prometheus는 APM은 아니고 로깅과 모니터링을 할 수 있다. APM은 병목구간을 찾아내는 툴이며 pinpoint, scouter등이 있다.

CI/CD 툴(Github Actions vs Jenkins)

선택지

Github Actions, Jenkins

선택 과정

Github Action의 경우 CI/CD 설정이 간단하며 Github과 높은 호환성을 제공.

작은 규모의 프로젝트 또는 간단한 워크플로우에 적합

JenKins의 경우 CI/CD 설정이 복잡하고 러닝커브가 Github Action에 비해 큼.

다양한 플러그인이 있어 유연성과 확장성이 높음.

복잡한 파이프라인 구축에 적합

Github Action보다 빠른 빌드 처리속도

→ 리소스 여유가 있으면 Jenkins가 좋다(서버 프로비저닝을 함), 둘 다 해보는 것이 좋다

질문
할인이벤트의 경우 만약 재고가 한정되어 있지 않다면, 동시접속자의 처리를 위해서는 비동기 방식이 유리할 것으로 생각되는데 MVC로 구축된 애플리케이션에서 일시적으로 비동기 방식을 적용할 수 있나요?

멀티 쓰레드로 주문 요청은 비동기로 받을 수 있지만 DB에 주문을 입력하고 그 결과 감소된 재고를 읽어 들이는 것을 비동기로 처리하는 것이 가능한지…

아니면 별도의 서버를 WebFlux로 구축하여 일시적인 대량 트래픽을 처리하는 방식을 적용할 수 있나요? 그리고 이 경우에 데이터의 정합성을 100% 유지하는 것이 가능한가요?

만약 비동기로 발생된 주문 입력을 별도의 큐에서 순차적으로 DB에 입력하는 것이 가능한지…

위에서 재고가 한정되어 있다면 비동기 방식을 적용할 수 있나요?

→ WebMVC도 비동기 처리가 가능하다, AtomicLong 자료형을 쓰는 등의 적용을 하면 된다.
데이터 정합성이 핵심인 구간(ex. 재고 관리)는 동기 처리가 필요하다.
그 외의 후속 프로세스들은 비동기처리가 유리하다.
WebFlux도 잘못 구현하면 동기처리가 된다.

0개의 댓글