<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://memex-server.memect.cn/docs-site/changelog</id>
    <title>Memex Server Blog</title>
    <updated>2026-07-03T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://memex-server.memect.cn/docs-site/changelog"/>
    <subtitle>Memex Server Blog</subtitle>
    <icon>https://memex-server.memect.cn/docs-site/img/favicon.ico</icon>
    <entry>
        <title type="html"><![CDATA[v0.2.68 — 孤儿 Traefik 路由自动回收]]></title>
        <id>https://memex-server.memect.cn/docs-site/changelog/v0-2-68</id>
        <link href="https://memex-server.memect.cn/docs-site/changelog/v0-2-68"/>
        <updated>2026-07-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[修复生产 Traefik 被上千僵尸路由文件拖垮、外部访问全部超时的问题。]]></summary>
        <content type="html"><![CDATA[<p>修复生产 Traefik 被上千僵尸路由文件拖垮、外部访问全部超时的问题。</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="问题背景">问题背景<a href="https://memex-server.memect.cn/docs-site/changelog/v0-2-68#%E9%97%AE%E9%A2%98%E8%83%8C%E6%99%AF" class="hash-link" aria-label="问题背景的直接链接" title="问题背景的直接链接">​</a></h2>
<p>生产 Traefik 一天内卡死 2 次，外部访问全部超时，系统基本不可用。根因：
<code>/data/memex/traefik-conf/</code> 累积 <strong>1119 个路由文件，其中 1065 个是僵尸</strong>
（预览进程早已死、路由文件残留）。Traefik file provider 每次文件变更就全量
reload 上千个 YAML，8668 entrypoint 监听 hang，外部请求全超时。</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="僵尸来源">僵尸来源<a href="https://memex-server.memect.cn/docs-site/changelog/v0-2-68#%E5%83%B5%E5%B0%B8%E6%9D%A5%E6%BA%90" class="hash-link" aria-label="僵尸来源的直接链接" title="僵尸来源的直接链接">​</a></h2>
<p>正常 <code>stop_serve</code> 会删路由，但容器重建杀进程、OOM、崩溃等异常路径不走
<code>stop_serve</code>，路由文件就永久留下了。</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="修复内容">修复内容<a href="https://memex-server.memect.cn/docs-site/changelog/v0-2-68#%E4%BF%AE%E5%A4%8D%E5%86%85%E5%AE%B9" class="hash-link" aria-label="修复内容的直接链接" title="修复内容的直接链接">​</a></h2>
<p>新增 <code>reap_orphan_routes()</code>：扫路由文件，用端口 HTTP 探活判定预览死活，
删掉端口无响应的孤儿路由。挂到 <code>preview_patrol_loop</code>（每 300s），持续把
路由数收敛到实际运行的预览数。</p>
<p><strong>生产处置</strong>：立即批量清理 1065 个僵尸路由（1119→55），Traefik reload
压力锐减，外部访问恢复（探活稳定 0.3-0.5s）。</p>]]></content>
        <category label="fix" term="fix"/>
        <category label="traefik" term="traefik"/>
        <category label="稳定性" term="稳定性"/>
    </entry>
    <entry>
        <title type="html"><![CDATA[v0.2.67 — 架构改造大版本]]></title>
        <id>https://memex-server.memect.cn/docs-site/changelog/v0-2-67</id>
        <link href="https://memex-server.memect.cn/docs-site/changelog/v0-2-67"/>
        <updated>2026-07-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[12 个架构改造 commit，涵盖分层修复、连接池化、SQLAlchemy Core 迁移、348 个测试防护网。]]></summary>
        <content type="html"><![CDATA[<p>12 个架构改造 commit，涵盖分层修复、连接池化、SQLAlchemy Core 迁移、348 个测试防护网。</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="分层修复">分层修复<a href="https://memex-server.memect.cn/docs-site/changelog/v0-2-67#%E5%88%86%E5%B1%82%E4%BF%AE%E5%A4%8D" class="hash-link" aria-label="分层修复的直接链接" title="分层修复的直接链接">​</a></h2>
<ul>
<li>消除 core→api 反向依赖，新增 <code>core/dispatcher.py</code> Dispatcher protocol</li>
<li><code>task_manager.py</code> 三拆：<code>db_adapter.py</code> + <code>db_schema.py</code> + 业务方法</li>
<li><code>api/sse.py</code> 瘦身 1466→94 行，阶段编排状态机下沉为 <code>core/phase_runner.py</code></li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="数据库层">数据库层<a href="https://memex-server.memect.cn/docs-site/changelog/v0-2-67#%E6%95%B0%E6%8D%AE%E5%BA%93%E5%B1%82" class="hash-link" aria-label="数据库层的直接链接" title="数据库层的直接链接">​</a></h2>
<ul>
<li>修生产连接饱和（"FATAL: too many clients already"）：改为进程级共享 SQLAlchemy Engine（QueuePool），16 线程并发只占 3 个连接（旧代码 16 个）</li>
<li>删除全部手写方言转换规则</li>
<li>新增 <code>schema_migrations</code> 表，补 Postgres 此前不执行 migrations 的缺陷</li>
</ul>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="可观测性">可观测性<a href="https://memex-server.memect.cn/docs-site/changelog/v0-2-67#%E5%8F%AF%E8%A7%82%E6%B5%8B%E6%80%A7" class="hash-link" aria-label="可观测性的直接链接" title="可观测性的直接链接">​</a></h2>
<p>每次 job 启动生成 <code>job_run_id</code>（12 hex），<code>server.log</code> 每行携带 <code>[run:xxx]</code>。</p>
<h2 class="anchor anchorWithStickyNavbar_LWe7" id="测试抓出的-3-个生产-bug">测试抓出的 3 个生产 bug<a href="https://memex-server.memect.cn/docs-site/changelog/v0-2-67#%E6%B5%8B%E8%AF%95%E6%8A%93%E5%87%BA%E7%9A%84-3-%E4%B8%AA%E7%94%9F%E4%BA%A7-bug" class="hash-link" aria-label="测试抓出的 3 个生产 bug的直接链接" title="测试抓出的 3 个生产 bug的直接链接">​</a></h2>
<ol>
<li><code>sweep_wedged_running</code> 产物检查被 except 吞掉 → 误杀保护从未生效</li>
<li><code>run_migrations</code> 在 Postgres dict 行上 <code>row[0]</code> KeyError → PG 库二次启动崩</li>
<li>SQLite Core 路径默认值列落 NULL → <code>api_tokens.revoked</code> 为 NULL 导致认证失败</li>
</ol>]]></content>
        <category label="refactor" term="refactor"/>
        <category label="数据库" term="数据库"/>
        <category label="架构" term="架构"/>
        <category label="测试" term="测试"/>
    </entry>
</feed>