使用 docker-compose 时 web 容器和 rabbitmq 容器间 WebSocket 连接的地址该怎么写?

2019-07-14 00:41:37 +08:00
 1oNflow

最近写一个使用了 RabbitMQ 的 spring boot 项目,采用 docker 部署,所以有一个 openjdk 容器和一个 rabbitmq 容器,docker-compose.yml 里面是这样定义的:

services:
  core:
    build:
      context: .
      dockerfile: docker/core/Dockerfile
    ports:
      - 8080:8080

  rabbitmq:
    build:
      context: .
      dockerfile: docker/rabbitmq/Dockerfile
    ports:
      - 5672:5672
      - 15672:15672

然后项目的 application.yml 里面,把 localhost 替换成 rabbitmq

spring:
  rabbitmq:
    host: rabbitmq
    port: 5672

这样后端到 rabbitmq 的连接是正常的,但是前端用 websocket 连 rabbitmq 的 stomp (插件已开)却总是报错( 61613 端口也试了):

var ws = new WebSocket('ws://rabbitmq:15674/ws');
var client = Stomp.over(ws);

报错信息:

WebSocket connection to 'ws://rabbitmq:15674/ws' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED

想问下 websocket 这里应该怎么写地址才能实现两个容器间的通信?

3448 次点击
所在节点    程序员
12 条回复
40huo
2019-07-14 00:46:28 +08:00
docker compose 里加上 link
gzlock
2019-07-14 01:40:56 +08:00
要 link 同名容器,host 就是容器名字
可以参考官方 docker-compose 的配置例子,有写的
also24
2019-07-14 01:50:22 +08:00
前端指的是前端网页上?

网页上的代码,跑在你的浏览器上,也就是跑在客户端的系统上。
客户端的系统上,怎么会有 rabbitmq 这个 host 呢?自然就连不上了。

配置文件里把 15672 端口转发出来了,也就是说目前这个服务监听了宿主机的 15672 端口。
因此,此处应当写你的 docker 宿主机的 IP 或 hostname:ws://docker_server_ip:15672/ws

另外:你配置里的端口号是 15672,代码里是 15674,记得改掉
1oNflow
2019-07-14 10:56:27 +08:00
@40huo
@gzlock 这个试过了,添加了 links 也不行,而且查到新版 docker 不需要 links 可以直接用别名。application.yml 里的设置就生效了,websocket 就不行。
1oNflow
2019-07-14 11:01:08 +08:00
@also24 rabbitmq 的容器的地址按理说就是 rabbitmq (替换了 localhost ),而且 java 代码访问 rabbitmq 就没问题。
15672 是网页管理器的端口,stomp 的端口是 15674,这个没暴露出来给容器外访问,难道是因为这个?
carlclone
2019-07-14 11:11:24 +08:00
你把前端也部署在容器里就好了
salamanderMH
2019-07-14 11:15:23 +08:00
客户端的系统上,肯定没有 rabbitmq 这个 host,自然就连不上了。
also24
2019-07-14 12:07:20 +08:00
@1oNflow
你仔细想一下你的前端代码运行在什么地方。

另外,端口的问题,你需要从容器外部访问的端口,自然需要映射出来。

还有就是,我感觉你似乎需要了解下映射到 0.0.0.0 和映射到 127.0.0.1 的不同。
Hopetree
2019-07-14 13:11:24 +08:00
如果前端不是容器的话,那就使用 127 加本地映射端口啊
1oNflow
2019-07-14 16:12:46 +08:00
@also24 前端忘了在正文里说了,就是 spring 加模板引擎,后端渲染的 html,所以前后端都在一个 jar 一个容器里。我看 java 后台连接 rabbitmq 没问题就以为前端也应该没问题。
后来开放了 mq 容器的 15674 端口,问题就解决了,原以为 compose 的两个容器会有更紧密的联系(相比于 docker 外的用户),可以直接互相访问…
also24
2019-07-14 16:22:39 +08:00
@1oNflow #10

说实话我实在是没看懂你的 “前端” 到底指的是什么。
你所说的 “前端”,究竟指的是哪部分代码。
到底是谁在连接 rabbitmq 的 websocket ?

是说输出 ->前端页面<- 的 ->后端 Java 代码<- 去连接 websocket ?
还是在说 ->前端页面上的 JavaScript <- 本身去连接 websocket ?

我看了下 STOMP 是个 js 插件,所以我理解为你说的是第二种情况,
这种情况我不觉得单纯的开放端口就能解决。

你的错误代码也很明确的表示了:net::ERR_NAME_NOT_RESOLVED
是主机名没有被找到,而不是端口连接超时失败之类的。


我现在开始很好奇你到底是怎样的情况了。
hantsy
2019-07-14 22:49:45 +08:00
客户端 JS 程序,除非是部署在一个 Docker 环境,如 K8s,Docker Swarm, 否则用 IP 连接吧。

用 docker-compose 运行后,可以直接查到虚拟机 IP 地址,docker-machine env.

也可以用 Localhost,127.0.0.1,前提是虚拟机 IP 映射到本地 IP。

我用 Docker Toolbox 比较多,Virtualbox 可以用命令映射服务地址,例如,VBoxManage modifyvm "meandev" --natpf1 "tcp-port3306,tcp,,3306,,3306"

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/582767

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX