분류 전체보기 195

[Ticketing] nGrinder를 통한 부하 테스트

완성된 백엔드 배포 환경에 대해서 서버가 얼마나 버텨줄 수 있을지 테스트 해보기로했습니다.DB Connection을 한 번 가지는 테스트로 진행했습니다. 1. API Gateway로 요청ECS 클러스터 내 컨테이너를 1개 띄웠을 경우와 2개 띄웠을 경우를 테스트하며 결과를 비교해봤습니다.가상 유저 수는 10, 50, 100, 200, 400, 800, 2000 순으로 차례대로 늘려가며 테스트 했습니다.                               1대의 컨테이너                                  2대의 컨테이너VusersTPSMTTErr RateTPSMTTErr Rate1083.4119.50.0%89.1111.30.0%50324.1153.40.0%343.6144.70.0..

[Ticketing] 인프라 아키텍처 설계 및 구축

프로젝트의 전체 그림을 설계하고 AWS를 활용해 배포한 내용을 서술합니다. 전체 그림을 살펴보고 세부적인 내용을 살펴보겠습니다. 가장 큰 특징은 개발자의 인프라 관리 포인트를 최소화한 *서버리스 아키텍처*라고 말씀드릴 수 있습니다. 1. Frontend - Web Hosting웹 서버를 호스팅하는 다양한 방식이 있지만, 인스턴스를 직접 사용하지 않고 AWS CloudFront + S3 Web Hosting을 사용한 이유는 다음과 같습니다.관리 포인트 최소화 : 표면적으로 S3는 객체 스토리지 입니다. 정적 파일(.html)을 업로드하고 해당 버킷을 Web Hosting으로 동작시키면 개발자가 직접 nginx와 같은 웹 서버를 관리할 필요가 없습니다. 높은 가용성 : 트래픽이 순간적으로 급증하는 상황에서 ..

[Ticketing] Lock을 활용한 동시성 제어

현재 프로젝트에는 동시성을 제어해야할 비지니스 상황이 있습니다.선착순 쿠폰 발급공연(좌석) 예약 각 상황을 어떻게 대처했는지 단계별로 알아보겠습니다. 1. 선착순 쿠폰 발급가정한 상황은 정해진 수량의 쿠폰에 대해서 순간적으로 동시 발급 요청이 몰리는 상황입니다.이 때 별도의 동시성 제어가 없다면 다음과 같은 순서에 의해, 최초 수량보다 더 많은 사용자가 쿠폰을 발급받게 됩니다.최초 수량 100개 가정유저 A가 쿠폰 발급 요청, 수량 read (100개)유저 B가 곧이어 쿠폰 발급 요청, 수량 read (100개)유저 A가 쿠폰을 저장을 요청, read 시점에서 수량을 하나 빼고 저장 (99개)유저 B가 쿠폰을 저장을 요청, read 시점에서 수량을 하나 빼고 저장 (99개)유저 A와 B 모두 쿠폰을 발급..

[Ticketing] Slack으로 에러 메세지 전송하기 (Feat: Spring AOP)

현재 프로젝트를 운영하는 상황이라고 가정했을 때 떠오르는 문제 중 한 가지가 *에러 상황 대응*이었습니다.백엔드 서비스의 경우 AWS ECS 클러스터 내에서 운영중이라 웹 콘솔을 통해 각 서버의 매트릭을 확인할 수 있고 시스템 로그를 확인할 수 있지만, 에러 발생 여부를 즉각적으로 확인할 순 없었습니다. 특정 알림 형식으로 에러 상황을 받아볼 수 있다면 참 좋겠는데..이메일과 Slack중 고민하다가 Slack이 개인적으로 접근성이 좋아보여 선택하게되었습니다. 1. logback-slack-appenderlogback-slack-appender는 logback을 활용해 Slack으로 로그를 전달하는 오픈소스 라이브러리입니다.의존성을 추가하고 다음과 같이 logback.xml파일을 작성하면 설정한 로그 레벨..

[Ticketing] Git Actions와 AWS CodePipeline을 활용한 자동화된 배포 파이프라인 구축

본 프로젝트에서 빌드 및 배포해야하는 코드는 크게 Frontend(Vue3), Backend(Spring)로 구성됩니다.Frontend의 경우 Web Hosting 기반의 S3 버킷 위에서 동작하며, Backend는 AWS ECS 클러스터 내부 서비스로 정의되어 동작합니다.  먼저 완성된 파이프라인의 구조를 사진으로 한 번 보고, Frontend 및 Backend 배포 파이프라인을 어떻게 자동화 시켰는지 알아보겠습니다. 1. Git Actions를 활용한 배포 과정아래에 진행할 동일한 과정을 별도의 인스턴스에 Jenkins를 설치해 진행해봤는데 현재 자동화된 배포 단계에서 필요한 기술은 Git Actions만으로 충분히 구현할 수 있었으며, 시간적 비용 및 실제 과금 여부에서도 Git Actions가 압..

[Ticketing] AWS Lambda Authorizer를 활용한 인가 서버 개발

1. 인가 서버를 분리우선 본 프로젝트의 전체 흐름을 살펴보자.모든 요청은 단일 진입점, API Gateway에서 처리하도록 설계로그인 성공 시, WAS에서 JWT 발급클라이언트는 권한이 필요한 요청 시 Request Header에 JWT를 함께 전송이후 *토큰을 어디서 검증할까?*에 대해 고민을 많이 했는데, 간단하게 토큰 발급을 구현한 WAS에서 처리할 수 도 있지만, 관심사를 분리하는게 맞다고 생각했다.  모든 요청의 단일 진입점 역할을 맡는 API Gateway 레벨에서 인증 및 인가되지 않은 요청은 미리 차단하는게 뒷 단의 부하도 줄여주고 자연스럽다. 따라서 API Gateway 레벨에서 인증/인가를 도와주는 Lambda 권한 부여자를 활용해보기로 했다. 2. Secret Key 공유 문제최초 ..

[Ticketing] JPQL에서 QueryDSL으로 전환

현재 프로젝트에서 직접적인 쿼리가 필요한 부분은 전부 JPQL을 통해 해결했었다.대체로 크게 복잡하지 않은 쿼리이기에 대수롭지 않게 넘겼었는데, 최근에 생각에 변화가 생겼다.내가 짠 코드이기에 당장은 이해하기 쉬울 것이다. 하지만 6개월 뒤에 본다면 쉽게 이해할 수 있을까? 소스 작성자도 시간이 지나면 이해하기 어려울 수 있는데, 다른 팀원이 봤을 때 가독성이 좋다고 할 수 있을까? 게다가 동적쿼리를 활용해 조회하는 쿼리도 존재하니, 지난날의 생각이 매우 잘못되었음을 느꼈다.코드의 가독성, 그리고 동적 쿼리 문제를 해결하기 위해 QueryDSL을 도입하기로 결정했다. 비교적 간단한 쿼리로 구성된 단건 조회와 동적 쿼리를 구현해야하는 메서드를 비교해보며, QueryDSL을 도입함으로써 실제로 가독성이 좋아..

[Spring] JDK 동적 프록시와 CGLIB의 한계

이전 포스팅에서 포인트컷 지시자 중 `this`와 `target`을 다루며 한 가지 주의사항을 이야기했었다.JDK 동적 프록시는 인터페이스를 상속받은 프록시 객체를 스프링 빈으로 등록하기 때문에, *구체 클래스 타입으로 타입 캐스팅이 불가능하다는 점이다.* 당시에 "이런 유사한 이유로 스프링은 CGLIB를 기반으로 프록시 객체를 생성하도록 기본값을 설정했을까?" 의문을 가졌었는데 본 포스팅에서 자세히 이야기해보고자 한다.1. JDK 동적 프록시와 CGLIB의 차이점표면적인 차이점은 이미 이야기한 바와 같다. JDK 동적 프록시의 경우, 인터페이스를 상속받은 프록시 객체가 생성되기 때문에 *자식 타입으로는 캐스팅이 불가능하다.*반면, CGLIB의 경우 구체 클래스를 상속받은 프록시 객체가 생성되기 때문에 ..

Spring 2024.05.12

[Spring] 포인트컷 지시자 (AspectJ Pointcut Expression) - 3

포인트컷 지시자에 관한 마지막 포스팅이다.이번 포스팅에서는 커스텀 애노테이션을 생성해 포인트컷 표현식으로 활용할 수 있는 방법과 어드바이스에 다양한 매개변수를 전달해 활용하는 방법에 대해 알아볼 것이다. 1. 예제 세팅먼저 커스텀 애노테이션을 생성하자.@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface ClassAop {}@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MethodAop { String value();} `ClassAop`의 경우 클래스 레벨에 붙일 애노테이션으로, @Target의 값을 `ElementT..

Spring 2024.05.11

[Spring] 포인트컷 지시자 (AspectJ Pointcut Expression) - 2

직전 포스팅에서는 포인트컷 지시자 중 `execution`, `within`, `args`에 관한 문법에 대해 알아봤다.이들은 표현식을 사용해 대상 타입이나 메서드 이름, 파라미터 타입 등을 지정했다. 이번 포스팅은 대상 타입만을 지정하는 `this`와 `target`지시자에 대해 알아볼 것이다. 1. 차이점기본적으로 `this`와 `target` 모두 대상 타입을 지정한다는 점에서 공통점이 있다.단순히 타입 하나를 지정하면 되는데 차이점은 뭘까? `this`는 스프링 빈으로 등록되어 있는 *프록시 객체*를 대상으로 포인트컷 매칭을 시도한다.`target`은 *실제 타겟*을 대상으로 포인트컷 매칭을 시도한다.이게 무엇을 의미할까?  우선 기본적으로 스프링은 별도의 설정이 없다면 CGLIB를 기반으로 프..

Spring 2024.05.10