{谷歌蜘蛛池搭建}
## 如何用 Docker 实现 Google “蜘蛛池”节点快速扩展
> **目标**
> 1️⃣ 把每个 **Worker**(爬虫引擎)放进 **容器**,
> 2️⃣ 用 **Docker‑Compose**、**Docker Swarm** 或 **Kubernetes** 让“Worker”按需水平扩容,
> 3️⃣ 让**Nginx/Traefik** 作为**负载均衡**把抓取任务分发给所有可用节点。
下面把三种常见方案拆成**步骤**+**代码**,你可以直接拷贝到自己的项目里跑。
---
## 1️⃣ 方案总览
| 方案 | 适用场景 | 关键技术 |
|------|----------|----------|
| **Docker‑Compose** | 单机 / 小型集群,快速原型 | `docker-compose.yml` + `replicas` |
| **Docker Swarm** | 需要多主机、服务发现 | `docker stack deploy` + `--replicas` |
| **Kubernetes** | 高可用、弹性扩容、丰富生态 | `kubectl scale` / `HorizontalPodAutoscaler` |
> **小结**:
> - **Compose** 适合**本地开发 / 单机**,最快上手。
> - **Swarm** 适合**几台服务器**,无需学习 K8s。
> - **K8s** 适 pengguna **数十到上百台机器**,生产级弹性伸缩。
---
## 2️⃣ Docker‑Compose:让 Worker 节点一键扩容
### 2.1 Dockerfile(Worker)
```dockerfile
# 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.3
```
### 2.2 docker‑compose.yml
```yaml
version: "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"
```
### 2.3 立即扩容
```bash
# 原始部署
docker-compose up -d
# 扩容到 10 个 worker
docker compose up -d --scale worker=10
```
> `docker compose up -d --scale` 会在**同一台宿主机**上根据 `replicas` 创建更多容器。
> 如果你使用 **Swarm**,改为:
```bash
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`。
---
## 2️⃣ Swarm 方案(几台服务器)
### 2.1 初始化 Swarm
```bash
# 在所有服务器上执行
docker swarm init # 主节点
# 在其他节点上执行
docker swarm join --token <TOKEN> <MANAGER_IP>:2377
```
### 2.2 `docker‑stack.yml`(与 Compose 同样的文件名)
```yaml
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]
```
### 2.3 部署 & 动态扩容
```bash
# 部署堆栈
docker stack deploy -c docker-stack.yml spider_pool
# 只要你想扩容到 30 个节点
docker service scale spider_pool_worker=30
```
> Swarm 自动做**服务发现**与**负载均衡**(内部 DNS + 内置负载均衡)。
> 若想让外部访问可用端口,往 `nginx` 或 **Traefik** 添加 `ports`。
---
## 3️⃣ Kubernetes 方案(生产级弹性伸容)
### 3.1 基础部署
| 文件 | 作用 |
|------|------|
| `deployment.yaml` | 定义 Pod、镜像、环境变量 |
| `hpa.yaml` | 自动根据 CPU/自定义指标扩容 |
| `service.yaml` | 内部负载均衡(ClusterIP) |
| `ingress.yaml` | 外部访问(Traefik / Nginx Ingress) |
#### `deployment.yaml`
```yaml
apiVersion: 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: 2Gi
```
#### `hpa.yaml`
```yaml
apiVersion: 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
```
> **部署**:
```bash
kubectl apply -f deployment.yaml
kubectl apply -f hpa.yaml
```
> **手动扩容**(立即):
```bash
kubectl scale deployment spider-worker --replicas=20
```
> **自动扩容**:HPA 读取 CPU 利用率(或你自定义指标,例如 `URL_QUEUE_LENGTH`),当达到阈值时会自动增减 Pod。
---
## 4️⃣ 负载均衡:把抓取任务分发给所有节点
### 4.1 Nginx
> 适合 Compose/Swarm;在 `nginx.conf` 里配置 `upstream` 指向 `spider-worker` 服务。
```nginx
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 "";
}
}
```
### 4.2 Traefik(现代化可自动服务发现)
```yaml
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 加上标签:
```yaml
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 容器。
---
## 5️⃣ 快速扩容操作流程(以 Swarm 为例)
| 步骤 | 命令 | 说明 |
|------|------|------|
| 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。
---
## 6️⃣ 关键点回顾
| 关键点 | 最佳实践 |
|--------|----------|
| **镜像化** | `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,几乎不需要停机或改代码。祝你部署顺利!
Google谷歌