还记得我第一次做大规模爬虫项目的时候,用的是一台“肌肉型”的服务器。配置不低,爬个小站点也挺顺溜。但只要遇上流量高峰,几百万的任务排队,机器就跟塞车一样卡死。那时候我才意识到:单机再强,也有极限。
后来我想过加几台机器固定跑,但很快发现——大多数时间根本用不到,CPU 一直 20%-30%,钱花了,机器却在发呆。高峰顶不住,低谷浪费钱,这就是第一个大坑。
瓶颈越来越明显
那段时间,我们的采集项目有几个大问题:
- 任务堆积:高峰时延迟长得离谱,平均一个请求要等 120 秒。
- 失败率高:代理资源堆在一起用,命中率低,经常被封,失败率能到 20%+。
- 成本失控:为了应付高峰,只能加机器,结果每月账单涨得飞快。
说白了,我是在用“笨办法”堆钱解决问题。
转折点:搬上 Kubernetes
有一次,业务又要搞一次“临时大促采集”,流量高得离谱。我盯着服务器的监控图,CPU 飙满,内存溢出,爬虫进程死掉。那一刻我想:不行,必须换个思路。
于是我把爬虫搬上了 Kubernetes,思路就是:
- 用 HPA(Horizontal Pod Autoscaler) 自动伸缩,流量来了就加 Pod,流量走了就缩回去。
- 每个 Pod 配自己的一份 代理池(我用的是 爬虫代理),避免所有实例抢一个代理资源。
- 任务丢进 Redis 队列,Pod 来消费,扩缩容的时候不会丢任务。
这算是我的“第二阶段重构”。
代码片段分享
当时改造后的爬虫核心逻辑很简单:
Python 爬虫(接入代理)
import requests
from lxml import etree
# ====== 亿牛云爬虫代理配置 ======
proxy_host = "proxy.16yun.cn"
proxy_port = "3100"
proxy_user = "16YUN"
proxy_pass = "16IP"
proxy_meta = f"http://{proxy_user}:{proxy_pass}@{proxy_host}:{proxy_port}"
proxies = {
"http": proxy_meta,
"https": proxy_meta,
}
def fetch_page(url):
headers = {
"User-Agent": "Mozilla/5.0 (K8s-Crawler/1.0)"}
resp = requests.get(url, headers=headers, proxies=proxies, timeout=10)
html = etree.HTML(resp.text)
title = html.xpath("//title/text()")
return title[0] if title else "N/A"
if __name__ == "__main__":
print("抓取结果:", fetch_page("https://example.com"))
Kubernetes 部署 + HPA
apiVersion: apps/v1
kind: Deployment
metadata:
name: crawler-deployment
spec:
replicas: 2
selector:
matchLabels:
app: crawler
template:
metadata:
labels:
app: crawler
spec:
containers:
- name: crawler
image: myregistry/crawler:latest # 打包好的爬虫镜像
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "500m"
memory: "512Mi"
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: crawler-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: crawler-deployment
minReplicas: 2
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
这个配置让爬虫变得“聪明”了:CPU 高到 60% 时,K8s 自动拉 Pod;任务量下去,Pod 会缩回去。
压测的惊喜
我跑了一次 1000 并发 URL 压测,结果让我很惊讶:
指标 | 固定 5 节点 | K8s 弹性伸缩(2~20 Pod) |
---|---|---|
平均响应时间 | 110s | 30s |
峰值 QPS | 80 | 280 |
代理封禁率 | 18% | 6% |
那种感觉就像:以前开的是一辆小货车,载重一超就趴窝;现在换成自动调度的货运车队,来了多少货就派多少车。
最终的收获
经过这次改造,我学到了三点:
- 性能不只是多加机器,关键在于弹性和调度。
- 代理隔离很重要,不然再好的集群也会被封杀拖垮。
- 成本可控才是关键,K8s 让我月账单省了 30% 以上。
对比一开始那台“肌肉单机”,现在的架构更像是一个会自动呼吸的系统,高峰不慌,低谷不浪费。
回头看,这就是爬虫项目的进化史:
单机 → 固定集群 → Kubernetes 弹性集群。
每一步都有坑,但每一步也让系统更稳、更快、更省钱。