반응형
open files
- open files는 파일을 열 수 있는(file descriptor를 생성할 수 있는) 최대값을 말함
- ulimit 명령으로 확인할 수 있음
- 파일 뿐만 아니라 소켓, 커넥션 생성시에도 file descriptor가 생성됨
- 따라서 과도하게 커넥션이 생성됐는지 확인이 필요하면 해당 프로세스의 file descriptor가 많이 생성되었는지 확인하면 됨
현재의 open files 확인
ubuntu@ubuntu-server:~$ ulimit -a | grep files
open files (-n) 1024
ubuntu@ubuntu-server:~$ ulimit -aH | grep files
open files (-n) 1048576
테스트를 위해 open files 낮추기
sudo vi /etc/security/limits.conf
* soft nofile 1024
* hard nofile 4096
재접속 후 open files 다시 확인
ubuntu@ubuntu-server:~$ ulimit -a | grep files
open files (-n) 1024
ubuntu@ubuntu-server:~$ ulimit -aH | grep files
open files (-n) 4096
api-example.jar 생성
@RestController
public class TestController {
@GetMapping("/api/makeConnections/{connectionCount}")
public String makeConnections(@PathVariable("connectionCount") int connectionCount) {
for (int i = 0; i < connectionCount; i++) {
int index = i;
new Thread(() -> {
RestTemplate restTemplate = new RestTemplateBuilder()
.setConnectTimeout(Duration.ofMinutes(30))
.setReadTimeout(Duration.ofMinutes(30))
.build();
String response = restTemplate.getForObject("http://localhost:8080/api/hang/" + index, String.class);
System.out.println("response : " + response);
}).start();
}
return "OK";
}
@GetMapping("/api/hang/{index}")
public String hang(@PathVariable("index") int index) throws InterruptedException {
System.out.println("hang : " + index);
Thread.sleep(20 * 60 * 1000);
return "hang : " + index;
}
}
api-example.jar 실행
java -jar api-example.jar
api-example.jar에서 사용중인 file descriptor 수 확인
ubuntu@ubuntu-server:~$ jps
14566 Jps
14343 api-example.jar
ubuntu@ubuntu-server:~$ ls -l /proc/14343/fd | wc -l
17
open files보다 많은 커넥션 생성 유발해보기
- connection 요청하는 컨트롤러와 요청을 받는 컨트롤러가 같은 서버에 있으므로 2100개의 커넥션 생설 요청시 4200개의 커넥션을 생성하게됨
curl localhost:8080/api/makeConnections/2100
2020-07-19 13:44:09.813 ERROR 16914 --- [o-8080-Acceptor] org.apache.tomcat.util.net.Acceptor : Socket accept failed
java.io.IOException: Too many open files
at java.base/sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method) ~[na:na]
at java.base/sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:533) ~[na:na]
at java.base/sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:285) ~[na:na]
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:469) ~[tomcat-embed-core-9.0.36.jar!/:9.0.36]
at org.apache.tomcat.util.net.NioEndpoint.serverSocketAccept(NioEndpoint.java:71) ~[tomcat-embed-core-9.0.36.jar!/:9.0.36]
at org.apache.tomcat.util.net.Acceptor.run(Acceptor.java:95) ~[tomcat-embed-core-9.0.36.jar!/:9.0.36]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
file descriptor 수 다시 확인
- open files가 soft type은 1024, hard type은 4096으로 설정되어 있음
- 아래 내용을 확인해보면 hard type 값에 의해 제한된 것으로 보임
ubuntu@ubuntu-server:~$ ls -l /proc/14343/fd | wc -l
4097
java의 MaxFDLimit 설정 확인
- MaxFDLimit 값은 디폴트로 true
- MaxFDLimit 값이 true일 경우 open files 값을 hard type에 맞춰 자동으로 늘리도록 되어있음
- 참고
ubuntu@ubuntu-server:~$ java -XX:+PrintFlagsFinal -version | grep MaxFDLimit
bool MaxFDLimit = true {product} {default}
결론
- 위와 같은 오류 발생시 과도하게 커넥션이 생성되어있지 않은지 해당 프로세스의 file descriptor 수 확인
- open files가 낮게 잡혀있지 않은지 ulimit 명령어로 확인
- 너무 낮게 잡혀있을 경우 limits.conf 파일의 nofile 값을 적절하게 조절하여 이슈 해결
참고
반응형
'Development > Experiment' 카테고리의 다른 글
[Experiment] X-Forwarded-For, X-Real-IP (1) | 2021.03.23 |
---|---|
[Experiment] MySQL 커넥션풀 부족 현상 (0) | 2020.12.30 |
[Experiment] 스레드 과다 생성 테스트(max user processes) (0) | 2020.12.30 |