본문 바로가기

학습 기록 (Learning Logs)/CS Study

Real-time Notification Service Using WebSocket

 

 


 

웹소켓?

client <---> server간 양방향 통신

실시간으로 server로부터 update가 필요한 data를 받는 service : 효율적 구축

 

 

출처: https://www.youtube.com/watch?v=2oMPf-ueQic

 


주로 http 기반 소통 방식

- 단방향 통신

- client : 요청

- server: 응답

http 기반 통신 종류
단방향, client가 먼저 시작해야함

 

 

 

 

하지만 채팅에서는 http(단방향)만으로는 부족하다

- 상대방이 보낸 메시지를 내 앱으로 감지하는 것이 불가능하다.

- 왜냐면 http에서는 요청이 있어야 응답할 수 있어서, 상대방이 보낸 응답을 받고 싶으면, 내가 요청을 계속해서 날려야하기 때문이다

HTTP 1.1 이하에서는 클라이언트 요청 없이는 서버에서 메시지를 보내지 못한다.

 

polling: client가 주기적으로 server에서 요청을 보내는 방식

문제점

- 요청을 보내는 주기만큼, 지연이 발생

- 불필요한 요청을 계속해서 보냄(요청의 주기가 짧다면, 반응 속도는 빨라짐, but traffic 낭비는 심해진다)

 

 

 

polling 개선 -> long polling

server가 client의 요청에 바로 응답하지 않고, update가 발생할때까지 기다림

상대방이 chat을 보내거나, timeOut으로 설정된 시간이 지나면 server는 client에게 응답을 보낸다

client는 응답을 받고, 다시 requst를 server에게 날린다

 

 

data의 update에 반응하는 속도는 빨라짐

but 서버의 부담이 커짐

- 서버가 클라이언트로부터 요청을 받을때부터 응답을 보낼 때까지 클라이언트와의 연결을 지속해야함

- 동시에 여러 클라이언트가 있다고하면, 서버가 클라이언트별로 연결을 유지해야하니, 부하가 발생

 

- http 에서 요청과 응답에 포함되는 header의 정보 양도 매번 오니.. 부담으로 작용됨

 

 

따라서 client <---> server간 양방향 통신이 필요해짐


WebSocket

 

 

http/2 : 공중전화 부스에서의 제한된 통화

- 장시간 양방향 통신을 위해 설계되지 않음

- 서버쪽에서 push를 보내는 것이 가능하지만, 이는 client의 초기 요청에 대한 응답의 일부로 이뤄짐

- 연결의 지속을 위해서도 주기적인 요청, 응답이 필요하다

- 브라우저에서의 사용이 제한 되는 부분이 많다

 

websocket: 스마트폰을 통한 자유로운 통화

Hand Shake(연결)

- http로 client -> server에게 요청을 보낸다

 

- server에서 http으로 응답을 보낸다

 

- http가 아닌, WebSocket 프로토콜로 사용하여 소통

 

header 크기 작음, 효율적 통신

 

header를 사용한 handShake

현재 http -> webSocket protocol로 바꾸자
sec-websocket-key : client가 Random으로 생성한 값을 Base64 인코딩한 문자열
서버는 sec-websocket-key 를 
sha-1 해시로 계산
base64로 인코딩

->
모두에게 알려진 어떤 공식을 사용

->
요청 문자열을 아래 문자열로 바꿈

->
서버는 client에게 돌려보냄
클라이언트는 자기가 보낸 key로부터
생성된 value가 맞는지 확인

 

 

 

종료

 

비정상적 종료

- 지정된 시간동안 메시지 없음: 확인 패킷 보내기

 

- 주기적 ping pong 프레임 주고 받아서 -> 접속 여부 확인

 

tcp 소켓, udp 소켓이란 무슨 차이?

속한 osi 계층이 다르다

계층이 낮을 수록 hardware, 계층이 높을 수록 software에 가깝다

 

web socket은 tcp를 사용한다

- Trans mission Control Protocol

- 순서, 신뢰성 보장

 

한계

로드밸런서

- 서버의 설계에 따라 구현이 복잡해진다

- 웹소켓은 특정 서버와의 지속적인 연결 안에서만 이뤄짐

- 하나의 서버 <-------> 클라이언트 : 계속해서 같은 서버로만 데이터를 전송되도록 설정해야함

- web socket 을 처리할 수 있는 load balancer를 선택하여, 구성해야한다.

더보기

🚀 일반적인 로드밸런서의 동작

  • 로드밸런서는 여러 개의 서버 중 하나를 선택하여 클라이언트의 요청을 분배하는 역할을 함.
  • 일반적인 HTTP 요청매 요청마다 다른 서버로 전달될 수 있음(Stateless).
  • 따라서, 클라이언트가 요청할 때마다 어떤 서버로 갈지 모름.

 

📌 2. 웹소켓과 로드밸런서의 문제

⚠️ 웹소켓은 특정 서버와 지속적인 연결을 유지해야 함

  • 웹소켓은 연결이 유지되는 프로토콜(Persistent Connection)임.
  • 클라이언트가 웹소켓을 열면, 한 번 연결된 서버와 지속적으로 통신해야 함.
  • 그런데, 일반적인 로드밸런서는 웹소켓 연결을 다른 서버로 보낼 수도 있음 → 연결이 끊기는 문제 발생.

📌 예제 상황

  1. 클라이언트 A가 웹소켓 연결을 시작 → 로드밸런서가 서버 S1에 연결해줌.
  2. 몇 분 후, 클라이언트 A가 새로운 웹소켓 메시지를 보냄.
  3. 일반적인 로드밸런서는 이 요청을 S2 또는 S3로 보낼 수도 있음.
  4. 하지만 클라이언트 A의 웹소켓 연결은 S1과만 유지됨 → S2/S3는 이 연결을 모름 → 에러 발생.

 

📌 3. 해결 방법: 웹소켓을 처리할 수 있는 로드밸런서 설정

웹소켓을 안정적으로 동작하게 하려면 특정한 로드밸런서 구성 방식을 적용해야 함.

✅ 해결 방법 1: Sticky Session (세션 고정)

  • 클라이언트가 최초 연결된 서버(S1)로 계속 요청이 가도록 설정하는 방식.
  • 로드밸런서가 특정 클라이언트와 서버의 연결을 유지함.
  • AWS ALB(Application Load Balancer), Nginx, HAProxy 등에서 지원.

 

📌 설정 예시 (Nginx에서 Sticky Session 설정)

  • ip_hash: 클라이언트의 IP를 기준으로 같은 서버에 유지되도록 설정.
upstream websocket_servers {
    ip_hash;  # 클라이언트의 IP를 기반으로 같은 서버에 연결
    server 192.168.1.100;
    server 192.168.1.101;
    server 192.168.1.102;
}

server {
    listen 80;
    location /ws/ {
        proxy_pass http://websocket_servers;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_http_version 1.1;
    }
}

 

 

✅ 해결 방법 2: Load Balancer with WebSocket Support

  • 웹소켓을 제대로 처리할 수 있는 로드밸런서(LB)를 선택해야 함.
  • AWS ALB(Application Load Balancer), Nginx, HAProxy 등의 LB를 웹소켓 모드로 설정.

📌 AWS ALB 설정 예시

  1. ALB 리스너(Listener) 설정
    • HTTP/HTTPS가 아닌 **WebSocket(WSS) 포트(443)**을 리스너로 추가.
    • Connection Upgrade 헤더 설정.
  2. Target Group 설정
    • 대상 서버 그룹(Target Group)에서 WebSocket 지원 모드 설정.
    • Stickiness 활성화하여 같은 서버로 연결 유지.

 

✅ 해결 방법 3: WebSocket Gateway 사용

  • 웹소켓 전용 게이트웨이(예: AWS API Gateway WebSocket, NATS, Socket.io) 사용.
  • 클라이언트의 모든 웹소켓 연결을 한 곳에서 받고, 서버 간 메시지 브로커(Kafka, Redis Pub/Sub) 를 활용하여 서버 간 데이터 동기화.

📌 WebSocket Gateway 구성

  1. 클라이언트는 WebSocket Gateway와 연결.
  2. WebSocket Gateway는 메시지를 Kafka, Redis Pub/Sub 등에 저장.
  3. 웹소켓 서버들은 브로커에서 메시지를 구독하여 클라이언트에 전달.

 

📌 4. 결론

웹소켓은 한 번 연결된 서버와 지속적인 연결이 필요함.
일반적인 로드밸런서는 웹소켓을 잘못 처리하면 연결이 끊길 수 있음.
Sticky Session(세션 고정) 설정, WebSocket 지원 LB 사용, WebSocket Gateway 방식으로 해결 가능.

🚀 만약 대규모 트래픽을 처리해야 한다면 WebSocket Gateway + Kafka/Redis Pub/Sub 조합이 가장 안정적인 방법!

 

 

메시지 크기 제한

- 브라우저, 서버, 네트워크 환경마다 web socket에서의 메시지 크기에 제약을 둘 수 있다.

 

보안

web socket은 암호가 없다

보안이 중요한 서비스면, SSL/TLS 인증서를 발급받아서 -> WSS 설정

 

 

서버에 부담을 주는건 마찬가지..

메시지들이 오가는 빈도가 높다면 네트워크 대역폭, cpu 사용량 증가

 

 


웹소켓을 이용한 실시간 알림 서비스는 어디에 사용되는가?

즉각적인 정보 전달이 필요한 서비스에서 널리 사용

사용되는 이유?

기존의 HTTP Polling(주기적으로 서버에 요청)이나 Long Polling(서버가 응답을 지연) 방식보다

지연 시간이 짧고 서버 부하를 줄일 수 있음

 

 

왜 HTTP Polling보다 웹소켓이 나은가?

 


사용되는 대표적 서비스

메신저 / 채팅 서비스

  • 예시: 카카오톡, 슬랙(Slack), 디스코드(Discord), 텔레그램(Telegram)
  • 웹소켓이 필요한 이유:
    • 새로운 메시지가 올 때마다 유저가 직접 새로고침하지 않아도 됨.
    • 메시지를 실시간으로 전송하고 바로 확인 가능.
    • 기존 HTTP 요청 방식보다 지연 시간이 적고 빠름.

 

소셜 미디어 / SNS (실시간 알림)

  • 예시: 페이스북(Facebook), 트위터(Twitter/X), 인스타그램(Instagram), 유튜브(YouTube)
  • 웹소켓이 필요한 이유:
    • 좋아요, 댓글, 멘션, 팔로우, DM 등의 이벤트를 실시간으로 전달.
    • 유저가 페이지를 새로고침하지 않아도 새로운 알림을 즉시 받을 수 있음.

 

주식 / 암호화폐 거래소 (실시간 시세 업데이트)

  • 예시: 나스닥(NASDAQ), 업비트(Upbit), 바이낸스(Binance)
  • 웹소켓이 필요한 이유:
    • 주식 및 암호화폐 가격이 초 단위로 변동되므로 실시간 데이터 업데이트가 필수.
    • HTTP Polling 방식으로는 초당 수천 개의 요청이 발생하여 서버 부하가 증가함.
    • 웹소켓을 사용하면 연결이 유지된 상태에서 변동된 데이터만 전송하여 성능 최적화 가능.

 

게임 서비스 (멀티플레이 및 알림)

  • 예시: 배틀그라운드(PUBG), 포트나이트(Fortnite), 롤(LOL)
  • 웹소켓이 필요한 이유:
    • 실시간 게임 이벤트(플레이어 위치, 채팅, 게임 내 푸시 알림 등) 전달.
    • 로비에서 친구의 접속 상태 업데이트.
    • HTTP 요청 방식으로는 빠른 반응성이 필요한 게임에서 지연이 너무 큼.

 

이커머스 / 온라인 쇼핑몰 (라이브 이벤트 & 실시간 재고 알림)

  • 예시: 쿠팡(Coupang), 11번가, 아마존(Amazon)
  • 웹소켓이 필요한 이유:
    • 한정 수량 상품이 빠르게 매진될 때, 실시간 재고 변동을 알림.
    • 구매가 완료되었을 때 실시간으로 유저에게 알림 전송(결제 승인, 배송 상태 업데이트 등).
    • 플래시 세일(타임딜)에서 실시간 가격 변동 전달.

 

실시간 고객 지원 (챗봇 및 라이브 채팅)

  • 예시: 네이버 톡톡, Zendesk, Kakao i Chatbot
  • 웹소켓이 필요한 이유:
    • 고객이 문의를 입력하면 상담사가 즉시 답변 가능.
    • 챗봇과의 대화에서도 빠른 응답 처리가 가능하여 자연스러운 UX 제공.
    • HTTP 방식으로 구현하면 고객이 응답을 기다리는 시간이 길어질 수 있음.

 

헬스케어 / IoT 디바이스 모니터링

  • 예시: 스마트워치(애플 워치, 갤럭시 워치), 헬스 모니터링 앱
  • 웹소켓이 필요한 이유:
    • 심박수, 혈압, 산소포화도 등의 건강 데이터를 실시간으로 업데이트.
    • IoT 장비(스마트홈, 자동차, 공장 센서 등)의 상태를 지속적으로 모니터링해야 함.
    • 데이터가 지연되면 사용자 경험이 나빠지거나, 헬스케어에서는 심각한 문제 발생 가능.

'학습 기록 (Learning Logs) > CS Study' 카테고리의 다른 글

WebRTC - Communicating with clients  (0) 2025.02.20
SSE (Server Sent Events)  (0) 2025.02.20
concurrenct problem  (0) 2025.02.13
noSQL  (0) 2025.02.12
mvcc  (0) 2025.02.06