본문 바로가기

분류 전체보기

(35)
대용량 알림 개선기 (3) - RabbitMQ Consumer 서버 분리 0. 개요해당 글은 에 이어지는 글입니다 이전 글에서는 Spring Application Server 내에서 RabbitMQ를 도입하며 BlockingQueue + 동기 전송 + RateLimiter 조합을 통해 내부 흐름 제어 및 확장을 시도해보았습니다. 하지만 다시 생각해보니, 메시지 큐의 도입 목적 자체가 알림 발송의 완급 조절을 위함이었는데요. 즉, 알림 전송 대상들을 바로 FCM으로 전송하는 것이 아니라, 먼저 큐에 적재함으로써 전송 부담을 줄이고, 실제 발송은 별도로 분리된 RabbitMQ Consumer 서버에서 처리하는 구조로 설계하는 것이 맞다고 생각해 발행(Producer) 애플리케이션과 소비(Consumer) 애플리케이션을 분리한 스케일 아웃 구조로 개선해보았습니다 ! ..
대용량 알림 개선기 (2) - RabbitMQ + BlockingQueue 기반 메시지 처리 구조 개선기 0. 개요해당 글은 에 이어지는 글입니다 이전 개선기에서는 자체의 sendAsync > + 내 비동기 환경 @Async("alarmExecutor") > + 구조를 가져가면서 CPU 사용량을 안정화시키고 알람 처리 속도를 5분대로 낮춰보았었습니다. 하지만 요청이 한 번에 몰리면 FCM 전송 병목이 발생할 수 있다는 문제점이 있어 RabbitMQ로 메시지를 큐잉하고,Consumer를 병렬로 띄워서 비동기 전송 처리를 통해 시스템 부하를 분산시키고 안정성을 높여보겠습니다. 1. Kafka vs RabbitMQ, 왜 RabbitMQ를 선택했는지 Kafka는 Append-Only Log 기반 스트리밍 플랫폼으로, 대규모 이벤트 로그 수집, 분석 파이프라인 구축 등에 적합하게 설계되었습니다. -..
Nginx 등장 배경 (feat. Apache Http Server) 1. 개요무중단 배포를 진행했을때 클라이언트 -> (HTTPS) ALB -> (HTTP) NGINX -> 백엔드 서버이런 흐름으로 Nginx를 사용했었다.  웹 서버의 종류에는 여러가지가 있고 Apache Server도 널리 사용되는 것으로 알고 있는데과연 이 두개의 차이는 무엇이고 Nginx의 등장 배경은 무엇인지,나는 정말 Nginx를 제대로 알고 사용하는 것인지 의문이 들어 알아보았다 ! 2. 본문🏃‍➡️ 2-1. Nginx의 이해   Nginx는 웹서버, 리버스 프록시, 로드 밸런서, 그리고 HTTP 캐시 기능을 갖춘 소프트웨어이다. Nginx는 요청에 응답하기 위해 Event 기반 구조를 채택하여, 현재 웹 서버분야에서 1등을 차지하고 있다.Nginx는 성능이 좋고 가벼운 특징으로 인해 선택되..
Spring Batch로 역정규화 해보기 0. 개요  현재 프로젝트의 ERD부터 살펴보면 Item table을 중심으로 연관된 테이블들이 무수히 많다.   Item 별로 검색과 필터링에 필요하기 때문에 아래 코드와 같이 @Overridepublic Page searchItem(ItemSearchCondition searchCondition, Member member, Pageable pageable) { BooleanExpression isLiked = member != null ? new CaseBuilder().when(itemLike.member.eq(member)).then(true).otherwise(false) : Expressions.asBoolean(false); BooleanBuilder booleanBuilder =..
JDBC Bulk insert 처리속도 확인해보기 0. 개요 현재 프로젝트에서는 마케팅팀이 넘겨주신 csv 파일을 파싱해서 DB 에 저장하는 로직을 가지고 있었다.  @Transactional(rollbackOn = RuntimeException.class)public void read() throws RuntimeException { try (InputStream inputStream = new ClassPathResource("data.csv").getInputStream(); CSVReader csvReader = new CSVReader(new InputStreamReader(inputStream))) { List dataList = csvReader.readAll().stream() ..
대용량 알림 개선기 (1) - 비동기 환경 내 Custom Thread Pool 설정 실험기 0. 개요 프로젝트를 진행하면서 소수의 test user 는 크게 문제 없었지만 이벤트 프로모션 알람을 신청한 사람이 100000명까지 늘어나면 이벤트 오픈 시간과 최대한 가깝게 모든 알람을 사용자들이 받아볼 수 있을지 의문이였다. 참고로 나는 알림을 받을 target token 생성을 위해 FCM 프론트 서버를 간단히 구현해두었다. 로그로 target token 을 확인해볼 수 있다. https://github.com/lielocks/FCM-react 1. 모니터링 도구로 cloud watch 도입 memory 사용량 + cpu 사용량 실시간으로 분석하려고 했기 때문이다. 혹시 cloud watch config script 를 잘 짰는데 위 사진처럼 404 error 가 난다면 https:/..
C1 C2 Compiler (JIT Compiler) Full thread dump OpenJDK 64-Bit Server VM (17.0.13+11-Ubuntu-2ubuntu124.04 mixed mode, sharing):Threads class SMR info:_java_thread_list=0x00007533d8000c40, length=34, elements={0x000075344c050ec0, 0x000075344c0522f0, 0x000075344c05b7e0, 0x000075344c05cb80,0x000075344c05df80, 0x000075344c05f920, 0x000075344c060e40, 0x000075344c0622a0,0x000075344c09e230, 0x000075344c0a1150, 0x000075344ce7f7a0, 0x..
Caffeine cache 적용 후 Ngrinder 로 성능 개선 측정해보기 0. 개요현재 프로젝트는 쇼핑몰과 비슷한 도메인 특성상 가장 인기 있는 상품들이 홈화면 첫 번째 페이지에 계속 로드되며 이 데이터의 인기 순위 변동이 크지 않고, 가장 많은 JOIN 문으로 엮여있는 복잡한 쿼리이자 자주 호출되는 API 였기 때문에 매번 사용자가 조회할 때마다 데이터를 전달하는 것보다 고정된 데이터를 주기적으로 업데이트하고 이를 캐시로 제공하면 좋겠다고 생각했다.  Local Cache- 서버마다 캐시를 따로 저장- 다른 서버의 캐시를 참조하기 어려움- 속도 빠름- 로컬 서버 장비의 Resource를 이용한다. (Memory, Disk)Global Cache- 여러 서버에서 캐시 서버 접근 및 참조 가능- 별도의 캐시 서버 이용 → 서버 간 데이터 공유가 쉬움- 네트워크 트래픽을 사용해야..