1. 项目概述与背景
HOJ作为一款开源的在线判题系统,在编程竞赛和算法训练领域有着广泛应用。基于CentOS系统配合宝塔面板搭建HOJ的方案,因其操作便捷性受到许多技术爱好者的青睐。本次搭建的核心在于数据库配置和关键脚本的实现,这是确保判题系统稳定运行的基础架构。
在CentOS 7环境下,我们选择宝塔面板作为运维管理工具,它能显著降低服务器环境配置的复杂度。数据库部分采用MySQL 8.0作为HOJ的数据存储引擎,这是考虑到其良好的事务支持和高并发读写性能,完全满足在线判题系统对数据一致性的严格要求。
提示:建议使用CentOS 7.6以上版本,这个版本对宝塔面板的兼容性最佳,且系统稳定性经过长期验证。
2. 环境准备与基础配置
2.1 系统初始化设置
在开始安装前,需要对CentOS系统进行基础优化:
# 更新系统组件 yum update -y # 安装常用工具 yum install -y wget curl vim git unzip # 关闭不必要的服务 systemctl stop firewalld systemctl disable firewalld setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config2.2 宝塔面板安装与优化
执行官方安装命令获取最新版宝塔面板:
wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh安装完成后,通过面板推荐安装以下组件:
- Nginx 1.20(高性能Web服务器)
- MySQL 8.0(数据库服务)
- PHP 7.4(部分HOJ组件依赖)
- PM2管理器(Node.js进程管理)
注意:安装MySQL时务必选择8.0版本,HOJ的部分功能如窗口函数依赖此版本特性。同时建议设置root密码强度不低于12位,包含大小写字母、数字和特殊字符。
3. 数据库部署与配置
3.1 MySQL参数调优
在宝塔面板的MySQL设置中,需要调整以下关键参数:
[mysqld] innodb_buffer_pool_size = 2G # 建议为物理内存的50%-70% innodb_log_file_size = 256M max_connections = 500 query_cache_size = 64M character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci这些参数优化主要考虑:
- 增大缓冲池提升查询性能
- 调整日志文件大小平衡IO性能
- 提高最大连接数应对并发访问
- 使用utf8mb4字符集完整支持emoji等特殊字符
3.2 HOJ数据库初始化
通过宝塔面板的phpMyAdmin导入HOJ提供的SQL初始化脚本:
-- 创建数据库 CREATE DATABASE hoj CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 授权特定用户(生产环境建议使用最小权限原则) CREATE USER 'hoj_user'@'localhost' IDENTIFIED BY 'StrongPassword123!'; GRANT ALL PRIVILEGES ON hoj.* TO 'hoj_user'@'localhost'; FLUSH PRIVILEGES;导入完成后,需要特别检查以下表结构是否完整:
problem题目表user用户表judge判题记录表contest比赛表
4. 关键脚本实现与部署
4.1 判题服务脚本
判题核心脚本judge-server.sh需要放置在/usr/local/hoj/judge目录下:
#!/bin/bash # HOJ判题服务守护进程 JUDGE_PATH="/hoj/judge" LOG_FILE="/var/log/hoj-judge.log" while true; do # 检查判题进程是否存在 if ! pgrep -f "hoj-judge" > /dev/null; then echo "$(date) - 判题服务未运行,正在启动..." >> $LOG_FILE nohup $JUDGE_PATH/hoj-judge >> $LOG_FILE 2>&1 & fi sleep 30 done设置脚本可执行权限并加入开机启动:
chmod +x /usr/local/hoj/judge/judge-server.sh echo "@reboot root /usr/local/hoj/judge/judge-server.sh" >> /etc/crontab4.2 数据库备份脚本
定期备份脚本db-backup.sh配置:
#!/bin/bash # HOJ数据库备份脚本 BACKUP_DIR="/backup/hoj-db" DATE=$(date +%Y%m%d) MYSQL_USER="hoj_user" MYSQL_PASS="StrongPassword123!" DB_NAME="hoj" # 创建备份目录 mkdir -p $BACKUP_DIR # 执行备份 mysqldump -u$MYSQL_USER -p$MYSQL_PASS $DB_NAME | gzip > $BACKUP_DIR/hoj_$DATE.sql.gz # 删除7天前的备份 find $BACKUP_DIR -name "hoj_*.sql.gz" -mtime +7 -exec rm {} \;配置每日凌晨3点自动执行:
chmod +x /root/db-backup.sh echo "0 3 * * * root /root/db-backup.sh" >> /etc/crontab5. 性能优化与安全加固
5.1 数据库索引优化
针对HOJ的高频查询场景,建议添加以下索引:
-- 题目表查询优化 ALTER TABLE problem ADD INDEX idx_visible_id (visible, id); ALTER TABLE problem ADD INDEX idx_author (author); -- 判题记录查询优化 ALTER TABLE judge ADD INDEX idx_submit_time (submit_time); ALTER TABLE judge ADD INDEX idx_uid_pid (user_id, problem_id); -- 比赛查询优化 ALTER TABLE contest ADD INDEX idx_start_end_time (start_time, end_time);5.2 系统安全配置
修改MySQL默认端口:
[mysqld] port = 3307配置Nginx访问限制:
location /admin/ { allow 192.168.1.0/24; deny all; auth_basic "Restricted"; auth_basic_user_file /etc/nginx/htpasswd; }安装fail2ban防御暴力破解:
yum install -y fail2ban systemctl enable fail2ban systemctl start fail2ban
6. 常见问题排查指南
6.1 数据库连接失败
现象:HOJ前端显示数据库连接错误
排查步骤:
- 检查MySQL服务状态:
systemctl status mysqld - 验证用户权限:
SHOW GRANTS FOR 'hoj_user'@'localhost'; - 检查最大连接数是否耗尽:
SHOW STATUS LIKE 'Threads_connected';
6.2 判题服务异常
现象:提交代码后长时间无判题结果
解决方案:
- 检查判题服务日志:
tail -f /var/log/hoj-judge.log - 验证判题进程是否存在:
ps aux | grep hoj-judge - 检查判题机资源使用情况:
top -u hoj
6.3 性能瓶颈分析
当系统响应变慢时,可按以下顺序排查:
- 数据库慢查询分析:
SET GLOBAL slow_query_log = 'ON'; SET GLOBAL long_query_time = 1; - 检查服务器负载:
vmstat 1 - 分析Nginx访问日志:
goaccess /www/wwwlogs/access.log
7. 维护与监控方案
7.1 资源监控配置
安装node_exporter用于Prometheus监控:
wget https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz tar xvf node_exporter-* cp node_exporter-*/node_exporter /usr/local/bin/ useradd -rs /bin/false node_exporter创建systemd服务:
[Unit] Description=Node Exporter After=network.target [Service] User=node_exporter Group=node_exporter ExecStart=/usr/local/bin/node_exporter [Install] WantedBy=multi-user.target7.2 日志轮转配置
在/etc/logrotate.d/hoj中添加:
/var/log/hoj-judge.log { daily missingok rotate 30 compress delaycompress notifempty create 640 hoj hoj sharedscripts postrotate /usr/bin/systemctl reload hoj-judge > /dev/null endscript }在实际部署过程中,我发现判题服务的稳定性很大程度上取决于数据库配置的合理性。特别是在高并发场景下,适当调整InnoDB缓冲池大小和连接数参数可以显著提升系统响应速度。另外,定期维护数据库索引和统计信息也能有效预防性能劣化。