feat(tunnel): 引入 aether-hub 帧路由器,支持多 worker 共享 tunnel 连接

新增 Rust 实现的 aether-hub 服务,作为 Docker 容器内部 WebSocket 帧路由器,
解决多 Gunicorn worker 进程间 tunnel 连接隔离问题。

主要改动:
- 新增 aether-hub Rust 项目,实现 proxy/worker 双向帧路由与 stream_id 重映射
- 新增 HubConnectionManager/HubTunnelTransport,worker 通过 Hub 转发 tunnel 帧
- 新增 create_tunnel_transport 工厂函数,按运行环境自动选择 Hub 或直连模式
- 新增 NODE_STATUS 广播机制,Hub 实时通知所有 worker 节点连接状态变化
- CI/CD 新增 build-hub job,Dockerfile 集成 Hub 二进制,deploy.sh 适配 Hub 构建
- 默认 GUNICORN_WORKERS 从 4 降为 2
This commit is contained in:
fawney19
2026-03-02 02:43:14 +08:00
parent 97d42703da
commit 039a18c243
30 changed files with 3728 additions and 75 deletions

View File

@@ -78,14 +78,22 @@ async def _on_startup() -> None:
from src.config import config
from src.services.proxy_node.health_scheduler import get_proxy_node_health_scheduler
from src.services.proxy_node.hub_config import get_hub_config
from src.utils.task_coordinator import StartupTaskCoordinator
logger = logging.getLogger("aether.modules.proxy_nodes")
hub_enabled = get_hub_config().enabled
if config.worker_processes > 1:
if config.worker_processes > 1 and not hub_enabled:
logger.warning(
"检测到 WEB_CONCURRENCY={}。Proxy tunnel 连接是进程内资源,"
"多 worker 场景可能出现节点显示 ONLINE 但当前 worker 无可用 tunnel 的情况。",
"多 worker 场景可能出现节点显示 ONLINE 但当前 worker 无可用 tunnel 的情况。"
"建议设置 GUNICORN_WORKERS/WEB_CONCURRENCY=1。",
config.worker_processes,
)
elif config.worker_processes > 1 and hub_enabled:
logger.info(
"检测到 WEB_CONCURRENCY={}Hub 模式已启用,允许多 worker 共享 tunnel。",
config.worker_processes,
)
@@ -111,14 +119,22 @@ async def _on_shutdown() -> None:
import logging
from src.services.proxy_node.health_scheduler import get_proxy_node_health_scheduler
from src.services.proxy_node.tunnel_manager import get_tunnel_manager
from src.services.proxy_node.hub_config import get_hub_config
from src.utils.task_coordinator import StartupTaskCoordinator
logger = logging.getLogger("aether.modules.proxy_nodes")
# 先向所有 tunnel 连接发送 GoAway让 proxy 端立即重连到其他 worker
manager = get_tunnel_manager()
await manager.shutdown_all()
hub_enabled = get_hub_config().enabled
if hub_enabled:
from src.services.proxy_node.hub_transport import shutdown_hub_connection_manager
await shutdown_hub_connection_manager()
else:
# 先向所有 tunnel 连接发送 GoAway让 proxy 端立即重连到其他 worker
from src.services.proxy_node.tunnel_manager import get_tunnel_manager
manager = get_tunnel_manager()
await manager.shutdown_all()
from src.clients import get_redis_client