本文目录导读:

在脚本中处理HTTP请求的超时,主要有以下几种常见方式,具体实现取决于你使用的语言或工具:
通用的超时处理策略
重试机制(指数退避)
import time
import requests
def request_with_retry(url, max_retries=3, timeout=5):
for attempt in range(max_retries):
try:
response = requests.get(url, timeout=timeout)
response.raise_for_status()
return response
except (requests.Timeout, requests.ConnectionError) as e:
if attempt == max_retries - 1:
raise e
# 指数退避等待
time.sleep(2 ** attempt)
设置合理的超时时间
# 连接超时 + 读取超时 response = requests.get(url, timeout=(3.05, 27)) # (connect_timeout, read_timeout)
不同语言的实现示例
Python (requests库)
import requests
from requests.exceptions import Timeout, ConnectionError
try:
response = requests.get(
'https://api.example.com',
timeout=5, # 总超时5秒
headers={'User-Agent': 'Mozilla/5.0'}
)
except Timeout:
print("请求超时")
except ConnectionError:
print("连接错误")
Node.js (axios)
const axios = require('axios');
async function fetchWithTimeout(url) {
try {
const response = await axios.get(url, {
timeout: 5000, // 5秒超时
timeoutErrorMessage: '请求超时'
});
return response.data;
} catch (error) {
if (error.code === 'ECONNABORTED') {
console.error('请求超时');
} else {
console.error('其他错误:', error.message);
}
}
}
Shell (curl)
#!/bin/bash
# 设置连接超时和总超时
curl --connect-timeout 5 --max-time 10 \
--retry 3 \
--retry-delay 2 \
"https://api.example.com"
# 检查退出码
if [ $? -eq 28 ]; then
echo "操作超时"
fi
进阶超时处理模式
使用信号机制(Linux/Unix)
import signal
import requests
class TimeoutError(Exception):
pass
def handler(signum, frame):
raise TimeoutError("请求超时")
def fetch_with_signal_timeout(url, timeout=5):
signal.signal(signal.SIGALRM, handler)
signal.alarm(timeout) # 设置闹钟
try:
response = requests.get(url)
return response
except TimeoutError:
print("请求超时")
finally:
signal.alarm(0) # 取消闹钟
异步超时处理 (asyncio)
import asyncio
import aiohttp
async def fetch_with_timeout(url, timeout=5):
async with aiohttp.ClientSession() as session:
try:
async with session.get(url, timeout=aiohttp.ClientTimeout(total=timeout)) as response:
return await response.text()
except asyncio.TimeoutError:
print("异步请求超时")
except aiohttp.ClientError as e:
print(f"客户端错误: {e}")
最佳实践建议
超时设置原则
- 连接超时:3-5秒(短连接快速失败)
- 读取超时:根据API响应时间设定,通常10-30秒
- 总超时:不超过30秒(除非特殊场景)
错误处理流程
def robust_http_request(url, retries=3):
"""健壮的HTTP请求处理"""
for i in range(retries):
try:
resp = requests.get(url, timeout=10)
resp.raise_for_status()
return resp.json()
except requests.Timeout:
if i == retries - 1:
log_and_alert(f"请求超时,已重试{retries}次")
return None
print(f"第{i+1}次重试:连接超时")
except requests.ConnectionError:
return None # 网络错误不重试
except requests.HTTPError as e:
if e.response.status_code == 429: # 限流
time.sleep(10)
else:
return None
return None
常见问题及解决方案
| 问题 | 解决方案 |
|---|---|
| DNS解析慢 | 设置连接超时 + 使用DNS缓存 |
| 服务器响应慢 | 设置读取超时 + 分块处理 |
| 网络不稳定 | 配合重试机制 + 指数退避 |
| 批量请求卡住 | 使用协程并发 + 每个请求独立超时 |
选择哪种方式取决于你的脚本运行环境、并发需求和错误容忍度,对于关键业务,建议同时使用超时、重试和熔断机制。