你有没有遇到过这样的情况:写了个监控程序,连着公司内网的 WebSocket 接口,结果中午断网五分钟,整个服务就卡死不动了?或者写的爬虫刚连上 API,对方服务器抖了一下,请求直接报错退出——根本没机会重试。
自动重连不是加个 while 就完事
很多人第一反应是写个死循环:while not connected: connect()。但这样容易把 CPU 跑满,还可能被目标服务限流甚至拉黑。真正的自动重连得考虑三件事:失败检测、退避策略、连接状态管理。
ref="/tag/136/" style="color:#3D6345;font-weight:bold;">Python 示例:带指数退避的 TCP 连接重试
假设你在写一个和 IoT 设备通信的客户端,用 socket 连接它的 TCP 端口:
import socket
import time
import random
def connect_with_retry(host, port, max_retries=5):
for i in range(max_retries):
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(3)
s.connect((host, port))
print(f"✅ 第 {i+1} 次连接成功")
return s
except (socket.timeout, ConnectionRefusedError, OSError) as e:
print(f"❌ 第 {i+1} 次连接失败:{e}")
if i < max_retries - 1:
# 指数退避 + 随机抖动,避免雪崩式重连
delay = min(2 ** i + random.uniform(0, 1), 30)
time.sleep(delay)
raise Exception("重连全部失败,请检查网络或目标地址")
# 使用示例
try:
sock = connect_with_retry("192.168.1.100", 8080)
# 后续通信...
except Exception as e:
print(e)JavaScript(浏览器端)WebSocket 自动重连
网页里用 WebSocket 做实时聊天,一断网就白屏?试试这个轻量封装:
class ReconnectWebSocket {
constructor(url, options = {}) {
this.url = url;
this.options = options;
this.reconnectDelay = 1000; // 初始延迟 1s
this.maxDelay = 30000; // 最大延迟 30s
this.ws = null;
this.shouldReconnect = true;
this.connect();
}
connect() {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
console.log("🟢 WebSocket 已连接");
this.reconnectDelay = 1000; // 成功后重置延迟
};
this.ws.onclose = () => {
if (this.shouldReconnect) {
console.log(`🔴 连接关闭,${this.reconnectDelay}ms 后重试...`);
setTimeout(() => this.connect(), this.reconnectDelay);
this.reconnectDelay = Math.min(this.reconnectDelay * 1.5, this.maxDelay);
}
};
this.ws.onerror = (err) => {
console.error("⚠️ WebSocket 错误:", err);
};
}
send(data) {
if (this.ws?.readyState === WebSocket.OPEN) {
this.ws.send(data);
}
}
close() {
this.shouldReconnect = false;
this.ws?.close();
}
}
// 使用
const ws = new ReconnectWebSocket("wss://api.example.com/chat");关键细节别漏掉
• 心跳保活:长连接不发数据时,记得定时发 ping/ping 或空消息,不然中间防火墙/代理可能主动断开;
• 重复连接防护:重连逻辑里加个标志位,防止 onclose 触发多次 connect;
• 业务层兜底:比如重连期间用户发的消息,要缓存到队列,等恢复后再 flush;
• 日志分级:首次失败打 info,连续 3 次失败打 warning,5 次以上打 error,方便排查。
自动重连不是炫技,而是让程序在真实网络里活得更久一点。多试几次,把 delay 调成你家 Wi-Fi 断线再恢复的真实时间,比啥文档都管用。