当前位置: 首页 > 后端技术 > Node.js

解决docker-compose中depends_on无效的问题

时间:2023-04-04 01:04:43 Node.js

背景最近在写一个即时聊天程序的demo。技术栈差不多就是vue+nodejs+redis+rabbitmq,就是用rabbitmq来处理消息队列。程序写好后,我用docker-compose做了一个镜像,方便以后给别人做DEMO。docker-compose.yml大致如下version:"3"services:redis:image:redis:latestports:-"6379:6379"container_name:im-redis-composerestart:alwayscommand:redis-server--appendonlyyesrabbitmq:image:rabbitmq:managementports:-"5672:5672"-"15672:15672"container_name:im-rabbitmq-composeenvironment:RABBITMQ_DEFAULT_USER:guestRABBITMQ_DEFAULT_PASS:guestRABBITMQ_DEFAULT_VHOST:my_vhostbackend:build:.links:-redis-rabbitmqcontainer_name:im-server-composerestart:on-failuredepends_on:-rabbitmq-redisports:-"3000:3000"原因是nodejs服务的启动会与redis和rabbitmq建立连接,并且存在依赖关系。于是我在docker-compose中使用depends_on属性确定启动顺序,然后在docker容器中使用links属性做网络别名访问,一切似乎都很顺利。但是当我输入docker-composeup命令的时候,报错了。分析查看启动日志,首先是nodejs报错,启动时报connectrefused,连接rabbitmq时报错。im-server-compose|错误:连接ECONNREFUSED172.24.0.3:5672im-server-compose|在TCPConnectWrap.afterConnect[asoncomplete](net.js:1136:16){im-server-compose|errno:-111,im-server-compose|代码:'ECONNREFUSED',im-server-compose|系统调用:'connect',im-server-compose|地址:'172.24.0.3',im-server-compose|端口:5672im-server-compose|}im-server-compose|错误!代码ELIFECYCLEim-server-compose|错误!errno1接下来打印出rabbitmq启动成功的消息im-rabbitmq-compose|2020-01-0608:44:17.837[info]<0.504.0>管理插件:HTTP(非TLS)侦听器在端口15672im-rabbitmq-compose上启动|2020-01-0608:44:17.839[info]<0.610.0>统计数据库启动.im-rabbitmq-compose|2020-01-0608:44:17.839[info]<0.609.0>在itim-rabbitmq-compose中启动具有3个进程的工作池'management_worker_pool'|2020-01-0608:44:18.132[info]<0.8.0>服务器启动完成;3个插件started.im-rabbitmq-co提出|*rabbitmq_managementim-rabbitmq-compose|*rabbitmq_management_agentim-rabbitmq-compose|*rabbitmq_web_dispatchim-rabbitmq-compose|完成3个插件。嘿!有点糊涂!明明是设置depends_on来决定启动顺序的,为什么rabbitmq还没有完全启动,就跑nodejs服务了?解决方案google了半天,还是没有找到更好的解决方案,浪费了很多时间终于去看了docker-compose文档中关于depends_on的章节,然后找到了解决depends_ondoesnotwaitfordb和redis在启动web之前“准备好”-仅在它们启动之前。如果您需要等待服务准备就绪,请参阅控制启动顺序以获取有关此问题的更多信息和解决它的策略。depends_on在启动web之前container,它不会等到db和redis这两个容器进入就绪态,而是等到它们都启动了,如果需要等到依赖的服务进入就绪态,需要看文章Controllingthestartupsequence这篇文章Controllingthestartupsequenceofthecontainer./startup-order/粗略说一下他提到的解决方案,在容器启动命令执行之前,运行一个shell脚本,这个脚本会访问的页面依赖服务或pingAPI以确定底层服务是否准备就绪。然后去启动真正的服务。有一个现成的解决方案sh脚本叫wait-for,只需要下载这个shell,在dockerfile中添加RUNapt-get-qupdate&&apt-get-qyinstallnetcatdocker-compose.yml调用wait-for命令即可版本:“3”服务:redis:图像:redis:最新端口:-“6379:6379”容器名称:im-redis-compose重启:始终命令:redis-server--appendonly是rabbitmq:图像:rabbitmq:管理端口:-“5672:5672”-“15672:15672”容器名称:im-rabbitmq-compose环境:RABBITMQ_DEFAULT_USER:来宾RABBITMQ_DEFAULT_PASS:来宾RABBITMQ_DEFAULT_VHOST:my_vhostrebitmq-builder:。撰写重启:失败取决于_on:-rabbitmq-redis端口:-“3000:3000”命令:sh-c'./wait-for.shrabbitmq:15672--npmrunstart'command:sh-c'./wait-for.shrabbitmq:15672--npmrunstart'表示可以访问rabbitmq:15672的管理页面后,执行真正的nodejs启动命令”npmrunstart》好久没来sf写专栏了,希望对大家有帮助!