關(guān)于socket.io的群集解決方案,官網(wǎng)中給出了3個示例代碼。除了負載均衡的軟件不同熄赡,其他的代碼其實都是一樣的,分別為:nginx
,httpd
, haproxy
齿税。以下以nginx為例說明彼硫。官網(wǎng)給的demo基于docker,讓你可以直接運行偎窘。代碼結(jié)構(gòu)如下:
- 首先代碼
index.js
中加入redis
適配
var io = require('socket.io')(3000);
var redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
除此之外乌助,和單機下的代碼并無區(qū)別。由于客戶端可能連接到集群中不同的節(jié)點陌知,為了在集群中不同的節(jié)點之間傳遞消息他托,socket.io官方以redis的發(fā)布訂閱功能為基礎(chǔ)做了消息路由分發(fā):socket.io-redis
。socket.io-redis
在節(jié)點向客戶端群發(fā)消息時會將該消息發(fā)布到redis的訂閱隊列中仆葡,讓其他節(jié)點能夠訂閱到該消息赏参,從而實現(xiàn)節(jié)點間消息推送。
nginx
配置
worker_processes 4;
events {
worker_connections 1024;
}
http {
server {
listen 80;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://nodes;
# enable WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
upstream nodes {
# enable sticky session
ip_hash;
server server-john:3000;
server server-paul:3000;
server server-george:3000;
server server-ringo:3000;
}
}
該配置文件沿盅,在請求頭中加入 Upgrade
來支持 websocket
使用ip_hash
保證同一個ip請求到固定的容器把篓。將請求分發(fā)給四個服務(wù):server-john
,server-paul
,server-george
,server-ringo
.
docker-compose
配置
nginx:
build: ./nginx
links:
- server-john
- server-paul
- server-george
- server-ringo
ports:
- "3000:80"
server-john:
build: ./server
links:
- redis
expose:
- "3000"
environment:
- NAME=John
server-paul:
build: ./server
links:
- redis
expose:
- "3000"
environment:
- NAME=Paul
server-george:
build: ./server
links:
- redis
expose:
- "3000"
environment:
- NAME=George
server-ringo:
build: ./server
links:
- redis
expose:
- "3000"
environment:
- NAME=Ringo
redis:
image: redis:alpine
expose:
- "6379"
該配置文件中,nginx依賴四個web服務(wù)腰涧,每個web服務(wù)都依賴redis韧掩。每個服務(wù)都暴露3000端口。environment
環(huán)境變量用于標示當前的服務(wù)器名稱窖铡,以此來告訴客戶端請求被分發(fā)到哪臺服務(wù)器了疗锐。會在index.js
以下的代碼中用到坊谁。
var serverName = process.env.NAME || 'Unknown';
- 每個服務(wù)的docker配置
FROM mhart/alpine-node:6
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
# Bundle app source
COPY . /usr/src/app
EXPOSE 3000
CMD [ "npm", "start" ]
該配置功能:拷貝package.json,安裝依賴滑臊,拷貝源文件口芍,啟動服務(wù)。
由于示例采用docker安裝雇卷,只要你的電腦中有安裝docker鬓椭,當我們下載完官方的代碼,直接在代碼根目錄下運行以下命令便可啟動服務(wù)進行測試关划。
$ docker-compose up -d
注意
官網(wǎng)的 socket.io-redis
庫只有在消息廣播(socket.broadcast.emit)
的時候小染,才能生效。對于私發(fā)的消息祭玉,如果想在集群不同節(jié)點之間傳遞還是需要自己手動寫一個解決方案氧映,具體可以參考redis的發(fā)布訂閱功能在nodejs下的api春畔。