用docker配置項目管理系統taiga的時候,不是我一我的遇到這個問題。https://github.com/douglasmiranda/docker-taiga/issues/5html
用docker-compose啓動celery_worker和rabbitmq,可是celery_worker 連不上 rabbitmqgit
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...github
建立celery的地方用官網的web
app = Celery(backend='amqp', broker='amqp://')
是不行的。docker
改爲正式點的:數據庫
app = Celery(backend='amqp', broker='amqp://guest:guest@localhost:5672/')
也是不行的,不論用localhost。docker-compose 裏 給 rabbitmq 設置的 hostname 都是不行的django
遇到問題1,首先縮小問題。分步嘗試,首先嚐試只用容器啓動rabbitmq。而後和傳統方式同樣,在host手工啓動celery worker。ubuntu
成功。網絡
問題縮小到celery_worker容器化的問題。app
稍微靠譜點的解法是
1先手工建立1個docker bridge
2 用docker命令行分別啓動rabbitmq和celery worker
3 手工把celery worker 和 rabbitmq 添加進bridge。
聽說可行,可是我就是要用docker-compose的啊,這樣太醜陋了。
但至少說明有可能成功(不是celery自己bug之類)
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
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。
關注點分離了,就各自聚焦了,也自由了。分得開,責任邊界清晰,才聯合得起來。