클라우드에서 WebSocket의 크기를 조절합니다(1 섹션).콘센트에서IO 및 Redis는 Docker 및 Kubernetes와 함께 분산 아키텍처를 구성합니다.
소개
Websocket은 TCP를 통해 전이중 통신을 할 수 있는 광범위한 프로토콜이다.몇 개의 라이브러리가 이 프로토콜을 실현했다. 그 중에서 가장 건장하고 유명한 것은 자바스크립트 단자
Socket.io
로 실시간 통신 모드를 신속하게 만들 수 있다.간단한 종단 간 통신
NodeJS
라이브러리 자체의 모든 예시를 사용하면 Socket.io
에서 여러 클라이언트를 연결할 수 있는 서버를 만드는 것은 상당히 간단하고 직접적이다.
이 라이브러리의 주요 기능 중 하나는 웹 소켓을 http 서버에 봉인할 수 있다는 것이다.
예를 들어 첫 번째 방법은 클라이언트가 웹소켓에 연결되면 서버 응용 프로그램이 메시지를 기록하고 메시지의 특정 메시지를 기다릴 수 있다
topic
.// Server
const socketServer = require('http').createServer();
const io = require('socket.io')(socketServer, {});
const socketPort = 5000;
io.on('connection', client => {
console.log('New incoming Connection from', client.id);
client.on('testMsg', function(message) {
console.log('Message from the client:',client.id,'->',message);
})
});
socketServer.listen(socketPort);
// Client
const io = require('socket.io-client');
const client = io('http://localhost:5000', {
transports: ['websocket']
});
client.on('connect', function(){
console.log("Connected!");
client.emit('testMsg', 'a message');
});
클라이언트가 연결된 서버는 유형 testMsg
의 메시지를 기다립니다.클라이언트는 이 컴퓨터의 WebSocket을 사용하도록 설정되어 있으며, 천진난만한 해결 방안을 http 폴링으로 시도하지 않습니다.
{ transports: ['websocket'] }
서버는 웹소켓에 연결된 모든 클라이언트에게 메시지를 방송할 수 있습니다.io.emit("brdcst", 'A broadcast message');
Tip
: those messages will be received by ALL the clients connected.
다중 서버-다중 클라이언트 통신
앞의 예는 간단하고 재미있다.우리는 그것을 효과적으로 이용할 수 있다.그러나 확장 가능한 다중 서버 구조를 만드는 것은 다른 일이며 이전의 상황처럼 직접적이지 않다.
두 가지 주요 문제를 고려해야 합니다.
첫 번째 문제는 채택
Adapter
을 통해 현지에서 해결할 수 있다.이 콘센트.io 메커니즘은 메모리에 위치하고 프로세스(서버) 간에 메시지를 전달하며 모든 클라이언트에게 이벤트를 방송할 수 있습니다.다중 서버 장면에 가장 적합한 어댑터는socket.io-redis으로
Redis
의 발표/구독 모델을 이용했다.예상한 바와 같이, 설정은 간단하고 원활하며, 단지 작은 코드만 필요하다.
const redisAdapter = require('socket.io-redis');
const redisHost = process.env.REDIS_HOST || 'localhost';
io.adapter(redisAdapter({ host: redisHost, port: 6379 }));
두 번째 문제는 클라이언트가 같은 원본 서버와 초기화된 세션을 유지하는 것이다. 이 문제는 특별히 번거로울 필요가 없다.비결은 클라이언트가 특정 서버에 연결할 때 같은 서버에 연결할 수 있도록 sticky
연결을 만드는 것이다.이것은 직접적으로 실현될 수 없지만, 우리는 NodeJS 서버 응용 프로그램 전에 뭔가를 놓아야 한다.
이것은 일반적으로 NGINX, HAProxy, Apache-Httpd와 같은
Reverse Proxy
일 수 있다.HAProxy의 경우 웹소켓 서버 응용 프로그램의 두 개의 복사본을 상상하면 백엔드 부분의 설정은 다음과 같습니다. cookie io prefix indirect nocache
server ws0 socket-server:5000 check cookie ws0
server ws1 socket-server2:5000 check cookie ws1
악수할 때 io 세션 쿠키를 설정합니다.다중 서버 요약 정보
이 구성의 예상 효과를 요약하려면:
용기화 모든 것: 소형 서비스 더미
지금까지 본 내용은 다음 그림에서 요약할 수 있습니다.

자연 진화는 Docker 이미지를 컨테이너로 하는 일련의 마이크로 서비스입니다.우리의 이전 장면은 컨테이너화할 수 있는 세 개의 구축 블록을 포함했다.
NodeJS
변체 중의 alpine
본체 이미지부터 미리 정의된 다단계 Docker image 를 만들었습니다.다른 두 개의 마이크로서비스는 본 컴퓨터의 이미지에 사용될 것이다.이 세 가지 서비스는
docker-compose
를 이용하여 배치할 수 있다.구성은 다음과 같습니다.version: '3.2'
services:
socket-server:
image: sw360cab/wsk-base:0.1.1
container_name: socket-server
restart: always
deploy:
replicas: 2
environment:
- "REDIS_HOST=redis"
proxy:
image: haproxy:1
container_name: proxy
ports:
- 5000:80
volumes:
- ./haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
depends_on:
- socket-server
redis:
image: redis:5.0
container_name: redis
deploy
일부는 Swarm
스택 배치에서만 작업할 수 있습니다.Swarm
가 시작되고 준비되었다고 가정하면 다음과 같이 배포할 수 있습니다.docker stack deploy --compose-file stack/docker-compose.yml wsk
단, Swarm
외부, 예를 들어 로컬 개발 환경에서 앞의 옵션(배치)이 무효입니다.이 경우 기본 명령을 사용할 수 있습니다.웹소켓 서버 프로그램의 추가 복사본을 수동으로 추가할 수 있습니다.
socket-server2:
image: sw360cab/wsk-base:0.1.1
container_name: socket-server2
restart: always
environment:
- "REDIS_HOST=redis"
Tip
: another elegant way to achieve that is by usingdocker-compose up -d --scale socket-server=2 socket-server
이제 모든 것을 제기하면 충분히 집행할 수 있다.
docker-compose up -d
Tip
: when usingHAProxy
remember to define the correct hostnames of the endpoints involved in the configuration file.
backend bk_socket
http-check expect status 200
cookie io prefix indirect nocache
# Using the `io` cookie set upon handshake
server ws0 socket-server:5000 check cookie ws0
# Uncomment following line for non-Swarm usage
#server ws1 socket-server2:5000 check cookie ws1
Tip
: After introducing a Reverse Proxy remember to tune the endpoint hostname and port which the client will attempt to connect to.
갈수록 많은 구성: Kubernetes 클러스터 실행
지금까지 우리는 이미 여러 서버 상황의 문제를 해결했다.우리는 또한 Docker에서 마이크로 서비스의 컨테이너화 스택을 실현했다.
현재 우리는 모든 마이크로서비스를 조율하여
docker-compose
(K8s) 자원으로 전환하고 집단에서 실행할 수 있는 진일보한 절차를 추가할 수 있다.Docker에서 전환하는 것은 정말 쉽다.우선, 우리는 역방향 에이전트 서비스를 포기할 수 있으며, 잠시 후에 우리는 원인을 이해할 것이다.그리고 우리는 모든 서비스를 한 쌍의 서비스와 배치로 전환한다.이 서비스는 요청을 수신하는 인터페이스가 될 것입니다. 프로그램이 실행되는pod 복사본을 유지할 것입니다. (K8s 용어를 모르면 각각pod를 하나의 용기로 생각하십시오.) 이 경우 Websocket 프로그램이나 Redis가 될 수 있습니다.
서비스가 받은 모든 요청은 배치가 정의한 복사본 집합으로 전달됩니다.
K8s 클러스터 설정 (내 제안 K3s 또는 Kind 을 개발 목적으로 사용하는 경우 다음이 제공됩니다.

Websocket Kubernetes 서비스
앞서 살펴본 바와 같이 Kubernetes로의 전환에서 우리는 역방향 에이전트 부분(HA Proxy)을 건너뛰었다.
이것은 완전히 고의적인 것이다. 왜냐하면 Kubernetes 서비스를 창설하면 이런 대리 형식을 직접 실현할 수 있기 때문이다.
Kubernetes 서비스는 여러 가지 방식으로 집단 밖(NodePort,LoadBalancer,Ingress,checkhere에 노출될 수 있지만 이 예에서 저는 간단한 방식을 채택하기로 결정했습니다.실제로
Kubernetes
를 사용하면 그룹 외부에 특정한 포트를 공개할 수 있고 클라이언트는 이 포트에 연결됩니다.apiVersion: v1
kind: Service
metadata:
name: wsk-svc
spec:
selector:
app: wsk-base
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10
ports:
- protocol: TCP
port: 3000
targetPort: 5000
nodePort: 30000
type: NodePort
서비스의 관건은 NodePort
아날로그 서비스의 점성 연결을 모의하는 것이다.
Tip
: In generalRound Robin
among Pods is not guaranteed using a simple solution like NodePort. In order to mimic Round Robin policy, this part of the previous configuration was employed:
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10
간단한 sessionAffinity: ClientIP
명령을 사용하여 클러스터를 구성할 수 있습니다.# Launch Redis Master/Slave Deployment and Service
kubectl create -f k8s/redis
# Launch Websocket Deployment and Service
kubectl create -f k8s/wsk
클라이언트 Gotchas
이 새로운 아키텍처를 처리하면 클라이언트에 경미한 변화가 발생할 수 있습니다.
그러나 클라이언트에
kubectl
정책을 추가하면 연결이 분실되면 유지보수를 위한 복제 집합의 첫 번째 사용 가능한pod에 다시 연결됩니다.const io = require('socket.io-client')
const client = io('http://localhost:30000', {
reconnection: true,
reconnectionDelay: 500,
transports: ['websocket']
});
결론
이 부분에서 우리는 처음부터 완전히 집단된 체계 구조에 들어갔다.다음 장에서 우리는 우리가 더욱 복잡한 해결 방안을 실현할 수 있음을 보게 될 것이다.
Note
: This part will correspond in the repository to thehaproxy
branch
공구서류
Reference
이 문제에 관하여(클라우드에서 WebSocket의 크기를 조절합니다(1 섹션).콘센트에서IO 및 Redis는 Docker 및 Kubernetes와 함께 분산 아키텍처를 구성합니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sw360cab/scaling-websockets-in-the-cloud-part-1-from-socket-io-and-redis-to-a-distributed-architecture-with-docker-and-kubernetes-17n3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)