refactor(判题机): 换成 go-judge,空闲内存从几百 MB 降到 16 MB
原来的 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>
This commit is contained in:
1 parent
8427475337
commit
37e971b6b4
30 files changed
+881
-592
No files matched your search
+9
-21
@@ -21,9 +21,9 @@
|
||||
# echo "OJ2_JUDGE_TOKEN=$TOKEN" >> docker/.env # docker compose 读这里
|
||||
# echo "JUDGE_SERVER_TOKEN=$TOKEN" >> .env # 后端读这里,两边必须一致
|
||||
#
|
||||
# 两个变量名不同但值必须相同:TOKEN 是判题机镜像认的名字,JUDGE_SERVER_TOKEN 是后端认的名字。
|
||||
# 忘了设 OJ2_JUDGE_TOKEN 的话 docker compose 会直接报错退出;忘了设 JUDGE_SERVER_TOKEN
|
||||
# 的话后端会随机生成一个并在启动日志里告警,判题机心跳会被 403 挡掉。
|
||||
# 两个变量名不同但值必须相同:ES_AUTH_TOKEN 是判题机(go-judge)认的名字,JUDGE_SERVER_TOKEN
|
||||
# 是后端认的名字。忘了设 OJ2_JUDGE_TOKEN 的话 docker compose 会直接报错退出;忘了设
|
||||
# JUDGE_SERVER_TOKEN 的话后端会随机生成一个并在启动日志里告警,判题请求会被 401 挡掉。
|
||||
|
||||
services:
|
||||
postgres:
|
||||
@@ -60,37 +60,25 @@ services:
|
||||
retries: 10
|
||||
|
||||
judge:
|
||||
# 自己构建的判题沙箱(上游 JudgeServer 1.6.1 + 新工具链,见 docker/judge/)。
|
||||
# 上游停更在 2024-04,registry 上的 1.6.1 == latest,没有新版可拉。
|
||||
# 自己构建的判题沙箱(go-judge + gcc / python,见 docker/judge/)。
|
||||
# ⚠️ 这个 tag 不在任何 registry 上:本机 docker/judge/build.sh 构建,
|
||||
# 服务器/机房用 docker load 装。镜像不在本地时 compose 会去 pull 然后报找不到。
|
||||
image: oj2-judge-2
|
||||
image: oj2-judge-3
|
||||
container_name: oj2-judge
|
||||
restart: unless-stopped
|
||||
read_only: true
|
||||
cap_drop:
|
||||
- SETPCAP
|
||||
- MKNOD
|
||||
- NET_BIND_SERVICE
|
||||
- SYS_CHROOT
|
||||
- SETFCAP
|
||||
- FSETID
|
||||
# go-judge 要自己建 namespace 和 cgroup 来关学生程序,只能给特权,理由见 docker/judge/README.md
|
||||
privileged: true
|
||||
# go-judge 的文件存储(编译产物、程序输出)放这里,见 Dockerfile 的 -dir
|
||||
tmpfs:
|
||||
- /tmp
|
||||
ports:
|
||||
- "127.0.0.1:8081:8080"
|
||||
volumes:
|
||||
- ../data/test_case:/test_case:ro
|
||||
- ../data/judge_server/log:/log
|
||||
- ../data/judge_server/run:/judger
|
||||
environment:
|
||||
SERVICE_URL: http://oj2-judge:8080
|
||||
BACKEND_URL: http://host.docker.internal:3000/api/judge-server/heartbeat
|
||||
# 没有默认值是故意的:写死在仓库里的弱 token 等于没有 token。
|
||||
# 未设置时 docker compose 直接报错,不会静默起一个人人可连的判题机。
|
||||
TOKEN: ${OJ2_JUDGE_TOKEN:?请先设置 OJ2_JUDGE_TOKEN,见本文件顶部注释}
|
||||
extra_hosts:
|
||||
- "host.docker.internal:host-gateway"
|
||||
ES_AUTH_TOKEN: ${OJ2_JUDGE_TOKEN:?请先设置 OJ2_JUDGE_TOKEN,见本文件顶部注释}
|
||||
mem_limit: 512m
|
||||
|
||||
volumes:
|
||||
|
||||
Reference in new issue
Block a user