EventLoopGroup 관련 질문드립니다.

883 views
Skip to first unread message

JunGyun Lee

unread,
May 16, 2019, 12:23:16 AM5/16/19
to Netty Korean User Group
안녕하세요. Netty 처음 써보게 된 초보 개발자 입니다. 잘 부탁드립니다.

client 에서 사용하는 EventLoopGroup 의 내부 동작에 대해 여쭤보고 싶은게 있습니다.

아래와 같이 Case 별로 테스트를 했을 때, 열린 File descriptor 의 갯수는

Case1 > Case2 > Case3 순이였습니다.

File descriptor 확인 방법은 ' lsof -p <pid> | wc -l ' 명령어로 확인했습니다.  

EventLoopGroup 생성자의 아규먼트 수가 커질수록 file descriptor 개수도 많아지는거 같은데, 

왜 그런지 내부적인 동작을 알고 싶습니다. 

답변 부탁드리겠습니다. 감사합니다.


Case 1. EventLoopGroup 의 Thread 수를 설정하지 않음.
- 아래와 같이 소스 코드를 구현하면, 서버 환경에 맞춰서 자동으로 스레드 수를 지정하는 걸로 알고 있습니다.
- EventLoopGroup group = new NioEventLoopGroup(); 

Case 2. EventLoopGroup 의 Thread 수를 2로 설정
- EventLoopGroup group = new NioEventLoopGroup(2);

Case 3. EventLoopGroup 의 Thread 수를 10 으로 설정
- EventLoopGroup group = new NioEventLoopGroup(10);



* 제가 생각해 본 바로는 EventLoopGroup 내의 스레드가 각각 이벤트 큐에 등록된 것을 처리하기 위해 Socket 연결을 하게 되고, 스레드 개수가 늘어난 만큼 소켓을 많이 open 하기에 File descriptor 가 늘어난 걸로 생각하고 있습니다.



Eugene Kim

unread,
May 16, 2019, 6:56:54 AM5/16/19
to Netty Korean User Group
답변 다시는 분이 없어서 부끄럽지만 제가 아는 대로 답해보겠습니다.

질문자께서 정의하신 group이 worker group을 의미하는 거라면(boss group과 worker group은 하는 일이 다릅니다),
이 설정값은 동시에 처리할 수 있는 채널의 개수를 의미합니다. (동시 접속수가 아닙니다)
통상적으로 질문자가 등록했을 decoder의 decode()와 handler의 channelRead() 메서드가 수행되는 동안 하나의 워커를 점유하게 됩니다.
이 부분에서 지연이 발생한다면 앞단에서는 여유가 생길 때까지 기다릴 수 밖에 없지요.
소켓 연결을 처리하는 부분은 위에서 언급했던 boss group이 처리하는 부분으로 일반적인 경우 1로 설정하여도 충분합니다.

File description의 늘어나는 문제는 단순히 thread 갯수와 연관지어 생각할 수는 없습니다.
client가 연결을 유지하는지, read time-out은 얼마인지? worker가 처리하는 비즈니스 로직이 얼마나 걸리는지, 
무슨 일을 하는지(이 곳에서도 파일을 열 수도 있겠지요) 등 고려해야할 변수가 많습니다.

웹서비스를 예로 든다면, 트래픽이 몰려서 worker가 처리하는 부분에서 지연이 발생하는 경우를 가정해 보겠습니다.
클라이언트 입장에서 socket이 연결된 뒤 요청을 보내고 나서는 read time out이 발생할 때까지 기다리고 있을 것입니다. 
이 때 소켓 연결 수가 제한되지 않았다면 이런 연결이 계속 늘어서 결국에는 파일오픈 갯수를 초과하여 서비스가 폭발하고 말 것입니다.

이런 경우에는 worker 개수를 늘려줘야 오히려 파일오픈 수가 줄어 들겠지요.

그럼 얼마까지 올려줘야 하는냐 하면, 그 답은 서비스에 따라 다르다 입니다.
우선은 CPU가 놀지 않고 적당하게 부하가 올라가는 수치를 찾아야 하겠지요. (CPU는 놀면서 위와 같은 이유로 서비스가 죽을 수도 있습니다)
그리고 나서 용량을 초과하는 요청이 들어오지 못하도록 앞단에 배압 로직을 추가해야 할 것 입니다.
병목이 발생하는 부분은 다양합니다. 의외로 CPU 부하 자체가 1차 원인이 되어 서비스가 죽는 경우는 많지 않습니다.

참고로, Case 1의 경우는 소스를 확인해 보면, 최대 worker thread 갯수가 Runtime.getRuntime().availableProcessors() * 2 입니다.

이상입니다.
혹시 잘못 기술한 부분이 있다면 너그러운 마음으로 지적해주시면 감사하겠습니다.



2019년 5월 16일 목요일 오후 1시 23분 16초 UTC+9, JunGyun Lee 님의 말:

JunGyun Lee

unread,
May 21, 2019, 10:27:13 PM5/21/19
to Netty Korean User Group
답변 주셔서 정말 감사합니다.
 
위 테스트는 Client 쪽의 EventLoopGroup 으로 테스트를 수행해보았습니다. (TCP 서버는 떠있습니다)
 
   Netty Client 쪽의 EventLoopGroup 의 스레드 수가 증가함에 따라 Filedescriptor 가 증가하는데 
  
   왜 그런건지 알고 싶었습니다.

   시간 내서 답변 주셔서 정말 감사드립니다.

   

 

 

Trustin Lee (trustin)

unread,
May 26, 2019, 6:58:05 PM5/26/19
to nett...@googlegroups.com, Netty Korean User Group
안녕하세요.

제가 기억하기로, NIO Selector의 Linux 구현체는 Selector.wakeup()을 구현하기 위해 실제로 통신하는데 사용되지 않는 유닉스 도메인 소켓을 Selector 인스턴스 갯수에 비례하여 생성합니다. Selector.wakeup()이 호출되었을 때 해당 유닉스 도메인 소켓에 무언가를 쓴다거나 하여 epoll_wait() 시스템 콜이 즉시 깨어나게 됩니다.

도움이 되셨길 빕니다.
이희승 드림
--
이 메일은 Google 그룹스 'Netty Korean User Group' 그룹에 가입한 분들에게 전송되는 메시지입니다.
이 그룹에서 탈퇴하고 더 이상 이메일을 받지 않으려면 netty-ko+u...@googlegroups.com에 이메일을 보내세요.
더 많은 옵션을 보려면 https://groups.google.com/d/optout을(를) 방문하세요.
Sent from Mailspring

JunGyun Lee

unread,
Jun 10, 2019, 9:15:33 AM6/10/19
to Netty Korean User Group
도움이 많이 됐습니다.

시간내서 답변해주셔서 감사합니다.

 

2019년 5월 27일 월요일 오전 7시 58분 5초 UTC+9, 이희승 (Trustin Lee) 님의 말:
안녕하세요.

제가 기억하기로, NIO Selector의 Linux 구현체는 Selector.wakeup()을 구현하기 위해 실제로 통신하는데 사용되지 않는 유닉스 도메인 소켓을 Selector 인스턴스 갯수에 비례하여 생성합니다. Selector.wakeup()이 호출되었을 때 해당 유닉스 도메인 소켓에 무언가를 쓴다거나 하여 epoll_wait() 시스템 콜이 즉시 깨어나게 됩니다.

도움이 되셨길 빕니다.
이희승 드림

On May 16 2019, at 11:43 am, JunGyun Lee <rainma...@gmail.com> wrote:
안녕하세요. Netty 처음 써보게 된 초보 개발자 입니다. 잘 부탁드립니다.

client 에서 사용하는 EventLoopGroup 의 내부 동작에 대해 여쭤보고 싶은게 있습니다.

아래와 같이 Case 별로 테스트를 했을 때, 열린 File descriptor 의 갯수는

Case1 > Case2 > Case3 순이였습니다.

File descriptor 확인 방법은 ' lsof -p <pid> | wc -l ' 명령어로 확인했습니다.  

EventLoopGroup 생성자의 아규먼트 수가 커질수록 file descriptor 개수도 많아지는거 같은데, 

왜 그런지 내부적인 동작을 알고 싶습니다. 

답변 부탁드리겠습니다. 감사합니다.


Case 1. EventLoopGroup 의 Thread 수를 설정하지 않음.
- 아래와 같이 소스 코드를 구현하면, 서버 환경에 맞춰서 자동으로 스레드 수를 지정하는 걸로 알고 있습니다.
- EventLoopGroup group = new NioEventLoopGroup(); 

Case 2. EventLoopGroup 의 Thread 수를 2로 설정
- EventLoopGroup group = new NioEventLoopGroup(2);

Case 3. EventLoopGroup 의 Thread 수를 10 으로 설정
- EventLoopGroup group = new NioEventLoopGroup(10);



* 제가 생각해 본 바로는 EventLoopGroup 내의 스레드가 각각 이벤트 큐에 등록된 것을 처리하기 위해 Socket 연결을 하게 되고, 스레드 개수가 늘어난 만큼 소켓을 많이 open 하기에 File descriptor 가 늘어난 걸로 생각하고 있습니다.




--
이 메일은 Google 그룹스 'Netty Korean User Group' 그룹에 가입한 분들에게 전송되는 메시지입니다.
이 그룹에서 탈퇴하고 더 이상 이메일을 받지 않으려면 netty-ko+unsubscribe@googlegroups.com에 이메일을 보내세요.
더 많은 옵션을 보려면 https://groups.google.com/d/optout을(를) 방문하세요.
Sent from Mailspring
Reply all
Reply to author
Forward
0 new messages