NGINX에서 499 Client Closed Request 오류 해결하기
cleanUrl: /NGINX에서-499-Client-Closed-Request-오류-해결하기
문제 상황
219.xxx.xxx.xx - - [03/Jan/2025:11:44:56 +0000] "POST /api/spring/dish HTTP/1.1" 200 647 "-" "AHC/2.1" "-" 219.xxx.xxx.xx - - [03/Jan/2025:12:08:37 +0000] "POST /api/spring/cafeteria HTTP/1.1" 499 0 "-" "AHC/2.1" "-" 219.xxx.xxx.xx - - [03/Jan/2025:12:09:08 +0000] "POST /api/spring/department-notice HTTP/1.1" 499 0 "-" "AHC/2.1
서버 환경

- GCP e2-micro Instance 사양
항목 | 사양 |
머신 타입 | e2-micro |
OS | Ubuntu 20.04.1 |
리전 | us-west1-a |
CPU | vCPU 2개 |
RAM | 1GB |
SSD | 30GB |
- Supabase DB 사양
항목 | 사양 |
플랜 | Free |
CPU | 공유 CPU |
RAM | 500MB |
스토리지 | 기본 1GB |
대역폭 제한 | 5GB |
API 요청 | 무제한 |
원인 분석
Spring
Postman 응답 결과 (Spring)
- 첫 번째 시도

- 두 번째 시도 이후

NestJS
Postman 응답 결과 (NestJS)
- 첫 번째 시도

- 두 번째 시도 이후

해결 과정
1️⃣ 데이터베이스 인덱스 문제?
EXPLAIN ANALYZE SELECT * FROM kakao-user WHERE id = 'test1234';
2️⃣ 네트워크 레이턴시 문제?
us-west1-a로 변경되었기에 충분히 의심해볼만했다.
3️⃣ 애플리케이션 내부의 처리 속도 문제?
docker stats

iostat을 이용해 보기로 했다.4️⃣ 디스크 I/O 분석
iostat -dx 1


vm.swappiness 값에 따라 스왑을 얼마나 적극적으로 사용할지 결정한다.- 0: 가급적 스왑을 사용하지 않음 (오히려 메모리가 거의 꽉 찼을 때만 사용)
- 1~100: 값이 높을수록 스왑을 더 적극적으로 사용 (기본값은 보통 60)
vm.swappiness 값이 높게 설정되어 있어서 디스크 스왑이 과도하게 발생했고, 그로 인해 디스크 I/O 병목이 일어났던 것이었다.해결 방법
디스크 스왑 최소화
- 아래 명령어로 현재 vm.swappiness 값을 확인한다.
cat /proc/sys/vm/swappiness
- 값이 60처럼 높다면, 이를 1로 조정한다. 또, 영구 적용을 위해
/etc/sysctl.conf파일에 추가
echo "vm.swappiness=1" | sudo tee -a /etc/sysctl.conf
- 적용 후 다시
sysctl -p를 실행하여 반영한다.
sudo sysctl -p
성능 개선 결과


마치며
참고 문헌

What Is a 499 Status Code?
What's an HTTP Status Code 499? Find out about the non-standard status code introduced by nginx also known as the "client closed request" here!

JVM Warm Up으로 스프링 클라우드의 첫 번째 요청 딜레이 없애기
👋랜손챗 프로젝트 깃허브 바로가기

Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Programming), FP (Functional Programming), and FRP (Functional Reactive Programming).
서비스 진입점으로의 첫 번째 요청이 지연되는 문제와 해결하기
서비스의 진입점은 사용자 요청의 시작점을 의미한다. 진입점에서 응답 속도가 느리면 사용자 경험에 부정적인 영향을 미칠 수 있다. 예를 들어, 로그인 페이지의 응답이 느리거나 페이지 로딩 시간이 길어지면, 사용자는 불편을 느끼고 서비스 이탈할 가능성이 높아진다. 진입점의 응답이 지연되는 문제올클 서비스의 진입점은 로그인 API다. 종종 운영 중인 서비스에 로그인하면 평균 3초를 기다리는 상황이 발생했다. 특히, 서버 배포하거나, 일정 시간 동안 사용자가 없었던 유휴 상태에서의 첫 번째 요청에서만 이 현상이 발생했다. 3초의 시간을 기다리는 동안 머릿 속에 여러 생각이 들었다. '서버가 꺼졌나?', 'DB에 문제가 생겼나?' 개발자인 나조차 문제가 생긴 게 아닌지 의심하게 된다. 이러한 로그인 API의 ..
Nest.js의 LifeCycle(생명 주기)는 어떻게 되지?
Nest.js 에서의 생명 주기를 알아보고, 요청이 왔을 때부터 응답을 할 때 까지의 간략한 흐름을 알아봅니다.
![[Backend] JVM warm up / if(kakao)dev2022](https://i.ytimg.com/vi/utjn-cDSiog/maxresdefault.jpg)
[Backend] JVM warm up / if(kakao)dev2022
Java 어플리케이션은 시작과정에서 성능을 보장하기 위한 warm up 과정이 필요합니다. 이 세션에서는 JVM warm up이 성능에 어떻게 도움이 되는지 그리고 이와 관련된 jit comipler의 내부 절차를 소개합니다. 또한 카카오 T 계정 서버를 배포하는 과정에서 발생한 초기 응답 지연 문제를 어떻게 해결하였는지를 함께 말씀드리려고 합니다. #성능 카카오모빌리티에서 백엔드엔지니어 역할을 맡고 있는 그렉입니다. 저는 주로 Python으로 개발하는 것을 좋아하는데요, 최근에는 Java를 활용한 백엔드 개발과 React를 활용한 프론트엔드 개발에도 관심이 많습니다. ifkakaodev2022에 대한 자세한 정보는 👉 https://if.kakao.com ifkakaodev2022에 대한 문의는 👉 if@kakaocorp.com #카카오 #이프카카오 #개발자컨퍼런스 #기술 #개발 #ifkakao2022 #ifkakaodev2022
[Spring] 애플리케이션의 초기 응답 속도 개선하기
들어가기 앞서 - 왜 Spring에서 초기 요청의 응답이 지연될까? Spring으로 개발을 하다 보면, 애플리케이션을 실행하고 초기 요청, 특히 첫 요청의 응답이 유난히 오래 걸린다는 점을 알 수 있습니다. 이러한 현상을 'Cold Start'라고 부르는데, 'Cold Start'의 주요 원인으로 추정할 수 있는 상황은 아래와 같습니다. 1. JIT 컴파일러의 작동 방식 Java는 'Write Once, Run Anywhere'를 지향하는 플랫폼 독립적인 언어입니다. 그래서, 일반적인 컴파일 언어와 동작 방식에서 약간의 차이가 있는데, Java 프로그램은 컴파일 시점에 바이트 코드로 변환되었다가, 실행 시점에 기계어로 변환되어 실행됩니다. 이러한 방식은 프로그램의 이식성을 높이는 대신, 바이트 코드를 실..

스프링 애플리케이션 배포 직후 발생하는 Latency의 원인과 이를 해결하기 위한 JVM Warm-up
최근 같은 팀원 중 한분께서 JVM Warm-up 이슈로 인해 발생한 성능 저하 이슈와 그 해결방법에 대해 공유해주셨다. JVM Warm-up 키워드에 대해서는 언젠가 한번 공부해 보아야겠다고 생각했지만, 계속 미뤄두고 있었다. 이 기회에 JVM Warm-up에 대해 공부해보려한다.
[Spring] Bean Lazy Initialization 사용법
이번 포스팅에선 Spring의 Lazy initialization에 대해 알아보겠다. 먼저 Spring이 lazy initialization 설명한 글을 번역해보겠다. Lazy Initialization in Spring Boot 2.2 Lazy란 무엇을 의미하나요? Spring Framework는 11년 전 소스 코드가 Git으로 이동하기 전부터 lazy bean 초기화를 지원해왔습니다. 기본적으로 응용 프로그램 컨텍스트가 새로 고침될 때마다 컨텍스트의 모든 bean이 생성되고 해당 bean의 종속성이 주입됩니다. 그에 반해, lazy bean 정의가 구성된 경우 해당 bean은 필요할 때까지 생성되지 않고 종속성이 주입되지 않습니다. Lazy Initialization를 활성화하는 방법 Spring ..
Java8이상에서 MaxMetaspaceSize 설정, 반드시 해야할까?
지난글(Java 8 에서 사라진 maxPermSize, PermSize을 대체하는 옵션?)에서 Class의 Meta정보, Method의 Meta정보, Static변수와 상수정보를 저장하는 공간인 Permanent Heap에 대해서 이야기해 보았다. Java8부터 해당 Heap은 Native Memory영역으로 넘어갔으며 Native Memory상한까지 영역을 차지할 수 있으며, 그렇기에 Metaspace에 대한 옵션은 크게 주의를 가지고 설정할 필요가 없다고 적었다. 하지만, MaxMetaspaceSize를 정의하지 않은 상태의 특수한 상황이라면 어떨까? 지속적으로 class의 meta정보, static변수와 상수정보값이 늘어나는 경우에는 아래와 같이 끔찍한 일이 벌어질 것이다. 상기 applicatio..
왜 처리량이 중요한 JVM 어플리케이션은 vm.swappiness = 1로 설정하라고 할까?
STEP 1.1 과거의 이야기 STEP 1.2 번외) NVMe를 스왑 영역으로 잡으면 RAM과 속도가 비슷할까? STEP 2.1 운영체제의 캐시 영역과 스와핑 STEP 2.1.1 캐시영역 STEP 2.1.2 스와핑 STEP 2.1.3 운영체제의 메모리 재할당 방식 STEP 2.2 자바, 페이지 캐시 그리고 가비지 컬렉션 STEP 2.2.1 페이지 캐시와 더티 페이지 동기화 STEP 2.2.2 자바 메모리와 가비지 컬렉션 STEP 3.1 추신 STEP 1. 서론 STEP 1.1 과거의 이야기 STEP 1.2 번외) NVMe를 스왑 영역으로 잡으면 RAM과 속도가 비슷할까? STEP 2. 본론 STEP 2.1 운영체제의 캐시 영역과 스와핑 STEP 2.1.1 캐시영역 STEP 2.1.2 스와핑 STEP 2.1.3 운영체제의 메모리 재할당 방식 STEP 2.2 자바, 페이지 캐시 그리고 가비지 컬렉션 STEP 2.2.1 페이지 캐시와 더티 페이지 동기화 STEP 2.2.2 자바 메모리와…
[linux] 우분투에서 swappiness 설정하기
1. swappiness 는 스왑 메모리의 활용정도를 뜻함 60이 기본값이며 db를 활용하는 서버에서는 보통 1을 사용하여 스왑메모리를 사용하는 적극성을 최소화 시킨다. 2. 현재 리눅스의 swappiness 확인하기 sysctl vm.swappiness 3. vm.swappiness 를 1로 변경시켜보자 먼저 /etc/sysctl.conf 파일을 열자 vi /etc/sysctl.conf 맨 아랫줄로 이동해서 다음 내용을 추가하자 vm.swappiness=1 재부팅한다 reboot 재부팅이 됐으면 다시 명령어 입력으로 확인해보자 sysctl vm.swappiness
리눅스 메모리와 스왑(swap)리눅스 메모리와 스왑(swap)
리눅스 메모리와 스왑(swap)
DevOps와 SE를 위한 리눅스 커널 이야기 4, 5장 중 일부 내용입니다.


