본문 바로가기

computer science

File Descriptor 제한 테스트(feat. ulimit, JMeter, VisualVM)

이전 글 테스팅 툴 - JMeter모니터링 툴 - VisualVM에서 어플리케이션을 테스트하고 어플리케이션이 사용하고 있는 자원을 모니터링하였다. JMeter 문서에 나오는 best practices에서 정확한 테스트를 위해 thread 수를 적절히 설정해야 할 필요가 있다고 나와 있었는데, 당시에는 그러면 얼마만큼의 thread 수가 적절한가? 하는 의문이 들었다. File Descriptor, ulimit을 공부하며 어떤 영향이 있는지 알 수 있는 테스트를 할 수 있었다. 이번 글은 그 테스트에 대한 글이다.

 

Spring Boot Application Server

SlowController를 하나 만들어 각 루트 요청이 Thread를 5초간 sleep 하도록 만들었다.

@RestController
@Slf4j
public class SlowController {

    @GetMapping
    public void slow() throws InterruptedException {
        log.info("call slow method");
        Thread.sleep(5000);
    }
}

 

File Descriptor(ulimit을 통한 확인)

테스트를 수행하는 JMeter 실행 프로세스를 내 맥북은 얼마나 감당할 수 있을까. 가용 자원을 알아보기 위해 ulimit 설정을 통해 확인하면 다음과 같다. 이전 글 File Descriptor란?에서 살펴본 것처럼 soft, hard 설정을 각각 확인할 수 있다.

현재 설정을 바꾸지 않는 이상, 프로세스가 실행될 때 처음 설정되는 file descriptor 수는 256개이고 최대 제한 없이 늘어날 수 있다. 실제로는 시스템 리소스에 따라 한 번에 open 될 수 있는 file descriptor 수는 제한될 것이다.

jmeter를 실행시켰을 때 프로세스의 PID는 79289이다. 동적 할당되므로 jmeter 프로세스가 실행되었을 때 할당된 PID를 확인하면 된다. 해당 PID를 이용해 현재 open되어 있는 file discriptor의 목록과 수를 확인해본다. 531개의 file discriptor가 열려 있다.

lsof -p 79289
lsof -p 79289 | wc -l

 

JMeter test

JMeter Simple HTTP request 테스트 방법은 이전 글 테스팅 툴 - JMeter를 참고한다. number of threads(users)를 2,000으로 설정해보고 요청을 날린다. 요청이 실행되면 lsof 명령어로 다시 file discriptor 수를 확인해본다.

2,532개가 되었다. VisualVM을 활용해서 Thread의 수를 확인해봐도 2,000개가 생성된 것을 확인할 수 있다. 시간이 지나며 200개씩 감소하는 것은, tomcat 기반으로 실행되고 있는 서버에 할당된 기본 thread pool 갯수가 200개이기 때문이다. 해당 요청이 매 5초 간 sleep 되기 때문에, application server가 5초마다 200개의 요청을 처리하고 응답하여 JMeter의 thread도 200개씩 감소하고 있는 것이다. 

시간이 지남에 따라 lsof 명령어로 file discriptor 갯수를 지속적으로 확인해봐도 200개씩 감소하여 테스트과 완료된 뒤 다시 531개가 되었다.

 

File Discriptor 수 설정 조정

기본 soft 설정 256은 그대로 두고, hard 설정의 값을 1,000으로 낮춰본다. 이후 해당 shell session에서 JMeter를 실행하여 동일한 테스트를 진행한다.

ulimit -Hn 1000

 

file discriptor의 수가 1,341을 찍고 동일하게 200개씩 감소한다. open 가능한 file discriptor의 수를 제한했더니 설정한 2,000개의 스레드를 통해 요청을 처리하지 못했다. JMeter Listener로 확인해보면, 다음과 같은 로그가 보인다. 자바로 구현된 JMeter 내부적으로 일정 갯수 이상의 스레드 객체는 생성한 것으로 보이나 실제 요청을 보내는 데는 실패했다. 실패한 요청의 response message를 보면 'Too many open files' 라고 되어 있다. file discriptor의 open 갯수를 초과한 것이다.

 

마치며

'하나의 서버가 요청을 몇 개나 맺을 수 있을까?'라는 질문에서 file discriptor의 설정이 미치는 영향에 대해서 알아보았다. JMeter를 client로 요청을 보냈을 때를 테스트 하였지만, 특정 운영 서버에서 여러 스레드를 생성해 작업을 동시 처리하게 된다면 file discriptor 설정이 충분히 되어 있는지, 시스템 리소스가 그만큼의 처리를 감당할 수 있을지 판단할 필요가 있다.

 

관련 글

File Discriptor란?