feat(proxy): 架构与算法优化二轮——sense 运行时单例激活 T-X3、打码密钥泄漏修复、账本热路径 2.4x
- gateway/proxy/routes.py:sense 运行时(SenseStore+Grader+晋升表)按配置单例化, 原每请求重建导致:每请求跑全量 DDL、重读工件文件,且 T-X3 60s 决策缓存随 Grader 丢弃、命中率恒为 0(本轮最大收益,激活既有已测组件); T1 审计抽样修复原 NameError×3 被 except 吞掉(load_config/get_review/request_id 均未定义、§9.4 从未入队)——request_id 上提、review 队列经 review_getter 注入 (api.py 反向依赖解除)、sample_rate 走 load_config - gateway/model_pool.py:新增 usable_entries() 未打码内通道;routes 的降级链/ 预算降档/能力位重定向/档位映射四处改走该通道——修复打码 api_key 流入上游 Bearer 头导致带密钥条目重定向必 401 的隐性缺陷(HTTP 管理面仍用打码 list()) - gateway/proxy/ledger.py + billing.py:共享持久连接(原每操作新建,全链路 每请求 3-5 次 connect)+ 日重置 UPDATE 每实例每日一次短路(原每请求全表扫描 抢写锁);check_and_count A/B 0.75→0.31 ms/op(2.4x);新增 usage_stats() SQL 聚合,/admin/stats 从 list_usage(limit=50 万) Python 四遍扫描改为下推聚合 (微基准 ~28x,随流水线性扩大) - gateway/sense/grader.py:决策留痕 insert_decision 移入 asyncio.to_thread (原同步 sqlite 写直接跑在事件循环线程,高并发阻塞网关;与观察写批量队列同等保护) - 全量 474 项两轮复核全绿(基线 474)
This commit is contained in:
+25
-9
@@ -8,8 +8,8 @@
|
||||
|
||||
工程纪律:
|
||||
- D-P1 毫元整数,本模块不做任何浮点运算(元换算只发生在入口参数转换)。
|
||||
- D-P10:同步实现 + 全局锁每操作连接(ReviewQueue 模式),异步调用方经
|
||||
asyncio.to_thread 包装;WAL 模式(§3)。
|
||||
- D-P10:同步实现 + 全局锁串行访问(ReviewQueue 模式;2026-09 起复用单条
|
||||
持久连接,语义不变),异步调用方经 asyncio.to_thread 包装;WAL 模式(§3)。
|
||||
- 全部数据库访问使用占位符参数化语句,语句为常量,零拼接。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
@@ -74,6 +74,8 @@ class Ledger(BillingMixin):
|
||||
self.db_path = Path(db_path)
|
||||
self.db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
self._lock = threading.Lock()
|
||||
self._conn: Optional[sqlite3.Connection] = None
|
||||
self._reset_date: Optional[str] = None # 日重置短路标记(2026-09 优化)
|
||||
self._init_db()
|
||||
|
||||
# ---------- 初始化 ----------
|
||||
@@ -83,9 +85,17 @@ class Ledger(BillingMixin):
|
||||
return cls(db_path)
|
||||
|
||||
def _connect(self) -> sqlite3.Connection:
|
||||
conn = sqlite3.connect(self.db_path, check_same_thread=False)
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
"""共享持久连接(2026-09 优化)。
|
||||
|
||||
所有操作本就串行于 self._lock 之下,复用单连接语义与逐操作新建等价,
|
||||
省去每请求 3-5 次 sqlite3.connect(Windows 上开销显著);
|
||||
`with conn` 只做提交/回滚不关闭,连接持续可用。
|
||||
"""
|
||||
if self._conn is None:
|
||||
conn = sqlite3.connect(self.db_path, check_same_thread=False)
|
||||
conn.row_factory = sqlite3.Row
|
||||
self._conn = conn
|
||||
return self._conn
|
||||
|
||||
def _init_db(self) -> None:
|
||||
with self._lock, self._connect() as conn:
|
||||
@@ -168,12 +178,18 @@ class Ledger(BillingMixin):
|
||||
|
||||
# ---------- 日限额 ----------
|
||||
def check_and_count(self, key_id: int, student_id: int, now: float) -> bool:
|
||||
"""日请求限额双检:跨日重置(注入日期)+ 原子计数;超限返回 False(429)。"""
|
||||
"""日请求限额双检:跨日重置(注入日期)+ 原子计数;超限返回 False(429)。
|
||||
|
||||
2026-09 优化:重置 UPDATE 每实例每日只执行一次(原每请求全表扫
|
||||
students 并抢写锁);单进程部署(D-P9)下语义等价。
|
||||
"""
|
||||
today = _today(now)
|
||||
with self._lock, self._connect() as conn:
|
||||
conn.execute(
|
||||
"UPDATE students SET spent_today_milli = 0, spent_date = ?"
|
||||
" WHERE spent_date IS NOT ?", (today, today))
|
||||
if self._reset_date != today:
|
||||
conn.execute(
|
||||
"UPDATE students SET spent_today_milli = 0, spent_date = ?"
|
||||
" WHERE spent_date IS NOT ?", (today, today))
|
||||
self._reset_date = today
|
||||
row = conn.execute(
|
||||
"SELECT req_today, req_date, day_cap_req FROM proxy_keys"
|
||||
" WHERE id = ?", (key_id,)).fetchone()
|
||||
|
||||
Reference in New Issue
Block a user