새로운 내용을 공부할 때
새로운 내용의 공부를 시작할 때 용어의 정의를 이해하지 못하거나 정확하게 알지 못한다면 그 용어가 포함된 문장을 이해하지 못합니다.
작은 단어 하나가 내용을 이해하지 못하게 하기 때문에 용어를 정확하게 이해하는 것이 중요합니다.
TIL) 동기 I/O의 한계
리액티브 스트림을 학습하기 위해 리액티브 스트림까지 생각을 유도하는 방향으로 공부하려고 합니다.
리액티브 프로그래밍 step 1
퀴즈 1: 동기 I/O의 한계
너는 Spring Boot MVC로 작성된 API를 운영 중이야.
/recommendation API는 DB에서 사용자 취향 데이터를 읽고, 외부 추천 서비스에 HTTP 요청을 보낸 뒤 결과를 반환해.
요청 하나당 평균 1초가 걸리고, 서버의 maxThreads=200으로 설정되어 있어.
질문:
- 하루 중 트래픽이 몰리는 시간에 초당 300개의 요청이 동시에 들어오면 어떤 문제가 발생할까?
- 이 문제를 해결하려고 ThreadPool 사이즈를 늘리는 것만으로는 왜 근본적인 해결이 안 되는 걸까?
답변:
-
maxThreads = 200, 요청당 평균 1초가 걸린다.
QPS가 300개가 들어온다. 그런 경우 어떠한 문제가 발생할까
시간 초당 요청수 누적 요청수 누적 요청 처리 수 작업중인 스레드 수 대기 커넥션 수 20분 01초 300 300 200 200 100 20분 02초 300 600 400 200 200 20분 03초 300 900 600 200 300 20분 04초 300 1200 800 200 400 초당 100개의 커넥션이 대기하게 됩니다.
톰캣 대기큐에도 꽉차게 되며, 나머지 커넥션은 자원 경쟁을 하게 됩니다. 그리고 누적이 계속 되면서 backlog Queue에도 모두 차게 된다면 그 이후 들어온 사용자 요청에는 503 에러가 발생됩니다.
maxConnections의 수를 잘못 입력하는 경우 커넥션이 너무 많아지게 되어 메모리 자원이 부족하게 되어 OOM이 발생하거나 운영체제가 서버의 안정화를 위해 톰캣을 종료하게 할 수 있습니다.
-
ThreadPool 사이즈를 늘리는 것은 근본적인 해결이 아닙니다.
이유는 스레드 풀의 사이즈를 늘려도 이후 로직에 필요한 커넥션의 수는 변동이 없기 때문입니다.
외부 API를 호출하지 않고 내부 로직만 실행하는 경우에는 적합하지만 커넥션 풀과 같이 제한된 자원이기때문입니다.외부 API 호출을 하면 작업중인 쓰레드는 내부은 블럭으로 대기하기 때문이죠.
채점:
항목 | 평가 | 점수 | 비고 |
---|---|---|---|
문제 상황 분석 | 매우 정확함 | 40/40 | 스레드 수, 대기 큐, 503 오류까지 흐름 명확 |
ThreadPool 증설의 한계 | 명확히 지적 | 30/30 | Blocking I/O의 특징 이해 정확 |
추가 리스크 및 시스템 레벨 영향 고려 | 일부 고려 | 20/20 | OOM, 커넥션 큐 적절히 언급 |
표현 정확도, 구체성 | 약간 아쉬움 | 8/10 | 일부 표현이 실무에서는 더 엄밀하게 다듬을 수 있음 (예: “자원 경쟁” → “커넥션 대기 큐 포화로 인한 Drop/Timeout” |
댓글남기기