현재 각 수집기와 서버는 TCP + 팀에서 정의한 프로토콜을 기반으로 수집한 데이터를 전송하고 있다. 그런데 한 수집기에서 방화벽을 올렸더니 다른 머신의 데이터 수집도 전부 멈추어버린 것이다.
NioSocket
+ Non-blocking
설정으로 데이터가 들어온 이벤트 발생시 데이터를 읽고 데이터가 없으면 넘어갈 텐데 왜 멈추는 지 분석하였다.
while
로 blocking
을 하고 있었다머신에서 특정 설정으로 방화벽을 올려서 TCP에 전송하는 데이터를 막으면 서버쪽에서 TCP가 끊긴줄 모르게 된다. NioSocket
의 Non-blocking
방식이므로 read에 Timeout 설정은 당연하게 불가능한데, 어디서 blocking
이 되고 있는지 파악해야 했다.
TCP로 헤더와 바디를 순서대로 받고 있었는데, 헤더에 바디 길이가 있다. 이 바디 길이 만큼 ByteBuffer
를 할당하고 NioSocket
에서 read
하는 로직에서 while
문으로 할당한 버퍼 크기만큼 데이터를 다 받을 때까지 반복해서 읽도록 반복문을 돌리고 있었다. read
는 Non-blocking
설정대로 데이터들 네트워크에서 다 들어오는 것을 기다리지 않으나 직접 blocking
을 하고 있던 것이다.
Map
을 통하여 Buffer
를 저장하고 있도록 수정NioSocket
에서 TCP 요청으로 등록할 체널은 고유한 키를 생성하여 등록하는 점을 이용하여 Map
의 키를 SelectionKey
로 하고 값을 Buffer
로 하여 진정한 Non-blocking
으로 TCP channel read를 할 수 있도록 수정하였다.
한 번의 read로 Buffer
를 완성하지 못하면 다음 반복문에서 알맞은 TCP input이 있다면 마저 해당 Buffer
에 담게 된다.
너무 당연하게 Non-blocking
설정이 있어 Non-blocking
으로 동작하고 있다고 믿었다. while
+ read
문을 보면서 blocking
로직인지 왜 생각하지 못했지 반성하게 되었다.