refactor: 代理节点架构重构与功能增强

aether-proxy:
- 重构 main.rs,拆分为 app/state/hardware/net 模块
- setup.rs 拆分为 setup/tui.rs + setup/service.rs,支持 systemd 服务管理子命令
- 新增 delegate 端点,支持后端通过代理节点转发请求而非传统 CONNECT 代理
- 注册时上报硬件信息(CPU/内存/fd_limit)和估算最大并发数
- 心跳上报活跃连接数,支持远程下发 node_name 配置
- HTTP 转发时剥离 X-Forwarded-* 等敏感头部
- 切换到 rustls-tls,降低日志级别减少噪音

后端:
- 从 http_client.py 提取代理相关逻辑至 proxy_node/resolver.py
- 从 routes.py 提取业务逻辑至 proxy_node/service.py
- handler 支持 delegate 模式(通过代理节点 HTTP 端点转发而非 CONNECT 隧道)
- ProxyNode 模型新增 hardware_info 和 estimated_max_concurrency 字段

前端:
- 新增 HardwareTooltip 组件展示节点硬件信息
- 远程配置支持下发 node_name
This commit is contained in:
fawney19
2026-02-08 13:33:08 +08:00
parent 254d30d32d
commit 519ad67eb1
44 changed files with 3339 additions and 1709 deletions

View File

@@ -0,0 +1,60 @@
"""Add hardware_info and estimated_max_concurrency to proxy_nodes
Revision ID: 5c6d7e8f9a0b
Revises: 4b5c6d7e8f9a
Create Date: 2026-02-08 12:00:00.000000
"""
from __future__ import annotations
from collections.abc import Sequence
import sqlalchemy as sa
from sqlalchemy import inspect
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "5c6d7e8f9a0b"
down_revision: str | None = "4b5c6d7e8f9a"
branch_labels: str | Sequence[str] | None = None
depends_on: str | Sequence[str] | None = None
def column_exists(table_name: str, column_name: str) -> bool:
bind = op.get_bind()
inspector = inspect(bind)
columns = [c["name"] for c in inspector.get_columns(table_name)]
return column_name in columns
def upgrade() -> None:
if not column_exists("proxy_nodes", "hardware_info"):
op.add_column(
"proxy_nodes",
sa.Column(
"hardware_info",
sa.JSON(),
nullable=True,
comment="硬件信息 (cpu_cores, total_memory_mb, os_info, fd_limit, ...)",
),
)
if not column_exists("proxy_nodes", "estimated_max_concurrency"):
op.add_column(
"proxy_nodes",
sa.Column(
"estimated_max_concurrency",
sa.Integer(),
nullable=True,
comment="基于硬件估算的最大并发连接数",
),
)
def downgrade() -> None:
if column_exists("proxy_nodes", "estimated_max_concurrency"):
op.drop_column("proxy_nodes", "estimated_max_concurrency")
if column_exists("proxy_nodes", "hardware_info"):
op.drop_column("proxy_nodes", "hardware_info")