【发布时间】:2020-06-26 05:21:46
【问题描述】:
早上好,
我遇到了一个我正在努力诊断和解决的问题。首先声明一下,我大约 6 或 7 个月前才开始学习 Python,在此之前我没有任何开发经验。我的第一个项目是一个使用 Scrapy 引擎的网页抓取项目。在学习了 Docker 之后,我决定把它分解成容器。这需要一些时间才能弄清楚,但一旦我做到了,我就可以在 docker-compose.yml 中工作和协调。
我有 5 项服务,一项用于 Scrapyd,它是 Scrapy 引擎运行的守护程序/服务器,一项用于 postgres 收集抓取的条目,一项用于轮询 postgres 以查找关键字,还有一个 postgres 服务与之配套。最后,我有部署服务,这给我带来了麻烦。
部署服务等待 Scrapyd 服务完全启动(通过脚本中的 APi 调用验证),然后为我所有的蜘蛛(抓取数据的网络爬虫)构建 python egg 文件,并通过发布请求将它们发送到刮痧。这一切都可以正常工作,但是现在我正在尝试将其部署到 Docker Swarm 上。
我在 2 个 Raspberry Pi 上设置了我的 swarm 设置,我用它来部署 Scrapyd 服务
sudo docker service create --name scrapyd --network scrapy-bridge \
--publish 6800:6800 --hostname scrapyd --with-registry-auth \
--replicas 2 my-registry:test-scrapyd-arm
然后我启动部署服务:
sudo docker service create --name scrapyd-deploy --replicas 2 \
--network scrapy-bridge --with-registry-auth \
my-registry:test-scrapyd-deploy-arm
除了部署服务似乎只影响 Scrapyd 的副本之一之外,一切似乎都很顺利。当我通过发送多个运行蜘蛛的请求进行测试时,有些会通过,有些会返回蜘蛛不存在的错误。
然后我做了:
curl 127.0.0.1:6800
多次发现蜘蛛只部署到其中一个 Scrapyd 副本
如何进行设置,以便我的部署服务影响两个节点上的 Scrapyd 服务?
docker-compose.yml:
version: '3'
services:
scrapyd:
image: my-image:test-scrapyd
ports:
- "6800:6800"
expose:
- "6800"
volumes:
- Vscrapyd:/app/clist/
networks:
- scrapyd-postgres
- scrapy-bridge
# - bridge
scrapyd-postgres:
image: my-image:test-scrapyd-postgres
ports:
- "5400:5432"
depends_on:
- scrapyd
volumes:
- Vscrapyd-postgres:/var/lib/postgresql/data
networks:
- scrapyd-postgres
- notify-bridge
notify:
image: my-image:test-notify
depends_on:
- notify-postgres
volumes:
- Vnotify:/projects/notify
networks:
- notify-bridge
- notif-postgres
notify-postgres:
image: my-image:test-notify-postgres
ports:
- "5401:5432"
depends_on:
- scrapyd-postgres
volumes:
- Vnotify-postgres:/var/lib/postgresql/data
networks:
- notif-postgres
scrapyd-deploy:
image: my-image:test-scrapyd-deploy
volumes:
- VTscrapyd-deploy:/app/clist_deploy/
networks:
- scrapy-bridge
command: ["./entrypoint.sh", "scrapyd", "6800" , "python3", "/app/clist_deploy/deploy.py"]
volumes:
Vscrapyd:
external: false
Vscrapyd-postgres:
external: false
Vnotify:
external: false
Vnotify-postgres:
external: false
VTscrapyd-deploy:
external: false
Vscrapyd-api:
external: false
networks:
default:
external:
name: bridge
notif-postgres:
driver: bridge
external: false
scrapyd-postgres:
driver: bridge
external: false
notify-bridge:
driver: bridge
external: false
scrapy-bridge:
driver: bridge
external: false
入口点.sh
#!/bin/sh
set -e
host="$1"
port="$2"
shift 2
cmd="$@"
python3 scrapy_status.py $host $port
# Retrieves the server response and parses out ok if it exists in response
# if ok then breaks out of loop
# until [ $response = "ok" ]
exec $cmd
scrapy_status.py
import subprocess, sys, time
def get_scrapyd_status(host, port):
try:
result = subprocess.check_output(["curl",f"http://{host}:{port}/daemonstatus.json"])
except subprocess.CalledProcessError:
pass
else:
return result
def main(host,port):
count = 0
while (count < 5):
r = get_scrapyd_status(host,port)
print(r)
try:
r = "".join(map(chr,r)).split(",")[1].split(":")[1].replace('"',"").strip()
except TypeError:
pass
if r == 'ok':
print('Scrapyd is up!')
sys.exit(0)
else:
print('Scrapyd not up yet...')
pass
count += 1
time.sleep(5)
if __name__ == "__main__":
if sys.argv and len(sys.argv) != 3:
sys.exit('Only 2 arguments are allowed!')
elif len(sys.argv) == 3:
host = sys.argv[1]
port = sys.argv[2]
main(host,port)
else:
sys.exit('Unknown error ocurred')
这里有一个 gist 来 deploy.py 如果有人想看的话
【问题讨论】:
-
可以添加docker-compose文件吗?
-
添加了 docker-compose.yml entrypoint.sh 和 scrapy_status.py
标签: docker docker-compose scrapy