Files
OJ2/docker/Caddyfile
T
xuyueandClaude Opus 5.5 37e971b6b4 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>
2026-10-26 15:03:57 +08:00

85 lines
2.7 KiB
Caddyfile
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 前端静态资源 + 反向代理。移植自旧后端 deploy/caddy/Caddyfile,
# 上游从「同容器里的 gunicorn」换成「api 容器」,其余策略照搬。
{
admin off
servers {
# TLS 由前面的 Nginx Proxy Manager 终止,转发进来是明文 http。
# 只信任内网来源的 X-Forwarded-For,{client_ip} 才解析得出学生的真实 IP。
trusted_proxies static private_ranges
}
}
# 站点地址只写端口,Caddy 就不会去申请证书(auto-HTTPS 自动关闭)。
:8000 {
encode gzip
# 和 NPM 那一层的 client_max_body_size 保持一致,上传测试用例压缩包用得上。
# 必须写 MiB:Caddy 的 MB 按 10^6 算,200MB 比 nginx 的 200M 小了将近 10M。
request_body {
max_size 200MiB
}
# Caddy 的 header 会跨层叠加,不像 nginx 的 add_header 一旦在子块出现就不再继承,
# 所以这里写一次就够,下面各 handle 里只管自己的 Cache-Control。
header {
X-XSS-Protection "1; mode=block"
X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
}
log {
output file /data/log/caddy_access.log {
roll_size 10MiB
roll_keep 10
}
}
# 静态资源量大且带永久缓存,不记访问日志
@nolog path /assets/* /emoji/*
log_skip @nolog
handle /api/* {
reverse_proxy oj-api:3000 {
header_up X-Real-IP {client_ip}
# AI 分析走 SSE。X-Accel-Buffering 是 nginx 专有的,Caddy 不认,
# 这里显式关掉响应缓冲,保证流式输出逐块下发。
flush_interval -1
}
}
handle /ws/* {
reverse_proxy oj-api:3000 {
header_up X-Real-IP {client_ip}
}
}
# 头像和题面图片。旧配置是 Caddy 直接读 /data 下的盘,这里改成反代给后端:
# 后端本来就要处理头像缺省回退,开发环境(Vite 代理)也走同一条路,
# 少一处「只在生产才生效」的分支。文件不大、量也不大,多一跳无所谓。
handle /public/* {
reverse_proxy oj-api:3000
}
# 构建产物文件名带内容 hash,内容一变文件名就变,可以永久缓存。
# 命中后浏览器直接读磁盘,不再发条件请求。
# emoji 字体(见 public/style.css)文件名不带 hash,但带了版本号(noto-v47-N),
# 内容不会原名改动,同样永久缓存 —— 否则每次开页面每个分包都要回源校验一次。
@immutable path /assets/* /emoji/*
handle @immutable {
root * /srv
header Cache-Control "public, max-age=31536000, immutable"
file_server
}
# index.html 引用着带 hash 的文件名,必须每次回源校验,
# 否则发新版后学生刷不到。no-cache 是「缓存但每次校验」,命中走 304。
handle {
root * /srv
header Cache-Control "no-cache"
try_files {path} /index.html
file_server
}
}