본문 바로가기

개발기술/통신 인터페이스, 프로토콜

장기연결 소켓통신

소켓통신

쌍방이며 연결 상태를 유지하는 stateful 통신 방식

 

장기연결 소켓통신 종류

① WebSocket (네가 아는 것)

  • HTTP → Upgrade → TCP 위에서 연결 유지
  • 브라우저/서버 친화적
  • 채팅, 알림, 대시보드

② TCP 소켓 (Persistent TCP)

  • HTTP 없음
  • 서버 ↔ 클라이언트가 직접 TCP 연결 유지
  • 메시지 포맷은 직접 정의
  • POS / 단말 / IoT 쪽에서 제일 흔함
  • 특징:
    • 연결 유지
    • keep-alive / heartbeat 직접 구현
    • framing(메시지 경계) 직접 관리

③ gRPC (HTTP/2 기반 장기 연결)

  • 내부 서비스 통신에서 많이 씀
  • 스트리밍 RPC 지원
  • 연결은 계속 유지됨

④ MQTT (브로커 기반)

  • IoT 표준
  • publish / subscribe
  • 항상 연결 유지

⑤ SSE (Server-Sent Events)

  • HTTP지만 연결 유지
  • 서버 → 클라이언트 단방향

 

 

HTTP/Socket통신 어떻게 결정되는가??

  • TCP는 메시지를 모른다. OS에게 소켓은 그냥 바이트 스트림을 받아드리는 창구이다.
  • Socket이 지속적으로 열려있을지  바로, 열고 닫을지는 Application에서 OS 함수호출을 통해서 결정한다.
handleRequest()
sendResponse()
socket.close()

 

onConnect()
  while (connected) {
  readMessage()
}

 

HTTP와 무엇이 다른가?

 

메세지 경계처리 : HTTP Protocol VS 커스텀정의

HTTP는 메시지 형식이 표준으로 완전히 정의되어있어 메세지 경계 분리를  서버 프레임워크(서블릿 컨테이너 Tomcat)가 책임진다

따라서, 애플리케이션이 바이트스트림과 HTTP의 세부를 몰라도 된다

  • 시작 라인
  • 헤더
  • 빈 줄
  • 바디
  • Content-Length / Transfer-Encoding

소켓 통신은 메세지 형식이 정해져있지않아서 개발자가 설계한 애플리케이션이 경계를 책임진다. 애플리케이션이 바이트 스트림을 세부적으로 다루어야한다. 

  • 내가 설계
  • 내가 파싱
  • 내가 예외 처리
  • 연결상태관리 : StateFul-Stateless가 다르다

 

서버 메모리 관점: 세션(Session) vs 커넥션(Connection)

  • HTTP (Stateless 지향): 서버는 요청이 끝남과 동시에 해당 스레드와 메모리를 비웁니다. 
  • Socket (Stateful): 서버 메모리에 SocketChannel 객체와 해당 기기의 정보가 계속 살아있어야 합니다. 2만 개 매장에서 연결되어 있다면 서버 힙(Heap) 메모리에는 항시 2만 개의 객체가 상주합니다.
    • 연장선: 메모리 누수(Leak)가 발생하면 서버가 즉시 뻗습니다. 그래서 Netty 같은 프레임워크는 참조 카운팅(ReferenceCounted)을 통해 메모리를 극도로 관리합니다.

 

장애/끊김 감지 방식: "수동적" vs "능동적"

  • HTTP: 클라이언트가 요청을 안 보내면 서버는 클라이언트가 살았는지 죽었는지 알 방법이 없고, 알 필요도 없습니다.
  • Socket:  연결이 끊긴 상태를 감지하지못하면, 그 장비를 위한 SocketChannel 객체각종 버퍼 그리고 OS에는 FD라는 소켓이 낭비되어 메모리가 비효율적으로 사용됨.

메시지 처리 방식: "완성형" vs "진행형"

  • HTTP (Tomcat): HttpServletRequest라는 객체가 내 손에 들어왔을 때는 이미 모든 바이트 조립이 끝난 상태입니다. 
  • Socket (Netty): 개발자는 ByteBuf를 보면서 "여기까지가 주문 번호고, 여기서부터는 메뉴 이름이구나"를 직접 판단.

스케일링(Scaling) 방식: "L4/L7 로드밸런싱"의 차이

  • HTTP: 아무 서버에나 요청을 던져도 됩니다(Stateless). 로드밸런서가 그냥 남는 서버에 배분하면 끝입니다.
  • Socket: 한 번 맺어진 연결은 특정 서버에 귀속됩니다. 그러므로  L4 스위치(장비)나 F5, 혹은 클라우드의 NLB(Network Load Balancer)는 연결을 고유한 키값으로 저장하고 동일한 서버로 지속적을 보내줌.
    • 연장선: 서버를 재시작하거나 늘릴(Scale-out) 때, 기존에 연결된 2만 개의 소켓을 어떻게 안전하게 끊고 새 서버로 유도할 것인지(Graceful Shutdown), 그리고 특정 서버에만 연결이 쏠리지 않게 어떻게 배분할 것인지(Sticky Session/Connection)가 설계의 핵심입니다.
    • 논리적 상태 (Session): 장비 식별자, 현재 진행 중인 주문 번호, 장바구니 정보 등을 redis같은 캐쉬에 담아서 
    • 연결 끊김: L4 로드밸런서가 연결을 끊거나, 서버 점검으로 소켓이 닫힙니다.
    • 재접속: 클라이언트(키오스크)가 다시 접속합니다. 이번에는 L4가 서버 B로 연결해 줍니다.
    • 인증 및 조회: 클라이언트가 "나 1004번 매장이야"라고 말하며 접속합니다.
    • 세션 복구: 서버 B는 자신의 메모리가 아닌 Redis를 뒤집니다.
    • 재개: 서버 B는 그 정보를 바탕으로 클라이언트에게 "500번 주문 이어서 하자"라고 응답합니다.

 

 

'개발기술 > 통신 인터페이스, 프로토콜' 카테고리의 다른 글

Message Broker : Kafka  (0) 2025.11.27
MessageBroker : RabbitMQ,  (0) 2025.09.22
응용계층 : HTTP와 그 외  (0) 2025.08.22
RabbitMQ : Java Client 통신구조  (1) 2025.07.07
전송계층 : TCP와 UDP  (0) 2025.04.30