在捕获到致命错误时,调用 self.close() 彻底关闭连接
This commit is contained in:
@@ -8,36 +8,41 @@ logging.getLogger('eventlet.greenio').setLevel(logging.CRITICAL)
|
||||
# 进行猴子补丁操作
|
||||
eventlet.monkey_patch()
|
||||
|
||||
# 配置 eventlet hub 以更优雅地处理所有错误
|
||||
# 配置 eventlet 以更优雅地处理错误,避免疯狂报错
|
||||
try:
|
||||
from eventlet import hubs
|
||||
import eventlet
|
||||
import traceback
|
||||
|
||||
# 只修改存在的属性,避免引用错误
|
||||
if hasattr(hubs, 'trampoline'):
|
||||
# 保存原始的trampoline方法
|
||||
original_trampoline = hubs.trampoline
|
||||
# 1. 首先,禁用 eventlet 的调试日志,减少输出
|
||||
import logging
|
||||
logging.getLogger('eventlet').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('socketio').setLevel(logging.CRITICAL)
|
||||
logging.getLogger('werkzeug').setLevel(logging.CRITICAL)
|
||||
|
||||
def custom_trampoline(fd, read=False, write=False, timeout=None, timeout_exc=None):
|
||||
try:
|
||||
return original_trampoline(fd, read, write, timeout, timeout_exc)
|
||||
except Exception as e:
|
||||
# 捕获 trampoline 方法中所有异常
|
||||
print(f"[Eventlet Trampoline Error] {type(e).__name__}: {e}")
|
||||
print(f"[Params] fd: {fd}, read: {read}, write: {write}, timeout: {timeout}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 返回 None 继续运行,不往外传播错误
|
||||
return None
|
||||
# 2. 配置 eventlet 只记录严重错误
|
||||
eventlet.debug.hub_prevent_multiple_readers(False)
|
||||
|
||||
# 替换原始方法
|
||||
hubs.trampoline = custom_trampoline
|
||||
# 3. 避免重复打印相同错误的机制
|
||||
seen_errors = set()
|
||||
max_error_logs = 5 # 每个错误最多打印5次
|
||||
error_counts = {}
|
||||
|
||||
# 同样处理 greenio 模块的所有相关方法,捕获所有异常
|
||||
def is_duplicate_error(e):
|
||||
"""检查是否为重复错误"""
|
||||
error_key = f"{type(e).__name__}: {e}"
|
||||
if error_key in seen_errors:
|
||||
error_counts[error_key] = error_counts.get(error_key, 0) + 1
|
||||
if error_counts[error_key] > max_error_logs:
|
||||
return True
|
||||
else:
|
||||
seen_errors.add(error_key)
|
||||
error_counts[error_key] = 1
|
||||
return False
|
||||
|
||||
# 4. 只修改关键的 greenio 方法,确保在致命错误时彻底关闭连接
|
||||
from eventlet import greenio
|
||||
|
||||
# 保存并替换原始的 greenio 方法(只修改存在的方法)
|
||||
# 保存并替换原始的 greenio 方法
|
||||
if hasattr(greenio.base.GreenSocket, '_recv_loop'):
|
||||
original_recv_loop = greenio.base.GreenSocket._recv_loop
|
||||
|
||||
@@ -45,11 +50,15 @@ try:
|
||||
try:
|
||||
return original_recv_loop(self, recv_func, recv_args, *args, **kwargs)
|
||||
except Exception as e:
|
||||
# 捕获所有 IO 操作异常
|
||||
print(f"[Eventlet IO Error] _recv_loop: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 返回空字节串继续运行
|
||||
if not is_duplicate_error(e):
|
||||
print(f"[Eventlet IO Error] _recv_loop: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 彻底关闭连接,不再继续处理
|
||||
try:
|
||||
self.close()
|
||||
except Exception:
|
||||
pass
|
||||
return b''
|
||||
|
||||
greenio.base.GreenSocket._recv_loop = custom_recv_loop
|
||||
@@ -61,11 +70,15 @@ try:
|
||||
try:
|
||||
return original_recv_into(self, buffer, nbytes, flags)
|
||||
except Exception as e:
|
||||
# 捕获所有 IO 操作异常
|
||||
print(f"[Eventlet IO Error] recv_into: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 返回 0 继续运行
|
||||
if not is_duplicate_error(e):
|
||||
print(f"[Eventlet IO Error] recv_into: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 彻底关闭连接,不再继续处理
|
||||
try:
|
||||
self.close()
|
||||
except Exception:
|
||||
pass
|
||||
return 0
|
||||
|
||||
greenio.base.GreenSocket.recv_into = custom_recv_into
|
||||
@@ -77,11 +90,15 @@ try:
|
||||
try:
|
||||
return original_send_loop(self, send_func, data, *args, **kwargs)
|
||||
except Exception as e:
|
||||
# 捕获所有 IO 操作异常
|
||||
print(f"[Eventlet IO Error] _send_loop: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 返回 0 继续运行
|
||||
if not is_duplicate_error(e):
|
||||
print(f"[Eventlet IO Error] _send_loop: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 彻底关闭连接,不再继续处理
|
||||
try:
|
||||
self.close()
|
||||
except Exception:
|
||||
pass
|
||||
return 0
|
||||
|
||||
greenio.base.GreenSocket._send_loop = custom_send_loop
|
||||
@@ -93,16 +110,20 @@ try:
|
||||
try:
|
||||
return original_send(self, data, flags)
|
||||
except Exception as e:
|
||||
# 捕获所有 IO 操作异常
|
||||
print(f"[Eventlet IO Error] send: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 返回 0 继续运行
|
||||
if not is_duplicate_error(e):
|
||||
print(f"[Eventlet IO Error] send: {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 彻底关闭连接,不再继续处理
|
||||
try:
|
||||
self.close()
|
||||
except Exception:
|
||||
pass
|
||||
return 0
|
||||
|
||||
greenio.base.GreenSocket.send = custom_send
|
||||
|
||||
# 处理 WSGI 中的所有错误
|
||||
# 5. 处理 WSGI 中的错误,确保彻底清理
|
||||
try:
|
||||
import eventlet.wsgi
|
||||
|
||||
@@ -113,12 +134,14 @@ try:
|
||||
try:
|
||||
return original_wsgi_handle_one_request(self)
|
||||
except Exception as e:
|
||||
# 捕获 WSGI 请求处理中的所有异常
|
||||
print(f"[Eventlet WSGI Request Error] {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 清理连接状态并返回,不往外传播错误
|
||||
if not is_duplicate_error(e):
|
||||
print(f"[Eventlet WSGI Request Error] {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 彻底清理连接,不再继续
|
||||
try:
|
||||
self.rfile.close()
|
||||
self.wfile.close()
|
||||
self.finish()
|
||||
except Exception:
|
||||
pass
|
||||
@@ -133,12 +156,14 @@ try:
|
||||
try:
|
||||
return original_wsgi_handle_one_response(self)
|
||||
except Exception as e:
|
||||
# 捕获 WSGI 响应处理中的所有异常
|
||||
print(f"[Eventlet WSGI Response Error] {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 清理连接状态并返回,不往外传播错误
|
||||
if not is_duplicate_error(e):
|
||||
print(f"[Eventlet WSGI Response Error] {type(e).__name__}: {e}")
|
||||
print("[Traceback]")
|
||||
traceback.print_exc()
|
||||
# 彻底清理连接,不再继续
|
||||
try:
|
||||
self.rfile.close()
|
||||
self.wfile.close()
|
||||
self.finish()
|
||||
except Exception:
|
||||
pass
|
||||
@@ -149,7 +174,7 @@ try:
|
||||
# 如果修改失败,忽略错误
|
||||
print(f"[WSGI Patch Error] {e}")
|
||||
|
||||
print("[Eventlet Error Handling] Eventlet errors will be caught and printed, not raised")
|
||||
print("[Eventlet Error Handling] Configured to handle errors gracefully, avoiding duplicate logs")
|
||||
except Exception as e:
|
||||
# 如果修改失败,打印错误但继续运行
|
||||
print(f"[Eventlet Patch Initialization Error] {e}")
|
||||
|
||||
Reference in New Issue
Block a user