用docker配置项目管理系统taiga的时候,不是我一个人遇到这个问题。https://github.com/douglasmiranda/docker-taiga/issues/5

问题描述:

用docker-compose启动celery_worker和rabbitmq,但是celery_worker 连不上 rabbitmq

celeryworker_1 | [2017-12-06 07:56:36,539: ERROR/MainProcess] consumer: Cannot connect to amqp://guest:**@rabbit1:5672//: [Errno -2] Name or service not known.
celeryworker_1 | Trying again in 4.00 seconds...

创建celery的地方用官网的

app = Celery(backend='amqp', broker='amqp://')

是不行的。

改成正式点的:

app = Celery(backend='amqp', broker='amqp://guest:guest@localhost:5672/')

也是不行的,不论用localhost。docker-compose 里 给 rabbitmq 设置的  hostname 都是不行的

成功尝试一:rabbitmq在容器中,celery worker 和 发起异步任务在host

遇到问题1,首先缩小问题。分步尝试,首先尝试只用容器启动rabbitmq。然后和传统方式一样,在host手工启动celery worker。

成功。

问题缩小到celery_worker容器化的问题。

稍微靠谱点的解法是

1先手工创建1个docker bridge

2 用docker命令行分别启动rabbitmq和celery worker

3 手工把celery worker 和 rabbitmq 添加进bridge。

据说可行,但是我就是要用docker-compose的啊,这样太丑陋了。

但至少说明有可能成功(不是celery本身bug之类)

成功尝试二、rabbitmq 和celeryworker都在容器中,celery用host的ip地址连接rabbitmq。

异步发起者可以在容器中,也可以在host中

docker中只运行rabbitmq,暴露5672 和15672端口,在本地host安装celery 起celery worker 是没问题的

但是如果想把celery worker也放进容器里,就出问题了。总是提示连不上amqp。

用了各种方法,最终把rabbit5672暴露,然后把HOST主机IP灌进celery,搞定

HOST_IP = '192.168.239.129' # ip of host(run docker-compose) 
app = Celery(backend = 'rpc://', broker = 'amqp://guest:guest@{0}:5672/'.format(HOST_IP))

额外的小技巧:

ubuntu查看 ip :

ip addr show

成功尝试三、rabbitmq 和celeryworker都在容器中,celery用docker-compose.yml中的service_name连接

异步发起者只能在容器中

20171207隔了一天,终于发现其实不需要HOST_IP,可以用名字连接的!

只不过名字被docker、rabbitmq给来回误导了

先说答案:celery里要用docker-compose.yml里的这个名字,即启动rabbitmq镜像的那个service的名字(而不是他的hostname,我把它注释掉了,太坑人):

这样搞的话,比用HOST_IP不好的地方在于,没法从host发起异步任务(返回不了结果)。只能从docker-compose启动容器,在里面发起异步任务。

好处是5672端口不用暴露出来了。docker-compose内网和外部完全隔离,外面感觉不到rabbitmq存在(当然我保留了暴露15672监控端口,其实也可以不暴露)

——其实postgres的问题也是一样,用Adminer连接的时候,Server处填的也是docker-composer.yml里的service名字。

http://www.cnblogs.com/xuanmanstein/p/7742647.html

结论

解决方案不细说了,放github上了

https://github.com/xuqinghan/celery-with-docker-compose#celery-with-docker-compose

心得:

1 遇到问题,要缩小、后退、分解。

 像锯木头锯不动了,要往后撤,然后稍微换换方向,角度,再用巧力,不要用蛮力:

1从部署taiga的event模块遇到celery_worker连接不上;

2退到用docker-compose运行celery官网的a+b小函数的demo 还是连不上;

3再继续后退:只用docker-compose部署rabbitmq。手工启动celery和发起异步任务,成功。

4在3成功的基础上小步前进。而此时问题已经缩小、聚焦到足够小,再尝试几种解决方案:localhost   127.0.0.1   hostname     bridge方式docker0网络

5搞定、总结。成为自己的技能点,到处复用。

2 不要有洁癖,

不追求rabbitmq不暴露任何端口,只服务于docker-compose的网络(不是docker0) ,在host里暴露端口不丢人;

在开发机上,只在调试当前工程时启动当前的docker-compose。在生产环境还是1机1个组的。不追求多工程在一个机器上运行。

不追求一次就实现全都容器化,和写代码一样,先写好单次执行的逻辑,再套外层的for循环。

——注意到了这些点,问题半天不到就搞定了;死钻牛角尖,可能N天都无解。

3 不能有0 or 100分这种想法。

不能急躁,也不能浮躁(想一次就得100分);

也不能因为想太多,把问题看成铁板1块,就畏惧困难(直接交白卷得0分)。

——做工程,都是1分、1分地得分,也是1分 1分地扣分的。 这和合同收付款、各种节点是完全不同的!不要被后者的干扰带乱了自己的工作节奏。

做工程是类似持仓、空仓的长期过程,而不是啪啪啪不断交易的各种精彩瞬间。(如果永远处在赶工、保/抢节点的状态,要么是自己工作能力不行,要么就是项目管理SB,没有轻重缓急)

4做工程的人,在工程上做任何事每次出手,都要有章有法:有高度的目的论,且目的又和普通人不同:

1 贯彻目的和意图导向的思考。在意从需求、系统用例、到组件名、类名、子过程名、直到变量名的命名,名不正则言不顺,要强迫自己和别人(Не жалей ни себя, ни врагов.“不要吝惜自己和敌人”——《斯拉夫女人的告别》白俄版)思考目的性、价值和重要性排序。并且在每一天、每一句的开发中不断加深学习、打磨、养成习惯;

2 能每时每刻聚焦特定问题,能暂时忽略其他问题和要求,有“置XX之敌于不顾”,“攻其一点,不及其余”的勇气和能耐。这是建立在对能力的自信心(“打哪个,哪个就剩不下”,所以我有资格挑着打)基础之上的纯粹和纯净的心理状态。

接触新人、业余选手、非技术人员的最大感觉就是:

在1上,想的太简单,做的太随意(用我的话说,像个孩子);

在2上,一次想得太,想得太多(0分VS100分 来回地跳变,还是像个什么都想要的孩子)。

——包括之前的自己,也是这样。还是因为功力不够+心浮气躁=棒槌。

因为和他们视角不同(甚至完全不同),所以自己首先不要生气,配合别人的任务区时可以忍着点,尽力配合;

但只要进入自己的责任区,就是要火力全开。如果气着对方也不要在意(负责这片的人是我,我也没想故意气谁,所以也无所谓)。

和战斗机一样,包线上各有优势区,但进入大喷9(Spitfire LF IX)的优势区,就不要怪Hispano 炮狠了。

技术方面的感受:容器和镜像不是万能的。不是什么都适合打包进镜像。

celery和django都相继不再在dockerhub发布官方镜像。因为这俩在用的时候,大家都是定制、引用之后才用的。

并不是这俩和docker决裂了,只是不适合打包进dockerfile罢了。

对开发人员来说,什么适合塞进dockerfile呢?配环境的步骤+配出来的一致性,隔离的、纯净的运行环境。塞配置文件的位置。

其实dockerfile有点像测试框架。而源代码和配置文件,类似mock。

所以,这符合我下意识的做法:我喜欢把源代码、和各种配置文件,数据库文件都放在外面, 用-v 或者volumns 在容器启动时挂进去,而不是写在dockerfile里(git clone 源代码,具体配置参数),直接build成image。

这种套路,非常类似于依赖注入,把repository,service塞进component的过程。

此外,这样好写测试用例啊(不依赖实际连接web和数据库)!

任何单元测试的运行,都不能依赖真实的web和数据库访问。

否则因为耗时间或者环境难配,不得不每次注释掉一部分用例,现在想想,那还测试个屁啊!

写程序的精髓在于识别和感受到  复杂性+变化性   VS  繁琐+稳定    ,然后不断分离,隔离,让不同变化速率,膨胀系数的材料,高度地解耦。

——写程序的门道无非那几条,但是知道这些道理是一回事,理解认同这些道理是另一回事, 而实际工作中能在各种场合把这些招给用出来,用活了,又是另一回事了。

和武术、修行一样,知易行难。“三岁小儿道得,八十老翁行不得”。

需要勤学苦练,不是蛮干(grasshopper里不写代码,一片一片地电池)

从各种角度、各种道路、多次实践,去领悟相同的道理。

然后就容易全面开窍和到处突破了。

之前了解、学TDD半天,但是就是用不好;现在用了一段时间docker,反而容易找到依赖注入的感觉。

自己写的程序,有哪些是框架性的,类似dockefile的;有哪些是频繁改动的,类似源代码、配置文件内容的,要层次分明,分离,然后各自获得自由;

这个分离:就是意图与实现、虚VS实;部队 VS 分队,测试用例VS外部接口的mock。

关注点分离了,就各自聚焦了,也自由了。分得开,责任边界清晰,才联合得起来。

从celery rabbitmq with docker-compose 引出对容器、依赖注入、TDD的感悟的更多相关文章

  1. Docker Compose—简化复杂容器应用的利器

    Compose是用于定义和运行复杂Docker应用的工具.你可以在一个文件中定义一个多容器的应用,然后使用一条命令来启动你的应用,然后所有相关的操作都会被自动完成. 1. 安装Docker和Compo ...

  2. Docker | Compose创建mysql容器

    本文通过Docker Compose来创建mysql容器 在linux服务器上创建文件,用于管理容器 mkdir docker-mysql cd docker-mysql vim docker-com ...

  3. 009.Docker Compose部署及基础使用

    一 Docker Compose概述 Compose是一个用于定义和运行多容器Docker应用程序的工具.使用Compose,您可以使用YAML文件来配置应用程序的服务.然后,使用单个命令,您可以从配 ...

  4. 阿里云上Docker Compose部署wordpress

    先上官方文档: https://docs.docker.com/compose/wordpress/ 我的环境: [root@xyjk1002 ~]# cat /etc/redhat-release ...

  5. ubuntu 14.04离线安装docker和docker compose

    准备安装包 1.下载docker docker支持以下版本的ubuntu系统Artful 17.10 (Docker CE 17.11 Edge)Zesty 17.04Xenial 16.04 (LT ...

  6. Docker:Docker Compose 详解

    Docker Compose 概述与安装? 前面我们使用 Docker 的时候,定义 Dockerfile 文件,然后使用 docker build.docker run 等命令操作容器.然而微服务架 ...

  7. 使用docker compose部署服务

    谈到微服务的话题,技术上我们往往会涉及到多服务.多容器的部署与管理. Docker 有三个主要的作用:Build, Ship和Run.使用docker compose我们可以在Run的层面解决很多实际 ...

  8. 基于Docker Compose的.NET Core微服务持续发布

    是不是现在每个团队都需要上K8s才够潮流,不用K8s是不是就落伍了.今天,我就通过这篇文章来回答一下. 一.先给出我的看法和建议 我想说的是,对于很多的微小团队来说,可能都不是一定要上K8s,毕竟上K ...

  9. 单机编排之Docker Compose

    当在宿主机启动较多的容器时候,如果都是手动操作会觉得比较麻烦而且容器出错,这个时候推荐使用docker 单机编排工具docker compose,Docker Compose 是docker容器的一种 ...

随机推荐

  1. java调用存储过程mysql

    在java中调用带返回值的存储过程的实现 直接上代码: DELIMITER $$ CREATE /*[DEFINER = { user | CURRENT_USER }]*/ PROCEDURE `t ...

  2. gcc升级

    升级到4.8[这个应该是目前最新的啦,不过网上查的话已经到5.2啦,感觉落后一点比较稳,当然还有就是这个版本是新的里面使用最多的]wget http://people.centos.org/tru/d ...

  3. VMWARE安装centos6 http://www.centoscn.com/image-text/setup/2013/0816/1263.html

    http://www.centoscn.com/image-text/setup/2013/0816/1263.html

  4. 通俗理解RxJS(一)

    自学 Rx 快有一个周了, 它非常适合处理复杂的异步场景.结合自己所学,决定写系列教程. 我认为, Rx 中强大的地方在于两处 管道思想,通过管道,我们订阅了数据的来源,并在数据源更新时响应 . 强大 ...

  5. AOAPC I: Beginning Algorithm Contests -- Training Guide (Rujia Liu) Chapter 3. Data Structures Fundamental Data Structures

    10410 这题说的是给了一棵多叉树的 bfs遍历轨迹 和dfs 遍历 轨迹 在父节点向叶子节点扩展的时候优先遍历编号较小的节点.我还原出这课树特殊判定 根据bfs的顺序来建立这课树,用一个队列安排要 ...

  6. python 展开嵌套的序列

    将一个多层嵌套的序列展开成一个单层列表 可以写一个包含yield from 语句的递归生成器来轻松解决这个问题. from collections import Iterable def flatte ...

  7. [转载]C#操作符??和?:

    先看如下代码: string strParam = Request.Params["param"]; if ( strParam== null ) {     strParam= ...

  8. 20180112final和static

    final关键字 fianl关键字可以修饰类.成员变量.和方法中的局部变量. (java中的局部变量?定义在方法中的变量都是局部变量,使用前必须初始化) 1.fianl类 Final类不能被继承,即可 ...

  9. JS四舍五入保留两位小数

    //四舍五入保留2位小数(若第二位小数为0,则保留一位小数) function keepTwoDecimal(num) { var result = parseFloat(num); if (isNa ...

  10. Linux LNMP架构搭建

    一.搭建LNMP基本架构 1.L(http) N(nginx) M(mysql) P(php) 2.安装顺序 Mysql-->PHP-->Nginx 3.安装包 Discuz_3. htt ...