메인 콘텐츠로 건너뛰기

스트리밍 데이터를 수신하는 Client 구축

스트리밍 endpoint를 사용할 때는 활용을 최적화하기 위해 고려해야 하는 일반적인 모범 사례가 있습니다.    

Client 설계

filter stream endpoint를 사용해 솔루션을 구축할 때에는 다음 기능을 수행할 수 있는 클라이언트가 필요합니다:
  1. filter stream endpoint에 대한 HTTPS 스트리밍 연결을 설정합니다.
  2. 스트림에서 규칙을 추가·삭제하기 위해 filter stream rules endpoint로 비동기적으로 POST 요청을 전송합니다.
  3. 데이터량이 적을 때의 처리 – 스트리밍 연결을 유지하면서 게시물 객체(Post object)와 keep-alive 신호를 감지합니다.
  4. 데이터량이 많을 때의 처리 – 비동기 프로세스를 사용해 스트림 수신을 후속 처리와 분리하고, 클라이언트 측 버퍼가 정기적으로 비워지도록 합니다.
  5. 클라이언트 측에서 볼륨(사용량) 추적을 관리합니다.
  6. 스트림 연결 끊김을 감지하고 상태를 평가한 뒤 스트림에 자동으로 재연결합니다.  

스트리밍 엔드포인트에 연결하기

X API v2 스트리밍 엔드포인트에 연결을 수립한다는 것은, 매우 오랜 기간 지속되는 HTTP 요청을 보내고 응답을 점진적으로 파싱한다는 의미입니다. 개념적으로는 HTTP를 통해 끝없이 이어지는 파일을 다운로드하는 것처럼 생각할 수 있습니다. 연결이 수립되고 나면, 연결이 열려 있는 동안 X 서버는 해당 연결을 통해 게시물 이벤트를 전송합니다.  

데이터 소비

JSON 객체의 개별 필드는 순서가 없으며, 모든 상황에서 모든 필드가 항상 존재하는 것은 아닙니다. 마찬가지로, 개별 활동(activity)은 정렬된 순서로 전달되지 않으며, 중복된 메시지가 발생할 수 있습니다. 시간이 지남에 따라 새로운 메시지 유형이 추가되어 스트림을 통해 전송될 수 있다는 점을 염두에 두어야 합니다. 따라서 클라이언트는 다음을 허용/처리할 수 있어야 합니다:
  • 임의의 순서로 나타나는 필드
  • 예기치 않거나 누락된 필드
  • 정렬되지 않은 포스트
  • 중복 메시지
  • 언제든지 스트림을 통해 내려올 수 있는 새로운 임의의 메시지 유형
관련 포스트 데이터 및 요청한 필드 파라미터 외에도, 스트림 연결에서는 다음과 같은 유형의 메시지가 전달될 수 있습니다. 이 목록이 완전하지 않을 수 있으며, 스트림에 추가 객체가 도입될 수 있다는 점에 유의하세요. 파서가 예기치 않은 메시지 형식도 문제없이 처리할 수 있도록 하세요.  

버퍼링

스트리밍 엔드포인트는 데이터가 사용 가능해지는 대로 최대한 빠르게 전송하므로, 많은 경우 매우 높은 데이터량이 발생할 수 있습니다. X 서버가 스트림에 새 데이터를 즉시 기록할 수 없는 경우(예: 클라이언트가 충분히 빠르게 읽지 못하는 경우. 자세한 내용은 연결 끊김 처리를 참조하세요), 클라이언트가 따라잡을 수 있도록 서버 쪽에서 콘텐츠를 버퍼링합니다. 그러나 이 버퍼가 가득 차면 연결을 끊는 강제 해제가 발생하며, 버퍼에 쌓여 있던 포스트는 삭제되고 다시 전송되지 않습니다. 더 자세한 내용은 아래를 참조하세요. 앱의 처리 속도가 뒤처지고 있는 시점을 파악하는 한 가지 방법은, 수신 중인 포스트의 타임스탬프를 현재 시간과 비교하고, 이를 시간 경과에 따라 추적하는 것입니다. 공용 인터넷 환경에서는 잠재적인 지연과 일시적인 장애 때문에 스트림 정체(백업)를 완전히 없앨 수는 없지만, 앱을 적절히 구성하면 대부분의 정체를 방지할 수 있습니다. 정체 발생을 최소화하려면 다음을 수행하세요.
  • 클라이언트가 스트림을 충분히 빠르게 읽고 있는지 확인하세요. 일반적으로 스트림을 읽는 동안 실질적인 처리 작업을 수행해서는 안 됩니다. 스트림은 읽기만 하고, 처리할 작업은 다른 스레드/프로세스/데이터 저장소에 넘겨 비동기적으로 처리하세요.
  • 데이터 센터의 인바운드 대역폭이, 장기간 지속되는 대용량 데이터뿐 아니라 훨씬 더 큰 스파이크(예: 평소의 5~10배 수준의 데이터량)도 수용할 수 있을 만큼 충분한지 확인하세요. 필터링된 스트림의 경우, 귀하 측에서 필요한 데이터량 및 해당 대역폭은 전적으로 규칙이 어떤 포스트와 일치하는지에 따라 달라집니다.  

사용량 추적 및 규칙 관리

스트림과 관련해 개발자들이 생각하는 “정상적인” 데이터 볼륨의 기준이 서로 다르기 때문에, 특정 퍼센트의 감소/증가나 기간에 대해 일반적인 권장값을 제시하지는 않습니다.  스트림 데이터 볼륨에 예상치 못한 변동이 있는지 모니터링하는 것을 고려해 보세요. 데이터 볼륨 감소는 스트림 연결 해제와는 다른 문제의 징후일 수 있습니다. 이런 상황에서는 스트림이 여전히 keep-alive 신호와 일부 신규 활동 데이터를 수신하고 있을 수 있습니다. 다만 포스트 수가 눈에 띄게 줄어들었다면, 애플리케이션이나 네트워크로 유입되는 데이터 볼륨을 감소시키는 요인이 있는지 조사하고, 관련 공지가 있는지 status page를 확인해야 합니다. 이러한 모니터링을 구현하기 위해, 일정 시간 동안 기대하는 신규 포스트 개수를 추적할 수 있습니다. 스트림의 데이터 볼륨이 지정한 임계값보다 충분히 낮아지고, 정해진 시간 안에 회복되지 않는다면 경보와 알림이 발생하도록 해야 합니다. 특히 필터링된 스트림에서 규칙을 수정하는 중이거나, 포스트 활동이 급증하는 이벤트가 발생한 경우에는 데이터 볼륨이 크게 증가하는지도 함께 모니터링하는 것이 좋습니다. 필터링된 스트림을 통해 전달되는 포스트는 전체 월간 포스트 볼륨에 포함되므로, 최적화를 위해 소비량을 추적하고 조정해야 합니다. 볼륨이 높은 경우, 각 규칙에 sample: 연산자를 추가하여, 필요 시 100% 매칭을 sample:50 또는 sample:25로 줄이는 것을 고려하세요.  또한 App 내에 볼륨이 미리 설정한 임계값을 초과할 때 팀에 알림을 보내는 기능을 구현하고, 너무 많은 데이터를 가져오는 규칙을 자동으로 삭제하거나, 극단적인 상황에서는 스트림에서 완전히 연결을 끊는 등의 추가적인 조치를 도입하는 것도 권장합니다.  

시스템 메시지에 응답하기

Keep-alive 신호 최소 20초마다 스트림은 열린 연결을 통해 \r\n 캐리지 리턴 형태의 keep-alive 신호(하트비트)를 전송하여 클라이언트의 타임아웃을 방지합니다. 클라이언트 애플리케이션은 스트림에 포함된 \r\n 문자를 정상적으로 처리할 수 있어야 합니다. 클라이언트가 사용 중인 HTTP 라이브러리에서 읽기(read) 타임아웃을 올바르게 구현했다면, 이 기간 동안 어떤 데이터도 읽히지 않을 경우 HTTP 프로토콜과 HTTP 라이브러리가 이벤트를 발생시키도록 할 수 있으며, \r\n 문자를 명시적으로 감시할 필요는 없습니다. 이 이벤트는 일반적으로 예외가 발생하는 형태이거나, 사용 중인 HTTP 라이브러리에 따라 다른 형태의 이벤트일 수 있습니다. 이러한 타임아웃을 감지하기 위해 HTTP 메서드를 에러/이벤트 핸들러로 감싸는 것을 강력히 권장합니다. 타임아웃이 발생하면 애플리케이션은 재연결을 시도해야 합니다. 에러 메시지 v2 스트리밍 엔드포인트는 스트림 내에서 에러 메시지를 전달할 수도 있습니다. 아래에는 이러한 메시지의 기본 형식과 몇 가지 예시가 제공됩니다. 전달되는 메시지는 변경될 수 있으며, 새로운 메시지가 도입될 수도 있다는 점에 유의하십시오. 클라이언트 애플리케이션은 변경될 수 있는 시스템 메시지 페이로드를 유연하게 처리할 수 있어야 합니다. 에러 메시지에는 문제를 해결하는 방법을 설명하는 문서로 연결되는 링크가 포함됩니다. 메시지 형식:
	"errors": [{
		"title": "operational-disconnect",
		"disconnect_type": "UpstreamOperationalDisconnect",
		"detail": "이 스트림은 운영상의 이유로 업스트림에서 연결이 끊어졌습니다.",
		"type": "https://api.x.com/2/problems/operational-disconnect"
	}]
}
버퍼가 가득 차서 강제 연결 해제를 나타내는 오류 메시지는, 강제 연결 해제를 유발한 백업(정체) 때문에 해당 메시지 자체가 전달되지 못하는 경우 클라이언트에 도달하지 못할 수 있습니다. 따라서 앱은 재연결을 시작하기 위해 이러한 메시지에 의존해서는 안 됩니다.