socket.io 如何处理 docker 部署的多个实例?
Posted
技术标签:
【中文标题】socket.io 如何处理 docker 部署的多个实例?【英文标题】:How does socket.io work with multiple instances which were deployed by docker ? 【发布时间】:2019-12-25 07:29:19 【问题描述】:我创建一个服务器并在其上绑定 socket.io
const express = require('express');
var io = require('socket.io');
var app = express();
app.get('/', (req, res) =>
res.sendFile(__dirname + '/index.html');
)
var server = require('http').createServer(app);
io = io.listen(server);
io.on('connection', function(socket)
console.log('user connected', socket.id)
socket.on('chat message', function(msg)
console.log(socket.id, 'message: ' + msg);
);
);
server.listen(9999)
当我在 docker 上部署 1 个实例时没问题(我使用 docker swarm 和 docker stack), 而如果我设置部署副本
这是我的 compose.yml
version: '3'
services:
web:
image: socket:v2
ports:
- "5000:9999"
command: node index.js
deploy:
replicas: 2
我遇到一些问题,当发送消息到服务器时, server1 显示已连接,并显示收到消息, 但下次我发送时,server2 显示收到消息
我怎样才能让它成为“我连接的服务器就是我发送消息的服务器”?
【问题讨论】:
我认为你需要应用和配置Sticky session,你可以阅读这个***.com/questions/10494431/… 【参考方案1】:您可以使用jwilder/nginx-proxy。这是使用 docker-gen 的 Docker 容器的自动 Nginx 代理。
用法
运行它:
$ docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
然后使用环境变量 VIRTUAL_HOST=subdomain.youdomain.com
启动您想要代理的任何容器
$ docker run -e VIRTUAL_HOST=foo.bar.com
被代理的容器必须暴露被代理的端口, 通过在他们的 Dockerfile 中使用 EXPOSE 指令或使用 docker run 或 docker create 的
--expose
标志。如果您的 DNS 设置为将
foo.bar.com
转发到主机 运行 nginx-proxy,请求将被路由到一个容器VIRTUAL_HOST env
变量集。
使用 Docker-compose 你可以试试这个例子
Docker 编写
version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
whoami:
image: jwilder/whoami
environment:
- VIRTUAL_HOST=whoami.local
这里的jwilder/whoami
将被jwilder/nginx-proxy
代理为指定的VIRTUAL_HOST
您可以阅读更多关于 jwilder/nginx-proxy here 和 here 的信息
另外,你可以查看docker-compose-scale-with-sticky-sessions
你可以查看上面的例子
docker-compose up
然后运行
curl -H "Host: whoami.local" localhost
您将在每个响应中看到一个容器 ID
现在,是时候扩大规模了
docker-compose scale whoami=3
现在查看来自不同容器的屏幕截图响应。
要使用粘性会话,您可以使用 tpcwang 的 fork,允许您在容器级别使用 IP_HASH
指令来启用粘性会话。
如果你对内置功能感兴趣,可以试试Implement persistent (sticky) sessions
Cookie IP 哈希您可以发布服务并配置代理以实现持久化 (粘性)会话使用:
IP 哈希
以下示例显示了如何使用 客户端 IP 哈希。这不像 cookie 那样灵活或一致 但为某些无法使用 其他方法。使用 IP 散列时,将 Interlock 代理重新配置为 使用主机模式联网,因为默认的入口联网模式 使用 SNAT,它会隐藏客户端 IP 地址。
创建一个覆盖网络,以便隔离和安全的服务流量:
$> docker network create -d overlay demo
使用 cookie 创建服务以用于使用 IP 的粘性会话 散列:
$> docker service create \
--name demo \
--network demo \
--detach=false \
--replicas=5 \
--label com.docker.lb.hosts=demo.local \
--label com.docker.lb.port=8080 \
--label com.docker.lb.ip_hash=true \
--env METADATA="demo-sticky" \
ehazlett/docker-demo
Interlock 检测服务何时可用并发布它。什么时候 任务正在运行并且代理服务已更新,应用程序正在运行 可通过http://demo.local 获得,并配置为使用粘性 会话:
【讨论】:
以上是关于socket.io 如何处理 docker 部署的多个实例?的主要内容,如果未能解决你的问题,请参考以下文章