Advertisement
目标
1️⃣ 把每个 Worker(爬虫引擎)放进 容器,
2️⃣ 用 Docker‑Compose、Docker Swarm 或 Kubernetes 让“Worker”按需水平扩容,
3️⃣ 让Nginx/Traefik 作为负载均衡把抓取任务分发给所有可用节点。
下面把三种常见方案拆成步骤+代码,你可以直接拷贝到自己的项目里跑。
| 方案 | 适用场景 | 关键技术 |
|---|---|---|
| Docker‑Compose | 单机 / 小型集群,快速原型 | docker-compose.yml + replicas |
| Docker Swarm | 需要多主机、服务发现 | docker stack deploy + --replicas |
| Kubernetes | 高可用、弹性扩容、丰富生态 | kubectl scale / HorizontalPodAutoscaler |
小结:
- Compose 适合本地开发 / 单机,最快上手。
- Swarm 适合几台服务器,无需学习 K8s。
- K8s 适 pengguna 数十到上百台机器,生产级弹性伸缩。
# worker/Dockerfile
FROM python:3.12-slim
WORKDIR /app
# ① 依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# ② 代码
COPY crawler_worker.py .
ENTRYPOINT ["python", "crawler_worker.py"]requirements.txt
httpx==0.27.0
redis==5.0.1
elasticsearch==8.11.3version: "3.9"
services:
# ---------- 入口 & 调度 ----------
redis: &redis
image: redis:7
restart: unless-stopped
expose:
- "6379"
kafka:
image: wurstmeister/kafka
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
depends_on: [zookeeper]
expose:
- "9092"
zookeeper:
image: wurstmeister/zookeeper
expose:
- "2181"
# ---------- Worker ----------
worker:
build: ./worker
depends_on: [redis, kafka, elasticsearch]
environment:
REDIS_HOST: redis
KAFKA_BROKER: kafka:9092
ES_HOST: elasticsearch
deploy:
replicas: 5 # ← 这里直接控制实例数
restart_policy:
condition: on-failure
# 可选:让容器暴露 8000 给外部监控
expose:
- "8000"
# ---------- 负载均衡 ----------
nginx:
image: nginx:1.27
depends_on: [worker]
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
ports:
- "80:80"# 原始部署
docker-compose up -d
# 扩容到 10 个 worker
docker compose up -d --scale worker=10
docker compose up -d --scale会在同一台宿主机上根据replicas创建更多容器。
如果你使用 Swarm,改为:
docker stack deploy -c docker-compose.yml spider_pool
docker service scale spider_pool_worker=20 # 20 个 Worker注意:
replicas控制的是 容器数量,不必关心主机数量。- 若要在多台机器上跑 Compose,你需要把每台机器挂到同一个 Docker‑Swarm,然后用
docker stack deploy。
# 在所有服务器上执行
docker swarm init # 主节点
# 在其他节点上执行
docker swarm join --token <TOKEN> <MANAGER_IP>:2377docker‑stack.yml(与 Compose 同样的文件名)version: "3.9"
services:
worker:
image: mycrawler:latest
deploy:
replicas: 10 # 10 个 Worker
resources:
limits:
cpus: "1.0"
memory: 2G
environment:
REDIS_HOST: redis
KAFKA_BROKER: kafka:9092
ES_HOST: elasticsearch
depends_on: [redis, kafka, elasticsearch]# 部署堆栈
docker stack deploy -c docker-stack.yml spider_pool
# 只要你想扩容到 30 个节点
docker service scale spider_pool_worker=30Swarm 自动做服务发现与负载均衡(内部 DNS + 内置负载均衡)。
若想让外部访问可用端口,往nginx或 Traefik 添加ports。
| 文件 | 作用 |
|---|---|
deployment.yaml | 定义 Pod、镜像、环境变量 |
hpa.yaml | 自动根据 CPU/自定义指标扩容 |
service.yaml | 内部负载均衡(ClusterIP) |
ingress.yaml | 外部访问(Traefik / Nginx Ingress) |
deployment.yamlapiVersion: apps/v1
kind: Deployment
metadata:
name: spider-worker
spec:
replicas: 5 # 起始 5 个
selector:
matchLabels:
app: spider-worker
template:
metadata:
labels:
app: spider-worker
spec:
containers:
- name: worker
image: mycrawler:latest
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: KAFKA_BROKER
value: kafka.default.svc.cluster.local:9092
- name: ES_HOST
value: elasticsearch.default.svc.cluster.local
resources:
limits:
cpu: "1"
memory: 2Gihpa.yamlapiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: spider-worker-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: spider-worker
minReplicas: 3
maxReplicas: 30
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60部署:
kubectl apply -f deployment.yaml
kubectl apply -f hpa.yaml手动扩容(立即):
kubectl scale deployment spider-worker --replicas=20自动扩容:HPA 读取 CPU 利用率(或你自定义指标,例如
URL_QUEUE_LENGTH),当达到阈值时会自动增减 Pod。
适合 Compose/Swarm;在
nginx.conf里配置upstream指向spider-worker服务。
upstream spider-worker {
least_conn;
server spider-worker:8000;
server spider-worker:8000; # 你可以复制多次,或用变量
}
server {
listen 80;
location /task/ {
proxy_pass http://spider-worker;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}services:
traefik:
image: traefik:v3.1
command: --providers.docker=true --entrypoints.web.address=:80
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro给 Worker 加上标签:
spider-worker:
image: mycrawler:latest
deploy:
replicas: 10
labels:
- "traefik.http.services.spider-worker.loadbalancer.server.port=8000"
- "traefik.http.routers.spider.rule=PathPrefix(`/task/`)"Traefik 会自动把请求分发到所有 Worker 容器。
| 步骤 | 命令 | 说明 |
|---|---|---|
| 1️⃣ 准备多台机器 | docker-machine create --driver generic --generic-ssh-user ubuntu --generic-ip-address 192.168.1.2 myvm1 | 任何支持 Docker 的主机 |
| 2️⃣ 把主机加入 Swarm | docker swarm init on manager → docker swarm join-token worker on others | 生成 token |
| 3️⃣ 部署堆栈 | docker stack deploy -c docker-stack.yml spider_pool | 读 Compose 并做 service discovery |
| 4️⃣ 动态扩容 | docker service scale spider_pool_worker=30 | 只需修改 replicas |
注意:如果你在云里跑多台节点,记得把 Docker‑Swarm 的 overlay 网络 绑定到同一子网。
对于 K8s 生产环境,建议用 Cluster Autoscaler 自动扩容 VMs。
| 关键点 | 最佳实践 |
|---|---|
| 镜像化 | Dockerfile 只保留运行环境;镜像尺寸 ≤ 200 MB。 |
| 多副本 | replicas(Compose/Swarm)或 HPA(K8s)。 |
| 服务发现 | Compose 通过 depends_on;Swarm/ K8s 自带。 |
| 负载均衡 | Nginx/Traefik,least_conn 或 round_robin。 |
| 横向扩容 | docker compose up --scale worker=20 或 docker service scale。 |
| 监控 | Prometheus + Grafana,监控 crawler_requests_total。 |
一句话总结:把 Worker 换成 Docker 容器,用
replicas或 Swarm/K8s 自动扩容,Nginx/Traefik 负责把抓取任务均匀分发。这样,你就能在 几秒钟 内把节点数从 1 增到 50 或 100,几乎不需要停机或改代码。祝你部署顺利!
0
Discussion (0)
Learn how to style your text
Write your thoughts
No posts found.
Related Products

4.6
414 Reviews
$50
MIN. ACC BALANCE
1.0%* p.a. base return + up to 3.20% p.a. returns on your fixed plan riders
RATE OF RETURN
Up to 3.20% p.a. for the first S$200K
INTEREST CAP
No posts found.
Advertisement