톰캣 max connection, acceptcount와 소켓,파일

ttomy·2024년 1월 5일

톰캣의 max connection, accpet count, max thread에 대해
톰캣 내부와 소켓의 개념, socket의 accept까지 이어서 정리하는 글입니다.

톰캣 max connection, accept count, max thread란?

톰캣 서버 max connection, accpet count등의 변수 설정을 통해
얼마만큼의 최대 connection을 받고, 대기시키고, 스레드를 할당해 처리할 지 설정할 수 있습니다.

보통 max connection만큼 요청을 수락하고,
이를 초과하면 accept count만큼 대기 큐에 집어넣고,
max thread만큼의 스레드를 할당해 요청을 처리한다고 설명합니다.

이 max connection, accept count란 것의 실체는 뭘까요?
이 설정이 os설정과 관계없이 잘 실행될 수 있을까요?

tomcat 서버의 connection

connection 이 정확히 뭘까요?
톰캣에서는 socket과 SocketWrapper를 합해 connection이라 간주하고 있습니다.
위에서 socketWrapper까지 생성 후 connections에 넣어주는 모습으로 connection이 맺어진 걸 볼 수 있습니다.

Tomcat의 SocketWrapperBase는 socket과 endpoint를 변수로 가지는 클래스로, 소켓과 함께 동작하는 기능들을 추상화하며 연결을 대표하는 객체입니다.
conection.put()전의 작업들을 보시죠. socketbuffetHandler할당, socketWrapper생성 후 channel에 등록하는 절차를 거칩니다.

그럼 이 sockerWrapper(connection)은 언제 생성될까요? connection을 맺는 과정을 더 알아봅시다.
endpoint에서 socketOPtion을 세팅하는 과정에서 connection.put()하며 커넥션이 등록됩니다.

이 setsocketOptions()메서드는 아래와 같이 acceptor가 실행시킵니다.

톰캣의 Acceptor는 루프를 돌며
endpoint.serverSocketAccept() 를 호출하는 식으로 웹요청을 수락하고, socket을 세팅하는 클래스입니다.

org.apache.tomcat.util.net의 AbstractEndpoint를 살펴봅시다.
여기에 connections, maxConnections 변수가 존재하고, nio2EndPoint에서 위와 같이 maxConnections 미만인지 검증하여 socket의 accept를 실행합니다.

connection은 acceptor를 통해 socket.accept()하고 endPoint에 등록되는 식으로 맺어집니다.
소켓이 accept한다는 게 뭔지 더 알아봅시다,

connection이란? -> 소켓이 accept한다는 건 뭐지?

accept는 어떤 기능인지 UnixAsynchronousServerSocketChannelImpl.implAccept()를 봅시다.

눈에 띄는 부분이 있습니다.
FileDescriptor를 생성해 native메서드인 Net.accept를 실행하며 넘기는 군요! 소켓은 근본적으로 파일입니다.
소켓이라는 파일에 데이터가 패킷이라는 형태로 저장되는 것이죠.

결론적으로 accept하는 건 파일에 접근하는 행위이고 따라서 해당 프로세스에서 더 이상 파일에 접근할 수 없다면 accept도 불가능합니다.

  • 결론
    최대 maxConnection만큼 socket.accept()하여 소켓의 file Descriptor를 할당하고, 각종 설정과 socketBufferHandler의 메모리까지 할당합니다. maxconnection이 높더라도 accept 시 fd에 접근하기에 os의 open files 제한에도 영향을 받는 설정입니다.

앞선 이해를 바탕으로 max connection, accept count설정 시 고려할 점들을 더 생각해보겠습니다.
우선 max connection은 소켓에 bufferhandler(입출력 버퍼)할당 등의 작업으로 메모리를 소모하는 작업입니다. 서버의 메모리를 고려해서 설정해야겠습니다.

accept count에 의해 대기된 요청들은 시간이 지나면 어떤 timeout 에러를 반환할까?
이미 서버 소켓에서 accpet()는 되어 연결은 맺어졌기 때문에 read timeout이 발생한다.

acceptCount는 그럼 언제 사용되는 설정인가요?

accpetCount는 maConnections를 초과한 요청에 대해서도 대기하는 개수 설정입니다.

결론적으로는 socket의 bind후 listen할 때 accept count가 사용됩니다.

accpetCount만큼 backlog로 간주해 추가로 listen해 대기큐에 넣어두고 이후에 socket.accept()합니다.
이렇게 서버 소켓의 backlog에서는 오래 대기하더라도 connection timeout이 발생하지 않습니다.
connection timeout을 발생시키지 않고 사용자가 더 기다리더라도 요청을 응답하고 싶으면 acceptCount를 크게 잡으면 되겠습니다.

0개의 댓글