原来的 JudgeServer 按核数起 gunicorn worker、每份提交再按核数开进程池,空闲内存跟着核数走 (2 核 52MB、16 核 305MB)。换成 go-judge 后空闲 16MB,同一批提交判题中 80–100MB(原来约 370MB)。 go-judge 只管在沙箱里跑命令,编译、逐点运行、比对输出、定状态码搬到 judge/sandbox.ts, 口径逐条照搬 JudgeServer,出参形状不变。拿生产库真实提交新旧逐点对比:C 2000 份 1989 一致、 C++ 891 份 890 一致、Python 2000 份全一致;不一致的是 system("pause")(现在不再判运行时错误)、 未定义行为、endl 死循环打印(运行时错误变运行超时),见 docker/judge/README.md。 - 判题容器改成 privileged(go-judge 要自己建 cgroup),镜像 oj2-judge-3 - 心跳改由 worker 每 5 秒问判题机 /version 代记,删掉 /api/judge-server/heartbeat - 前端统一用 stripJudgePath 去掉判题机工作目录(新的 /w/ 和旧的 /judger/run/) - 提交前编译检查只编译不运行 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
网站自带一套彩色 emoji 字体(Noto Color Emoji 的 COLRv1 版,按区段分 11 包,用到哪包才下哪包), 不再依赖系统字体。Caddy 对字体文件永久缓存。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## 镜像 一个 Dockerfile 两个 target:api(单二进制)和 web(Caddy + 前端产物)。 旧后端是一个容器里用 supervisord 跑 caddy+gunicorn+dramatiq,这里拆成 oj-web / oj-api / oj-worker 三个容器 —— Docker 本身就是进程管理器, 拆开之后 worker 挂了能单独重启、日志也分得开,少一层 supervisord 要维护。 同一个镜像换个子命令就是 worker,镜像里只有一份运行时。 新增 healthcheck 子命令:运行镜像是 debian-slim,没有 curl/wget, 让二进制自己打 /health(只打 /health 不碰库 —— 库挂了该由库的 healthcheck 报, 不该让 api 跟着被判不健康然后被重启)。 **数据目录照抄旧后端**(test_case、public/upload、public/avatar)。 不是审美问题:切换那天不用搬动任何文件,回滚时旧后端立刻能找到自己的数据。 少一次几十 GB 的 mv,就少一个在停机窗口里出错的机会。 构建路上踩到三个坑,都是「本地能过、容器里过不了」那一类: - 构建上下文吸进了 data/,judge_server/run 是判题沙箱用别的 uid 建的, docker 连 stat 都做不了,构建直接失败 → 补 .dockerignore - mermaid@9.4.3(机房老 Chrome 的 legacy 依赖,不能砍)从容器里连 registry.npmjs.com 稳定失败,主机上没问题 → 换 npmmirror,并重试两次 - 容器里 bun 用 isolated 布局,本地是扁平的。靠「提升」才能解析到的包 在容器里一律解析不到:@node-rs/jieba-linux-x64-gnu(编译要 import 它的 .node)、 以及前端的 @codemirror/{language,state,view} 和 @lezer/highlight。 这些本来就是代码直接 import 的,补成直接依赖。顺手写了个脚本扫全仓, 确认只有这 4 个。 ## 前端切回 /api、/ws 迁移期用 /api2、/ws2 指新后端,/api、/ws 还指着 Django。端点已全部搬完, 临时前缀去掉。改动只有三处(api2.ts 的 baseURL、websocket.ts 的两个 URL), `api2` 那些 import 是模块名不是路径,不动。vite 代理同步收敛成三条。 ## compose - debian:全套(含 postgres,对外开 5445 给机房连) - school:**没有 postgres**,连服务器的库;本地 Redis + 本地判题沙箱 - 两边共用一个库但各有各的队列和 WS 推送,和旧后端的 Dramatiq/Channels 拓扑一致 密钥一律走 env 且带 `:?`,没设置就直接报错退出,不静默用弱默认值。 COOKIE_SECURE 在机房必须是 false(http 直连 IP,带 Secure 的 Cookie 发不回来, 表现是「登录成功但立刻又变未登录」)。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>