전체 글 361

네이버 쇼핑의 노출 전용 DB 적용 정리!

해당 포스팅은 NAVER ENGINEERING DAY(7월)의 아래 강연을 토대로 나름대로 정리한 글입니다. https://www.youtube.com/watch?v=Jpvh9oOyNVM&t=53s 조회용 DB로 분산 DB를 선택해서 개발한 내용과 겪게된 이슈에 대한 내용입니다. 분산 DB가 필요해진 이유 아래는 네이버 쇼핑에서 상품에 대한 정보들이다. 해당 페이지에 필요한 데이터를 얻기 위해 20개 이상의 테이블 데이터를 가져와야 한다고 한다. 카탈로그 기본 정보 판매처별 정보 리뷰 정보 속성 네이밍 정보 기존에는 Oracle을 사용해서 Join을 사용했는데 코로나 이후 트래픽 수가 급증하면서 Lock도 걸리고 Replication lag도 늘어나면서 장애 상황이 많이 생겼다. 그래서 분산 DB인 Po..

분산 서버 - CAP 이론 이해하기!

분산이 가능한 DB는 대표적으로 Dynamo, Memcached, Redis와 같은 것들이 있다. 먼저 분산 서버를 저장하기 위한 저장소의 목적을 명확히 할 필요가 있다. 대용량 데이터 저장 가능 짧은 Latency HA 확보 강한 일관성 … 단일 서버 ? 단일 서버에서는 사실 비교적 쉽다. 데이터를 메모리에 Map형태로 저장하기만 하면 된다. 다만, 메모리가 부족해지는 문제를 해결하기 위해 아래 기법을 적용할 수 있다. 데이터 압축(compression) 캐싱 (자주 쓰이지 않으면 디스크에 저장) 분산 서버 분산 서버를 설계할 떄는 CAP 이론을 이해해야 한다. CAP 이론(Consistency, Availability, Partition Tolerance theorem)은 아래 세 가지 요구사항을 만..

ApplicationContext란 무엇인가?!

ApplicationContext는 무엇일까..? 일반적으로 스프링 컨테이너라고 불리며 빈을 관리한다 정도로 알고 있다. 더 자세히 알아보자. ApplicationContext Central interface to provide configuration for an application. This is read-only while the application is running, but may be reloaded if the implementation supports this. An ApplicationContext provides: Bean factory methods for accessing application components. Inherited from ListableBeanFactory. ..

Server/Spring 2023.08.14

SpringBoot - 무중단 배포 정말 안전할까?! (+ Graceful Shutdown)

k8s, 리버스 프록시 방식 등을 통해 무중단 배포를 하게 된다. 기존 인스턴스를 종료했을 때 이미 수행중인 작업이 있는 지 어떻게 보장할 수 있을까..? Graceful Shutdown Shutdown Graceful은 '우아한 종료'라는 뜻으로 하던 작업을 모두 안전하게 처리한 후 프로세스를 종료하는 것을 말한다. Linux의 kill - 15 명령어로 Graceful Shutdown을 할 수 있다고 말하는데, 실제 Spring 애플리케이션을 보면 하던 작업들이 강제로 종료된다. SpringApplication에서 요청을 어떻게 처리하는 지 Linux에서는 알 수 없기 때문이다! SpringBoot SpringBoot 2.3 부터는 손쉽게 Graceful Shutdown을 할 수 있는 설정을 제공한다..

Server/Spring 2023.08.13

@RequestBody에서 Enum과 String 어떤 것을 사용할까?!

Controller에서 Type과 같이 특정 값에 대해서만 입력을 받아야 하는 경우가 있다. 이때 Enum을 사용하면 아래의 문제가 생길 수 있다. 각 Layer의 강결합 아래는 기존의 코드이다. @RestController @RequiredArgsConstructor public class AlarmController { private final AlarmUseCase alarmUseCase; @PostMapping @ResponseStatus(HttpStatus.NO_CONTENT) public void postAlarm(@RequestBody PostAlarmRequest request) { String content = request.getContent(); PostType type = reque..

Server/Spring 2023.08.13

Unit Test - 리팩토링 내성이란 무엇인가?!

최근에 진행중인 대부분 프로젝트에서 Coverage 100%를 지향하면서 단위 테스트(Unit test)도 많아졌다. 해당 포스팅에서는 단위 테스트(Unit test)를 짜면서 얻게된 지식을 일부 공유한다. 리팩토링 내성 리팩토링 내성이란 테스트를 바꾸지 않고 프로덕트 코드를 리팩토링할 수 있어야 함을 의미한다. 쉽게 설명하면 리팩토링 과정에서 거짓 양성이 발생하지 않아야 한다. 거짓 양성: 기능은 잘 동작하는데 테스트가 깨지는 경우 테스트가 구현과 결합도가 높은 경우 발생한다. 단위 테스트를 신뢰할 수 없게 만든다. 프로덕트 코드를 유연하지 못하게 만든다. 구현에 의존하는 경우 최근에 외부 모듈을 사용한 코드에서 모듈 버전을 변경하면서 테스트가 다량 실패하는 현상이 발생했다. POJO 객체만 그대로 사..

Server/JUnit, Spock 2023.08.06

JVM 옵션으로 튜닝 이해하기!

JVM 튜닝에 앞서 고려해야 할 점이 성능 중 어떤 부분을 우선할 것인가를 정해야 한다. 일반적으로 성능이란 TPS와 Latency로 나뉜다. 1. GC 알고리즘 GC 알고리즘을 예로 들면 처리량(TPS)이 목적이면 Parallel GC, 응답 시간이 목적이면 CMS GC, G1 GC가 유리하다. Parallel GC는 Full GC를 수행하면서 GC 소요 시간이 길지만 빈도가 적어서 총 STW 시간이 적다. 그래서 처리량이 높다. CMS, G1 GC의 경우 GC를 짧지만 빈번하게 수행하므로 처리량이 낮지만 응답시간이 빠르다. 추가로 CPU Core의 코어가 싱글이라면 Serial GC를 사용할 수 있고, CPU Core가 멀티 코어이고 Ram이 4GB 이상이라면 한 번에 여러개의 객체를 처리할 수 있는..

Language/Java 2023.08.01

웹소켓(WebSocket) 개념 이해하기!

WebSocket(WebSocket)은 클라이언트와 서버를 연결하고 실시간으로 통신이 가능하도록 하는 통신 프로토콜이다. WebSocket은 TCP 접속에 전이중(duplex) 통신 채널을 제공한다. 쉽게 말해, Socket Connection을 유지한 채로 실시간 양방향 통신이 가능하다. 아래 서비스에서 대표적으로 웹소켓을 많이 사용한다. SNS 실시간 채팅 화상 회의 실시간 협업 툴 온라인 게임 증권, 거래소 예시를 보면 동시간 접속자 수가 많으며, 실시간 데이터가 아주 많이 오간다는 것을 알 수 있다. vs HTTP 먼저 일반적으로 사용하는 HTTP 프로토콜과의 차이를 알아보자. 1. State HTTP는 단방향 통신이다. 클라이언트가 서버로 요청을 보내면 응답을 받는 구조로 동작하며, 어떠한 상태..

Operation/Network 2023.07.25

메일 발송 시 OOM 해결하기! (with. FilterOutputStream)

평화롭던 어느날 메일 API에서 OOM이 터졌다. 발생한 End-point는 메일 발송으로 확인했다. 메일 원문은 40MB였고 개발 서버에서 테스트를 해봤다. 동일 본문으로 메일 발송 요청 1번에 결과 메모리 사용량이 117MB 정도 급증했다. 세부적으로는 2단계 메모리가 튀는 것으로 확인된다. 1차: 724MB -> 761MB 2차: 761 MB -> 841MB 바로 의심했던 것이 발송 이벤트였다. 비동기 이벤트가 두 건 발행되고 있었다. Forward Event Archive Event Line Separator 확인 결과 1. 발송, 2. 포워드 이벤트 핸들러, 3. 아카이브 이벤트 핸들러에서 아래 로직을 수행한다. 코드를 보면 ByteArrayOutputStream에 eml 파일 내용을 저장한다...

Language/Java 2023.07.24

JavaMail API 튜닝기! (메모리 성능 개선!)

이슈 Handle dispatch failed: nested exception is java.lang.OutOfMemoryError: Java heap space 어느날 특정 end-point에서 OOM이 터졌다. 아직까지 일부 사용자에게만 운영중인 서버라서 OOM이 터지는 것은 뭔가가 잘못되었다는 것을 의미한다. 리소스를 확인한 결과 실제로 메모리가 들쑥날쑥했고, OOM으로 인해 파드가 여러번 재실행되었다. 본문 내용 해당 본문을 확인해본 결과 아래와 같았다. 원문 크기: 38MB Part (첨부파일): 총 10개 - 하나 당 3~4MB 정도 첨부파일 조회 Flow 아래는 사용자가 Java-Mail-API를 사용하는 해당 서버에서 첨부파일을 조회할 때 발생하는 동작이다. 해당 원문과 Flow를 그려보니..

Language/Java 2023.07.19