갑자기 연결된 모든 수집기에서 수집이 멈췄어요!

Gunjoo Ahn·2023년 10월 15일
1

회고

목록 보기
8/8

문제: 한 데이터 수집기의 머신의 방화벽을 켰더니 모든 수집이 멈추는 현상

현재 각 수집기와 서버는 TCP + 팀에서 정의한 프로토콜을 기반으로 수집한 데이터를 전송하고 있다. 그런데 한 수집기에서 방화벽을 올렸더니 다른 머신의 데이터 수집도 전부 멈추어버린 것이다.

NioSocket + Non-blocking 설정으로 데이터가 들어온 이벤트 발생시 데이터를 읽고 데이터가 없으면 넘어갈 텐데 왜 멈추는 지 분석하였다.

원인: whileblocking 을 하고 있었다

머신에서 특정 설정으로 방화벽을 올려서 TCP에 전송하는 데이터를 막으면 서버쪽에서 TCP가 끊긴줄 모르게 된다. NioSocketNon-blocking 방식이므로 read에 Timeout 설정은 당연하게 불가능한데, 어디서 blocking이 되고 있는지 파악해야 했다.

TCP로 헤더와 바디를 순서대로 받고 있었는데, 헤더에 바디 길이가 있다. 이 바디 길이 만큼 ByteBuffer를 할당하고 NioSocket에서 read하는 로직에서 while문으로 할당한 버퍼 크기만큼 데이터를 다 받을 때까지 반복해서 읽도록 반복문을 돌리고 있었다. readNon-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 로직인지 왜 생각하지 못했지 반성하게 되었다.

profile
Backend Developer

0개의 댓글