脚本中HTTP请求如何处理超时

wen 实用脚本 1

本文目录导读:

脚本中HTTP请求如何处理超时

  1. 通用的超时处理策略
  2. 不同语言的实现示例
  3. 进阶超时处理模式
  4. 最佳实践建议
  5. 常见问题及解决方案

在脚本中处理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缓存
服务器响应慢 设置读取超时 + 分块处理
网络不稳定 配合重试机制 + 指数退避
批量请求卡住 使用协程并发 + 每个请求独立超时

选择哪种方式取决于你的脚本运行环境、并发需求和错误容忍度,对于关键业务,建议同时使用超时、重试和熔断机制。

抱歉,评论功能暂时关闭!