백그라운드 서비스 TCP 통신 이상 점검

비즈니스 모델: 백엔드 서비스는 TCP를 통해 그룹의 시장 게이트웨이와 연결을 맺습니다. 각 연결 시에는 먼저 인증 요청을 보내고, 그 후 지속적으로 하트비트 패킷을 전송하여 연결 상태를 유지합니다. 하지만 어느 날, 서비스 연결 해제 경고 메시지를 받았습니다. 로그를 꼼꼼히 확인해 본 결과, 백엔드 서비스는 계속해서 하트비트 패킷을 전송하고 있었지만 상대방은 전혀 응답하지 않았음에도 불구하고 연결은 끊어지지 않고 있었습니다.

현장 간략 설명

원래 회사에서 야근하며 프로젝트 진행을 추진 중이었는데, 업무 그룹 채팅방에 갑자기 경고 메시지가 떴다. 처음에는 예전 문제라고 생각했다. 네트워크 타임아웃으로 인해 하트비트 전송이 실패해서 연결이 끊어진 것 같았다. 하지만 로그를 자세히 확인해 보니 실제 상황은 그렇지 않았다. 백엔드에서 인증 로그인 메시지를 보냈지만 계속 응답을 받지 못했고, 동시에 하트비트는 지속적으로 전송되었지만 상대방은 어떠한 하트비트 데이터도 반환하지 않았다. 로그를 심층적으로 분석한 결과 다음과 같은 몇 가지 주요 문제가 드러났다:

인가 메시지에 대한 응답이 없으면, 상대방 시스템이 재시동 중이라 인가 메시지가 적시에 처리되지 않았을 가능성이 매우 높습니다 승인되지 않은 상태에서 하트비트 데이터를 전송하는 문제: 조사 결과, 프로그램 로직의 결함이 원인입니다. 하트비트 전송 함수의 판단 로직에 문제가 있어 연결 상태만 확인하고 인증 상태를 확인하지 않았습니다. 서비스 연결이 끊어지면 재연결 메커니즘을 트리거하여 인증 메시지를 다시 보낼 수 있습니다

현재, 해결해야 할 마지막 문제점은 서비스 연결이 끊어지지 않은 이유입니다. 이 문제의 해결을 위해서는 보다 심층적이고 세밀한 점검 작업이 필요합니다.

네트워크 데이터 패킷 분석

tcpdump는 매우 강력한 네트워크 패킷 캡처 도구로, 네트워크 데이터 패킷을 포착하는 데 사용할 수 있습니다. 네트워크 데이터 패킷을 분석함으로써 우리는 네트워크 통신의 세부 사항을 보다 직관적으로 이해할 수 있습니다. 여기서는 tcpdump를 사용하여 네트워크 데이터 패킷을 포착하여 추가 분석을 할 수 있습니다.

tcpdump

데이터를 분석해 보면 심박수는 계속 정상적으로 전송되고 있지만, 상대방 서버로부터는 아무런 데이터도 수신되지 않았고, 단지 ACK만 받았기 때문에 연결이 자동으로 끊어지지 않고 있습니다

일반적인 플래그 설명

TCP 프로토콜에서 PSH(Push)와 ACK(Acknowledgment)는 데이터 전송과 흐름 제어를 위해 사용되는 중요한 플래그 비트입니다. 이들의 역할은 다음과 같습니다:


1. PSH(Push Flag)

  • 기능: PSH 플래그는 수신 측이 버퍼에 있는 데이터를 상위 애플리케이션으로 즉시 푸시하도록 요청하는 역할을 합니다(버퍼가 채워질 때까지 기다리지 않고). 이는 PSH 플래그가 있는 데이터 세그먼트를 받으면 수신 측은 운영체제 버퍼에 저장하기보다는 가능한 한 빨리 처리하여 애플리케이션에 전달합니다.

  • 전형적인 장면

    • HTTP/HTTPS 요청 시(예: GET /index.html) 클라이언트는 서버가 즉시 응답하기를 바라는 PSH를 설정합니다
    • SSH 프로토콜: 키보드 입력이 있을 때마다 PSH가 트리거되어 입력 문자가 실시간으로 전송되도록 합니다
    • 실시간 통신: 비디오 스트리밍, 온라인 게임 등 저지연 시나리오에서는 PSH를 사용하여 지연을 줄일 수 있습니다
  • 주의:

    • PSH는 필수가 아니며, 수신측은 해당 비트(flag bit)를 무시할 수 있습니다(데이터는 정상적으로 처리해야 합니다)
    • 보내는 쪽에서 PSH를 설정하지 않을 수 있으며, 이 경우 받는 쪽은 자체 버퍼링 정책에 따라 데이터를 언제 보낼지 결정합니다

2. ACK(Acknowledgment Flag)

  • 기능: ACK 플래그는 이전 데이터 세그먼트가 올바르게 수신되었음을 확인합니다. 각 ACK에는 확인 번호(Acknowledgment Number)가 포함되어 있으며, 이는 예상되는 다음 바이트 시퀀스 번호를 나타냅니다. 이는 TCP 신뢰성 있는 전송의 핵심 메커니즘입니다.

  • 작동 원리:

    • 송신자는 데이터 세그먼트를 보낼 때, 예상 수신자의 ACK 값(예: ACK = 시퀀스 번호 + 데이터 길이)을 함께 전송합니다
    • 수신 장치가 데이터를 수신하면, 수신 확인(ACK) 세그먼트를 생성하여 수신된 데이터의 시퀀스 번호를 확인합니다
    • 송신자는 해당 ACK를 수신한 후에야만 확인되지 않은 데이터를 재전송합니다
  • 예시입니다

    • 송신자가 시퀀스 번호가 100~199인 데이터 세그먼트를 보냈다면, 예상되는 수신자의 ACK200이어야 한다
    • 수신자가 100~199 범위 내의 특정 데이터를 받지 못하면, 송신자에게 재전송을 요청하기 위해 ACK=150으로 알립니다

PSH와 ACK의 조합

TCP 패킷에서 PSHACK가 동시에 나타나는 경우는 다음과 같은 상황에서 흔히 볼 수 있습니다:

  • HTTP 요청 응답 클라이언트가 POST 요청(데이터 포함)을 보낼 때, PSHACK(이전 응답 확인)가 설정됩니다

    Client → Server: SYN, ACK=1 → 建立连接
    Client → Server: PSH, ACK=1, 数据 → 发送请求数据
    Server → Client: PSH, ACK=数据长度+1 → 返回响应
    
  • SSH 핸드셰이킹 후 명령 전송 클라이언트가 명령을 입력하면 PSHACK가 포함된 데이터 세그먼트를 전송하여 명령이 즉시 전송되고 서버에서 처리되도록 합니다


다른 플래그 비트의 연관성

기호 이름 간략 설명
동기화 초기화 연결 (세 번의 악수)
FIN 종료 연결 우아하게 닫기
재설정 강제 연결 종료 (비정상 상황)
URG 긴급 긴급 포인터 표시 (거의 사용하지 않음)

요약

  • 데이터가 최대한 빨리 애플리케이션 계층에 도달하도록 하여 지연 시간을 줄이는 데 중점을 두고 있습니다
  • 데이터의 신뢰성 있는 전송에 중점을 두고, 패킷 손실이나 순서 변경을 방지합니다

두 가지는 협력하여 TCP 프로토콜의 효율성과 안정성을 균형 있게 맞췄다

금융 IT 프로그래머의 이것저것 만지작거리기와 일상의 중얼거림
Hugo로 만듦
JimmyStack 테마 사용 중