如何使用Docker compose将应用容器连接到Redis容器

vojdkbi0  于 2022-11-21  发布在  Redis
关注(0)|答案(3)|浏览(296)

我正在尝试设置两个socket.io节点服务器,它们都连接到Redis进行通信,所有这些都在Docker内部。
我不断收到错误,我认为它与以下内容有关:

const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");

const pubClient = createClient({ host: "redis", port: 6379 }); // <- this host
const subClient = pubClient.duplicate();

我尝试了许多解决方案都不适合我,我是新来的 Docker 。
我的档案:
停靠文件:

FROM node:16.8
WORKDIR /home/node/app
COPY app /home/node/app/
RUN npm install
CMD npm run app 
EXPOSE 9999 6379

index.js:

const express = require("express");
const app = express();
const server = require("http").createServer(app);
const bodyParser = require("body-parser");
const appid = process.env.APPID;

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const cors = require("cors");
app.use(cors());
app.use(express.json({ limit: "8mb" }));

const { createClient } = require("redis");
const { createAdapter } = require("@socket.io/redis-adapter");

const pubClient = createClient({ host: "redis", port: 6379 });
const subClient = pubClient.duplicate();

const io = require("socket.io")(server, {
  cors: {
    origin: "*",
    methods: ["GET", "POST"],
  },
});

Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
  io.adapter(createAdapter(pubClient, subClient));
});

var allUsers = {};

app.get("/", async (req, res) => {
  res.send(`Hello from server ${appid}`);
});

io.on("connection", (socket) => {
  console.log("User connected: " + socket.id);
  socket.emit("port", appid);

  socket.on("message", (message) => {
    socket.broadcast.emit("new-message", message);
  });

  socket.on("disconnecting", (socket) => {
    console.log("User disconnected: ", socket.id);
  });
});

server.listen(appid, () => console.log(`Server running on port ${appid}`));

haproxy.cfg:

defaults
  mode http
  timeout client          35s
  timeout connect          5s
  timeout server          35s
  timeout tunnel         120s
  timeout http-keep-alive  1s
  timeout http-request    15s
  timeout queue           30s
  timeout tarpit          60s
  timeout http-request   10s

frontend http
    bind *:8080
    timeout client 10s
    use_backend all

backend all
    server s1 nodeapp1:1111
    server s2 nodeapp2:2222

docker-compose.yml

version : '3'

services:
    redis:
        image: redis
        ports:
            - "6379:6379"
    lb:
        image: haproxy
        ports:
            - "8080:8080"
        volumes:
            - ./haproxy:/usr/local/etc/haproxy
    nodeapp1:
        image: nodeapp
        environment:
            - APPID=1111
        depends_on:
            - redis lb
    nodeapp2:
        image: nodeapp
        environment:
            - APPID=2222
        depends_on:
            - redis lb

这是我得到的错误,我真的不明白它,我做了很多搜索的错误代码,但我没有找到一个解决方案可悲的。

docker-redis-1     | 1:M 13 Apr 2022 03:31:07.857 * Ready to accept connections
docker-nodeapp2-1  | 
docker-nodeapp2-1  | > test-server-for-expo@1.0.0 app
docker-nodeapp2-1  | > node index.js
docker-nodeapp2-1  |
docker-nodeapp1-1  | 
docker-nodeapp1-1  | > test-server-for-expo@1.0.0 app
docker-nodeapp1-1  | > node index.js
docker-nodeapp1-1  |
docker-nodeapp2-1  | Server running on port 2222
docker-nodeapp2-1  | node:internal/process/promises:246
docker-nodeapp2-1  |           triggerUncaughtException(err, true /* fromPromise */);
docker-nodeapp2-1  |           ^
docker-nodeapp2-1  |
docker-nodeapp2-1  | Error: connect ECONNREFUSED 127.0.0.1:6379
docker-nodeapp2-1  |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1146:16)
docker-nodeapp2-1  | Emitted 'error' event on Commander instance at:
docker-nodeapp2-1  |     at RedisSocket.<anonymous> (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:339:14)
docker-nodeapp2-1  |     at RedisSocket.emit (node:events:394:28)
docker-nodeapp2-1  |     at RedisSocket._RedisSocket_connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/socket.js:117:14)
docker-nodeapp2-1  |     at processTicksAndRejections (node:internal/process/task_queues:96:5)       
docker-nodeapp2-1  |     at async Commander.connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:162:9)
docker-nodeapp2-1  |     at async Promise.all (index 0) {
docker-nodeapp2-1  |   errno: -111,
docker-nodeapp2-1  |   code: 'ECONNREFUSED',
docker-nodeapp2-1  |   syscall: 'connect',
docker-nodeapp2-1  |   address: '127.0.0.1',
docker-nodeapp2-1  |   port: 6379
docker-nodeapp2-1  | }
docker-nodeapp1-1  | Server running on port 1111
docker-lb-1        | [NOTICE]   (1) : New worker (9) forked
docker-lb-1        | [NOTICE]   (1) : Loading success.
docker-nodeapp1-1  | node:internal/process/promises:246
docker-nodeapp1-1  |           triggerUncaughtException(err, true /* fromPromise */);
docker-nodeapp1-1  |           ^
docker-nodeapp1-1  |
docker-nodeapp1-1  | Error: connect ECONNREFUSED 127.0.0.1:6379
docker-nodeapp1-1  |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1146:16)
docker-nodeapp1-1  | Emitted 'error' event on Commander instance at:
docker-nodeapp1-1  |     at RedisSocket.<anonymous> (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:339:14)
docker-nodeapp1-1  |     at RedisSocket.emit (node:events:394:28)
docker-nodeapp1-1  |     at RedisSocket._RedisSocket_connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/socket.js:117:14)
docker-nodeapp1-1  |     at processTicksAndRejections (node:internal/process/task_queues:96:5)       
docker-nodeapp1-1  |     at async Commander.connect (/home/node/app/node_modules/@node-redis/client/dist/lib/client/index.js:162:9)
docker-nodeapp1-1  |     at async Promise.all (index 0) {
docker-nodeapp1-1  |   errno: -111,
docker-nodeapp1-1  |   code: 'ECONNREFUSED',
docker-nodeapp1-1  |   syscall: 'connect',
docker-nodeapp1-1  |   address: '127.0.0.1',
docker-nodeapp1-1  |   port: 6379
docker-nodeapp1-1  | }
docker-nodeapp2-1 exited with code 1
docker-nodeapp1-1 exited with code 1

我希望有人能帮我这个忙。提前谢谢你。

fruv7luv

fruv7luv1#

depends_on获取当前服务所依赖的服务数组

  • 您可以将“redis lb”声明为单个服务,尝试执行以下操作:
nodeapp2:
        image: nodeapp
        environment:
            - APPID=2222
        depends_on:
            - redis
            - lb
        restart: always

现在,您可以在应用程序代码中将redis服务名作为主机名连接到redis

5t7ly7z5

5t7ly7z52#

办公文档说https://docs.docker.com/compose/compose-file/compose-file-v3/#depends_on
depends_on在启动web之前不等待db和redis“就绪”-仅在它们已经启动之后
redis容器已启动,但尚未准备好连接。
最简单的方法是你可以继续尝试,直到它准备好。

let pubClient;
const pubClient = connectRedis();

function connectRedis() {
  try {
    return createClient({ host: "redis", port: 6379 });
  } catch {
    return connectRedis();
  }
}
l2osamch

l2osamch3#

我 也 遇到 过 同样 问题 , 我 的 配置 与 您 类似

const pubClient = createClient({ host: "redis", port: 6379 });

中 的 每 一 个
我 有 一 个 远程 主机 , 但 在 日志 中 我 看到 pubClient 尝试 连接 到 localhost .
我 将 此 配置 更改 为

const pubClient = createClient({url: process.env.REDIS_ENDPOINT});

格式
url 的 格式 为 redis ://{host} : {port} 。 更 详细 的 信息 可以 在 官方 网站 上 看到 。
而且 它 开始 工作 得 很 好 。

相关问题