VMware虚拟机中HUSTOJ在线评测系统搭建与二次开发排错

发布时间:2026/11/2 17:36:46
VMware虚拟机中HUSTOJ在线评测系统搭建与二次开发排错 项目标题HUSTOJ(VMware)开发指向的场景很明确把 HUSTOJ 这套在线评测系统在线判题系统装在 VMware 虚拟机里一边跑一边改代码。之所以要费劲开一台虚拟机是因为 OJ 这种东西属于编译器、数据库、Web 服务、守护进程、沙箱权限五件套绑死在同一台机器上的组合任何一个环节配错都会牵连一片裸机装一次失败就得重装系统。虚拟机给了你一次试错不用心疼的机会——快照一打改崩了三十秒回到上一秒的状态。这篇内容适合三类人想在自己电脑上搭一套 OJ 用来出题和教学的接了二次开发需求、需要读懂 HUSTOJ 源码的以及已经装好了但判题一直卡住、提交后一直 Pending 想找根因的。我会按虚拟机怎么配、服务栈按什么顺序装、判题机怎么编、二次开发从哪儿下刀、踩过的坑怎么排这条线走完中间给的都是可以直接抄的命令和配置不会只讲概念。1. 先把边界划清楚虚拟机里的 OJ 到底要做成什么形态动手之前得先想明白一件事你是要一个能用的 OJ还是要一个能改的 OJ。这两个目标对环境的要求完全不同。前者追求一次装完不再碰后者追求随时能重启服务、随时能回滚、随时能对照新旧两版代码的行为差异。我自己第一版就是按能用搭的结果改判题逻辑的时候把数据库搞坏没备份只能从零重来那次之后才彻底转成开发形态。1.1 裸机装、容器装、虚拟机装三种做法的真实代价先摆一张对比表这张表是我自己踩完之后总结的不是抄的做法装起来快不快改崩了恢复成本判题沙箱的权限问题适合谁物理机或本机双系统中等依赖包冲突多高可能要重装系统正常长期对外提供服务的场景容器里跑全套快镜像一把梭低容器删了重来麻烦容器内 setuid 和 ptrace 行为容易和预期不一致只想跑通看效果VMware 虚拟机中等但可复制极低快照秒回和物理机一致沙箱行为正常要做二次开发的人关键差异在第三列。HUSTOJ 的判题链路里有一个绕不开的东西判题客户端需要以较高权限运行才能对被测程序做资源限制和系统调用约束。在容器里做这套权限模型经常出现宿主机上好好的进容器就报错的情况而且报错信息通常非常隐晦——不是告诉你权限不足而是直接给你一个 Runtime Error让你以为是用户代码写错了。虚拟机里跑的是完整内核和完整用户态行为和你最终部署的服务器几乎一致这一点对排查问题太重要了。1.2 我为什么最终定成单网卡 快照基线 双目录分离最终的形态是这样的VMware 里一台虚拟机网络用 NAT 模式固定内网 IP只给自己宿主机访问系统装最小化版本额外挂一块数据盘专门放题目数据和数据库文件装完之后立刻打一个名为baseline-clean的快照后续所有实验都在快照之后做。单网卡 NAT 的理由很实际你不需要让外网访问它宿主机用浏览器打开http://虚拟机IP/就够了。桥接模式会让虚拟机暴露在局域网里多一层不必要的麻烦。数据盘单独挂载的理由更实际题目数据目录里动辄几百上千个测试点文件数据库文件又是另一个增长点这两块和你改的代码是分离的。代码改坏了你可以直接回滚系统盘快照但题目数据留在数据盘上不受影响——这个细节能帮你省掉很多次回滚之后题目全没了的崩溃。1.3 验收标准什么样才算这套环境搭好了我给自己的验收标准有四条缺一条我就认为没搭完不往下做二次开发能用一个普通账号登录 Web 端看到题目列表提交一段正确代码状态从等待走到通过提交一段死循环代码状态走到超时且 Web 端显示的时间接近设定的时限重启虚拟机之后不手动敲任何命令判题队列能自动恢复工作。第四条最容易被忽略。绝大多数人装完能跑一重启就废因为守护进程没配开机自启或者数据库没设开机启动。开发过程中你会频繁重启虚拟机改内核参数、清理环境、恢复快照每次都要手动拉一堆服务一天下来能烦死人。2. 虚拟机的规格单给判题留够余量很多人给虚拟机配 2 核 2G装完发现判题慢得像蜗牛提交一道题要等十几秒才出结果还以为是软件问题。判题这个场景的资源特征是短时高占用——编译阶段吃满一个核运行阶段要限制内存同时来几份提交就并行跑几个进程。资源给不够你调试的时候会分不清是代码问题还是机器跑不动。2.1 CPU 与内存的分配逻辑我给开发机的配置是 4 核 CPU、8G 内存、系统盘 40G、数据盘 60G。这个配置的推导过程是这样的判题的并发度通常设成 CPU 核心数因为每个判题进程在同一时刻基本只用一个核。4 核意味着最多 4 份提交并行判对于开发调试够用了。内存方面编译一份 C 代码峰值能吃到几百兆并行四份就是 1G 以上再加上数据库、PHP-FPM 进程池、Web 服务8G 是一个比较舒服的余量。如果你只想单人调试2 核 4G 也能跑但把并发度调到 2否则多份提交会互相抢资源测出来的时间完全不可信。注意判题机测出来的运行时间是墙钟时间 CPU 时间混合判断的虚拟机本身有调度开销。如果你要校准题目的时间限制最好在虚拟机空闲时测并且把并发度临时降到 1否则同样一份代码两次测出来的时间能差出一倍。2.2 磁盘布局系统盘与数据盘分开系统盘 40G 装系统和服务栈足够。数据盘 60G 挂到/home/judge这个位置因为 HUSTOJ 默认把源码、数据、日志全放在这个用户的家目录下。挂载的时候注意两件事一是格式化时选常规的 ext4 就够了别折腾花哨的文件系统二是在/etc/fstab里写挂载项时加上defaults,noatime减少文件访问时间戳的写入题目数据目录里的文件会被频繁读取这个参数能省一点 IO。先建目录再挂载顺序别反了sudo mkdir -p /home/judge sudo mount /dev/sdb1 /home/judge sudo blkid /dev/sdb1 # 拿到 UUID然后把 UUID 写进/etc/fstabUUIDxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx /home/judge ext4 defaults,noatime 0 2用 UUID 而不是/dev/sdb1的原因很直白虚拟机上加了新磁盘或者调整了控制器顺序之后盘符可能变用设备名写死的话某天开机就挂不上服务全挂。2.3 网络模式选择与固定 IP 的落地NAT 模式下 VMware 会给你一个虚拟网段通常是192.168.x.0/24。默认走 DHCPIP 可能会变而你在浏览器里存的地址、配置文件里写的回调地址都会因此失效。所以进系统第一件事就是把 IP 固定下来。用 netplan 的写法新版 Ubuntu 系network: version: 2 ethernets: ens33: dhcp4: false addresses: [192.168.150.128/24] routes: - to: default via: 192.168.150.2 nameservers: addresses: [223.5.5.5]网卡名和网关地址要按你自己虚拟机里的实际情况改ip a和 VMware 的虚拟网络编辑器里都能查到。改完执行sudo netplan apply。这里有个小坑如果你在虚拟机里又装了 Docker 之类的会改防火墙规则的东西重启后 netplan 的规则可能被覆盖表现出来就是IP 是对的但网页打不开遇到这种情况先sudo iptables -L看一眼转发链有没有被改。3. 系统底座与服务栈的安装顺序顺序错了会返工HUSTOJ 的安装脚本其实做了一件事把 Web 服务、数据库、PHP 扩展、编译工具链、判题程序按正确顺序串起来。手工装的时候最容易犯的错是先把源码丢进去再装依赖结果安装脚本检测不到某些组件就跳过了一步最后现象是网页能开但提交报错。3.1 依赖包的分层安装我把依赖分成三层按层装每层装完验证一次第一层是基础工具链build-essential、g、make、flex、unzip、curl、vim。这一层是给编译判题程序用的。第二层是 Web 与数据库nginx、php-fpm、php-mysql、php-gd、php-xml、php-mbstring、php-curl、mysql-server或mariadb-server。注意 PHP 的版本——HUSTOJ 的老代码里有相当多 PHP 5/7 时代的写法直接上最新的 PHP 8.x 会遇到一堆警告甚至致命错误。我在虚拟机上固定用 PHP 7.4 或 8.1 这两个版本兼容性最好装之前先apt-cache policy php-fpm看看仓库里给的是哪个版本。第三层是判题专用libmysqlclient-dev编译判题程序要链接数据库客户端库、libseccomp-dev如果版本里带了 seccomp 支持、time、sudo。一条命令装完以 Debian 系为例sudo apt update sudo apt install -y build-essential g make flex unzip curl vim \ nginx php-fpm php-mysql php-gd php-xml php-mbstring php-curl \ mariadb-server libmariadb-dev libseccomp-dev time sudo装完之后验证三件事php -v有输出、nginx -v有输出、mysql --version有输出。三个都通再往下走别嫌麻烦这一步省下来的时间后面要加倍还。3.2 数据库初始化与字符集设定建库这一步字符集必须一次设对。用默认的 latin1 建库后面题目描述里的中文全变问号改起来要导表重建非常折磨。CREATE DATABASE jol DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER jollocalhost IDENTIFIED BY 换成你自己的强密码; GRANT ALL PRIVILEGES ON jol.* TO jollocalhost; FLUSH PRIVILEGES;然后把 HUSTOJ 源码里自带的建表脚本导进去脚本一般位于src/install/目录下文件名类似hustoj.sql。导入之前建议先打开看一眼确认里面没有CREATE DATABASE语句覆盖你刚建的库。导入之后验证编码USE jol; SHOW VARIABLES LIKE character_set%;character_set_server和character_set_database都应该是utf8mb4。如果不是去/etc/mysql/下的配置文件里补上[mysqld]段的character-set-serverutf8mb4和collation-serverutf8mb4_unicode_ci然后重启数据库。提示数据库账号密码要和后面 PHP 配置文件里的完全一致包括大小写和特殊字符。密码里有#、$、的时候写进 PHP 文件的单引号字符串里一般没问题但写进 shell 脚本时记得转义我在这上面浪费过半小时。3.3 Web 服务与 PHP 的对接断层nginx 和 php-fpm 之间靠一个 unix socket 或者 TCP 端口通信这一层没接上网页就是 502。先确认 php-fpm 的监听方式grep -r listen /etc/php/*/fpm/pool.d/www.conf通常会看到listen /run/php/php7.4-fpm.sock或listen 127.0.0.1:9000两种。把这个值抄到 nginx 的站点配置里server { listen 80; server_name _; root /home/judge/src/web; index index.php index.html; client_max_body_size 64m; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php7.4-fpm.sock; } }client_max_body_size这一行别省。默认 1M用户提交一份长代码或者上传一个测试数据包直接 413 报错而且报错页面很难看懂。同时把 PHP 的upload_max_filesize、post_max_size一起调大三个地方的值要匹配只改一个没用。还有两个和开发体验直接相关的 PHP 配置date.timezone设成Asia/Shanghai否则页面上所有时间都差八小时display_errors在开发阶段设成On能省掉大量白屏不知道为什么的排查时间。生产环境记得关掉。4. 判题机的编译、配置与第一次真机验证到这一步 Web 端应该能打开、能登录、能看到题目列表了。但只要你提交一次就会发现状态永远停在等待——因为判题程序还没编译、没启动。这是整个搭建过程中技术含量最高的一段也是二次开发的主战场。4.1 judge.conf 里每个字段到底在管什么配置文件一般在/home/judge/etc/judge.conf。这个文件不长但每个字段配错都对应一个具体故障我挑关键的说OJ_NAMEMyOJ OJ_HOME/home/judge OJ_HOST_NAME127.0.0.1 OJ_DB_NAMEjol OJ_DB_USERNAMEjol OJ_DB_PASSWORD和数据库一致 OJ_TEMPLATEbs3 OJ_DATA/home/judge/data OJ_RUNNING4 OJ_SLEEP_TIME2 OJ_CPU_TIME_LIMIT10 OJ_COMPILE_CPU_TIME_LIMIT10 OJ_MEM_LIMIT256OJ_RUNNING是并发判题数设成 CPU 核心数比较合理。OJ_SLEEP_TIME是守护进程轮询数据库的间隔秒数设太小数据库压力大设太大提交后要等很久才有反应2 到 3 秒是常用值。OJ_CPU_TIME_LIMIT是全局兜底时限题目的时间限制在这个范围内才生效。OJ_DATA指向题目数据根目录每个题目一个以题目编号命名的子目录。OJ_TEMPLATE决定前端用哪套模板值对应 Web 目录下template/里的子目录名。这个字段在二次开发时会频繁改因为你可以复制一份模板目录改名然后改配置切换出问题随时切回来。4.2 judged 与 judge_client 的权限模型这两个程序的关系是judged是常驻守护进程负责轮询数据库里待判的提交judge_client是单次判题的执行体负责编译、运行、比对结果。为什么拆成两个因为每次判题面对的是不可信的用户代码需要一个进程专门承担风险判完就退而守护进程要长期稳定。编译命令在源码的core目录下通常是一个 shell 脚本包着 g 调用cd /home/judge/src/core sudo ./make.sh编完会生成judged和judge_client两个可执行文件安装脚本会把它们复制到/home/judge/下。这里有个非常关键、非常容易漏掉的步骤权限位。判题客户端需要对被测程序施加资源限制这需要额外的权限。手工编译时如果漏了chmod us judge_client这一步现象是每次提交都是 Runtime Error日志里写着创建沙箱失败之类的信息但你在 Web 端完全看不出来原因。同样资源限制的辅助程序通常叫judex或者版本不同的对应文件也需要正确的权限位。sudo chown root:root /home/judge/judge_client /home/judge/judex sudo chmod us /home/judge/judge_client sudo chmod 755 /home/judge/judex题目数据目录的属主也要调整因为判题进程会以较低权限用户去读这些文件sudo chown -R judge:judge /home/judge/data sudo chmod -R 755 /home/judge/data4.3 用一道 AB 跑通全链路并读懂日志先手动启动守护进程看日志sudo /home/judge/judged tail -f /home/judge/log/judge.log另开一个窗口在 Web 端建一道最简单的题输入两个整数输出它们的和。测试数据放在/home/judge/data/1000/下文件名是1.in、1.out、2.in、2.out这种格式。这里有个细节.out文件的末尾最好留一个换行并且判题时通常会忽略行尾空白但如果你的数据文件是在 Windows 上用记事本编辑的里面会混入回车符比对就会失败。我建议在虚拟机里直接用vim或者printf生成测试数据。建完题提交一份正确代码然后盯着日志看。正常的日志会依次出现读取提交、创建临时目录、编译成功、逐个测试点比对、写回结果。哪一步断了问题就在哪一步。判题结果的状态码在 Web 端显示为中文但在数据库里是数字。不同版本的状态码定义不完全一样最可靠的做法是打开 Web 源码里定义常量的那个文件通常在include/目录下把数字和含义对一遍。我调试时习惯直接查库SELECT solution_id, problem_id, user_id, result, time, memory FROM solution ORDER BY solution_id DESC LIMIT 10;result字段里待判状态是一个较小的数字判完之后会变成各种错误码。看到大量提交卡在待判状态超过一分钟基本可以断定守护进程没跑或者数据库连不上。5. 二次开发的切入点从改模板到写自定义判题环境跑通之后才进入正题。HUSTOJ 的代码结构是典型的老派 PHP C 守护进程组合不算优雅但分工清晰摸清目录之后改起来很顺。5.1 源码目录地图先把这个地图记住能省掉大量grep时间路径职责你会在什么时候进这里src/web/PHP 前端所有页面改界面、加字段、加新页面src/web/include/公共函数、数据库连接配置、常量定义改配置、查状态码、加公共方法src/web/template/名称/各套前端模板换皮肤、调布局src/web/admin/后台管理页面加管理功能src/core/判题程序 C 源码改判题逻辑、编译方式、资源限制src/install/安装脚本与建表 SQL重建环境、查表结构/home/judge/data/题目测试数据加题、改数据、挂特殊判题/home/judge/etc/judge.conf判题配置调并发、改路径/home/judge/log/judge.log判题日志排查一切判题问题改动最频繁的是src/web/include/db_info.inc.php数据库地址、账号、模板名、站点标题都在这里。这个文件相当于整个前端的总开关。5.2 改前端模板的最小改动路径假设你要改首页的排版。正确做法不是直接改src/web/index.php而是把template/下现有的某套模板目录整个复制一份改名成mytpl在db_info.inc.php里把模板变量改成mytpl只改template/mytpl/里的文件。这么做的原因是升级源码时src/web/根目录下的文件会被覆盖模板目录是可以保留的你的改动不会丢。我第一版为了省事直接改根目录文件后来同步上游代码时被全覆盖白干两天。模板文件里通常引用了公共的头部和尾部文件改布局时注意别把head里的样式表引用删了删了之后页面能开但样式全丢看上去像坏了其实只是丢了一行。5.3 加一个字段数据库、表单、展示三处必须联动这是二次开发里最高频的需求比如你想给题目加一个难度星级字段。改动点有三处漏一处就会出问题第一处数据库加列ALTER TABLE problem ADD COLUMN difficulty TINYINT DEFAULT 3;第二处后台的题目编辑页面。在src/web/admin/下找到题目编辑相关的页面里面会有一段拼接 SQL 的代码把新字段加到 INSERT 和 UPDATE 语句里同时在表单 HTML 里加一个下拉框或输入框。第三处前台的题目展示页面在模板文件里把新字段读出来渲染。这里最容易出的事故是 SQL 拼接时类型没处理好。difficulty是数字表单提交上来的是字符串直接拼进 SQL 不会报错但类型不对如果字段是文本类型而用户输入了单引号轻则语句报错重则被注入。老代码里这种拼接口很多我改的时候会用参数化查询把新加的这部分包起来改动量不大但能避免很多隐患。改完记得清缓存——如果你的模板里做了文件缓存或者用了 PHP 的 opcache改完代码刷新页面没变化先sudo systemctl restart php*-fpm再看。5.4 特殊判题的接入方式标准判题是逐字符比对输出但有些题答案不唯一比如要求输出任意一组可行解。这种题需要特殊判题程序SPJ。接入方式是在题目数据目录下放一个判题程序的源码或可执行文件判题客户端检测到它的存在就会优先调用它把输入文件、选手输出文件、标准输出文件三个路径传给它由它返回判定结果。约定一般是返回 0 表示通过返回非 0 表示失败返回特定值表示需要人工确认。写 SPJ 时有三个坑值得提前说第一SPJ 自己也有时间限制写一个 O(n²) 的校验逻辑在校验大数据时会超时表现出来是选手代码明明正确却判失败。校验逻辑一定要写成线性的。第二SPJ 崩溃或者返回了预期之外的值判题系统可能把它当成失败而不是系统错误于是你会看到一批莫名其妙的错误提交实际是判题程序自己出问题了。所以调试阶段要单独用命令行手动跑一遍 SPJ喂三个文件进去看返回值。第三SPJ 要用判题机上的编译器重新编译编译器版本和你本地不同可能导致语法不兼容。我在本地用较新的标准写扔到虚拟机上编译失败卡了很久才发现是标准版本问题。6. 三次重装换来的排错清单下面这些坑每一条我都真实踩过而且都是在看着应该没问题的情况下踩的。我把现象、根因、验证方法列出来你可以当成一个对照表用。6.1 网页白屏或 502先分清是哪一层挂了现象是浏览器打开一片空白或者提示网关错误。排查顺序是自下而上先看 PHP 是否活着sudo systemctl status php*-fpm。如果挂了看journalctl -u php*-fpm -n 50的日志。常见原因是扩展缺失比如代码里用了mysql_*系列函数但装的是 PHP 8这些函数已经被移除了报的是调用未定义函数。再看 nginx 的错误日志tail -f /var/log/nginx/error.log。如果里面写着connect() to unix:/run/php/xxx.sock failed说明 nginx 的fastcgi_pass指向的 socket 路径和 php-fpm 实际监听的路径不一致。这个不一致经常是因为系统里装了两个 PHP 版本一个 7.4 一个 8.1各自有自己的 socket 目录。最后才看应用层。在 Web 根目录临时放一个info.php内容就是输出 PHP 信息访问它看能不能出页面。这个文件能出、主页面不能出问题就在应用配置这个文件也出不来问题在服务层。排查完记得删掉这东西暴露出去不合适。6.2 提交后一直等待判题队列的四种卡死原因按概率从高到低排第一种守护进程没启动。ps aux | grep judged看一眼就知道。手动启动后记得配开机自启否则重启虚拟机就复现。第二种守护进程起来了但连不上数据库。日志里会出现连接失败的信息。验证方法是在同一台机器上用mysql -u jol -p手动登录一次能登进去说明账号密码对登不进去就是配置问题。注意配置文件里的密码有没有被引号包住、有没有多余空格。第三种数据目录权限不对。判题进程读不到测试数据日志里会写找不到文件。ls -l /home/judge/data/1000/看一下属主和权限位。第四种上一次判题进程僵死占着队列。这种情况的表现是日志停在某个提交不动后面所有提交都不推进。ps aux | grep judge看有没有僵尸进程有的话杀掉再重启守护进程。根治方法是给判题程序加超时兜底不让单次判题无限期挂着。6.3 编译通过却全是错误答案数据文件的隐形差异这类问题最气人因为你的代码逻辑明明是对的。我用一道最简单的求和题查过两个小时最后发现是数据文件的问题。第一个隐形差异是换行符。Windows 下生成的.out文件行尾是\r\n选手程序输出的是\n逐字节比对直接失败。用file 1.out看是不是有CRLF字样有的话用sed -i s/\r$// 1.out批量清理一遍。第二个是文件末尾的空行。有的比对逻辑要求输出完全一致多一个空行就判错少一个换行也判错。建议统一规范每个.out文件以一个换行结尾不多不少。第三个是编码。如果题目有中文输出数据文件是 GBK 编码而选手程序输出 UTF-8比对必然失败。统一用 UTF-8。排查这类问题最快的办法是绕过判题系统直接在命令行手动跑一遍把输入喂给程序输出重定向到文件然后diff一下标准输出和自己生成的文件。diff能直接告诉你差在第几行第几个字符。6.4 中文乱码与时间错乱乱码问题排查起来有个技巧先确定是数据库层还是展示层。直接查库SELECT title FROM problem LIMIT 5;如果终端里显示正常说明数据存储没问题问题在 PHP 连接数据库时的字符集设置。在数据库连接代码里执行一次设置连接字符集的语句即可通常是在建立连接之后紧接着执行SET NAMES utf8mb4。如果终端里也是问号那问题在建库或建表阶段得检查表和列的字符集SHOW FULL COLUMNS FROM problem;Collation那一列应该都是utf8mb4开头的。有latin1的就要改ALTER TABLE ... CONVERT TO CHARACTER SET utf8mb4。时间错乱就一个原因PHP 的时区没设。改php.ini里的date.timezone Asia/Shanghai同时数据库的时区也确认一下两边不一致会出现提交时间比现在晚八小时或者早八小时的情况。7. 让这套环境能长期用下去的几个习惯搭好只是开始能不能长期用取决于你维护它的方式。我见过太多人搭完之后不敢动因为一动就崩最后这套环境变成摆设。7.1 快照的命名规则与回滚时机我的规则是每个快照名都带日期和状态比如20240610-baseline、20240610-pre-edit、20240610-db-changed。打快照的时机有三个装完系统和服务栈之后、每次要动数据库结构之前、每次升级源码之前。不要指望出了问题再想办法判题系统涉及数据库和文件系统两套状态手工回滚经常只回滚了一半。快照是整机状态回滚就是彻底回到那个时间点干净利落。代价也要清楚快照会真实占用磁盘空间你打十个快照虚拟磁盘能膨胀好几倍。我的习惯是保留三个干净基线、当前稳定点、待观察的实验点更早的定期删掉。7.2 代码与数据分离备份快照解决的是整机回滚但如果你只想保住题目数据和自己的代码改动快照太重了。我的做法是两条独立的备份线代码线自己改过的文件和模板目录用 git 管起来在 Web 目录下建一个仓库只跟踪你改过的文件别把整个目录都加进去——里面有一堆上传的附件和缓存文件全提交会让仓库迅速膨胀。数据线题目数据目录和数据库导出。数据库用mysqldump定时导出题目数据目录用tar打包。这两样加起来的体积比整机快照小得多可以往宿主机上拷一份。mysqldump -u jol -p jol /home/judge/backup/jol_$(date %Y%m%d).sql tar -czf /home/judge/backup/data_$(date %Y%m%d).tar.gz /home/judge/data这两个命令我写进了一个脚本每次大改动之前跑一次。有一次我误删了一个题目目录就是靠这个包恢复的前后三分钟。7.3 多环境并行一套改一套验真正开始做二次开发之后单台虚拟机会不够用。你改代码的时候总得有个对照不然改出问题分不清是自己改错了还是本来就这样。我的做法是克隆一台虚拟机一台叫dev一台叫verify两台配置完全一样dev上随便折腾verify上只跑稳定版本。克隆完要改两件事IP 地址否则两台冲突都上不了网以及主机名方便在终端里分清自己在哪台机器上。改完 IP 记得把judge.conf里连数据库的主机地址一起改掉如果两台共用一个数据库实例就更要注意别让两台机器的判题进程同时抢同一个队列。让我最后说一句实在话这套东西最大的价值不是你搭起来的那一刻而是你改崩了能迅速恢复的能力。我前两次搭的时候所有精力都花在怎么装上去一次都没想过装坏了怎么办结果每次都是从头再来。第三次我花了半天先把快照、备份、克隆这套流程走通后面所有改动都变得很轻松——改错了回滚改对了打个快照继续。至于判题程序那些参数我建议你第一次就手动启动它、盯着日志看一遍完整的判题过程比起读十篇教程那几十行日志能让你立刻明白这套系统是怎么运转的。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询