目录
- 1. 项目概述
- 2. 项目演示
- 2.1 项目源代码
- 2.2 测试操作
- 3. 核心功能及代码框架
- 4. 所用技术与开发环境
- 5. 所需组件安装
- 5.1 gcc升级
- 1.CentOS 7 升级 GCC(适配 devtoolset 方式)
- 2. Ubuntu 升级 GCC(适配 apt 仓库方式)
- 5.2 安装jsoncpp
- 1. CentOS 7 安装 jsoncpp(仅 yum 方式)
- 2. Ubuntu 安装 jsoncpp(仅 apt 方式)
- 5.3 安装cpp-httplib
- 5.4 安装boost库
- 1. CentOS 7 安装 Boost 库(yum 方式)
- 2. Ubuntu 安装 Boost 库(apt 方式)
- 5.5安装ctemplate
- 1. CentOS 7 安装 ctemplate(yum 方式)
- 2. Ubuntu 安装 ctemplate(apt 方式)
- 5.6 Ace编辑器
1. 项目概述
该项目是一个负载均衡式在线评测系统(Online Judge,简称 OJ),目标是实现类似 LeetCode 的在线编程平台。用户可以浏览题目、在线编写代码、提交运行并获取评测结果。系统采用C++开发,基于MVC 架构,并实现了多机负载均衡,以提高编译和运行服务的并发能力与稳定性。
2. 项目演示
2.1 项目源代码
代码链接:OnlineJudge-过云雨/项目 - 码云 - 开源中国
2.2 测试操作
- 开启虚拟器/云服务器,打开四个终端,三个运行
./compile_server文件,端口分别为8081、8082、8083。第四个终端运行./oj_server。
./compile_server8081./compile_server8082./compile_server8083./oj_server- 打开浏览器,输入你电脑的
ip:port,即可打开OJ平台的主界面,点击开始编程进入题目列表。
# 我的虚拟机ip是192.168.233.128192.168.233.128:8080- 选择任意一个题目进入题目内容界面(此处我测试所以使用了多个同样的题目,可以自定义修改)
- 题目内容界面,有题目描述、代码框、提交代码按钮、编译运行结果。将代码完善之后,点击提交代码。
- 多次点击“提交代码”按钮,查看虚拟机终端,可见每次运行时寻找负载最低的后台来编译运行程序
3. 核心功能及代码框架
整个项目总共分三个文件夹存放:comm、compile_server、oj_server
comm:
util.hpp(常用公共功能):获取时间戳、路径拼接、文件名拼接、文件内容读取与写入、字符串分割。log.hpp(日志打印功能):打印日志功能。httplib.h(http协议):http协议的C++版本开源库。
compile_server:
compiler.hpp(编译器):用户代码编译。runner.hpp(执行器):用户代码运行与限制。compile_run.hpp(编译执行流程):编译运行流程、报错存放、中间文件删除。compile_server.cc(http协议+编译执行调用):http协议接收、执行编译运行流程。makefile(make指令):make编译与清理。
oj_server:MVC
oj_model.hpp:题目数据加载。oj_view.hpp:http界面渲染。oj_control.hpp:主机控制、负载均衡、序列化处理、http协议发送与接收。- oj_server.cc:主逻辑运行。
- makefile(make指令):make编译与清理。
- wwwroot文件夹:网页主界面
- template_html文件夹:题目目录和题目界面
- questions文件夹:存放题目内容、代码框架等
- conf文件夹:存放可用ip+port
项目宏观结构:
4. 所用技术与开发环境
所用技术:
- C++ STL 标准库
- Boost 准标准库(字符串切割)
- cpp-httplib 第三方开源网络库
- ctemplate 第三方开源前端网页渲染库
- jsoncpp 第三方开源序列化、反序列化库
- 负载均衡设计
- 多进程、多线程
- MySQL C connect
- Ace 前端在线编辑器(了解)
- html/css/js/jquery/ajax(了解)
开发环境
- Centos 7 系统 或者 ubuntu系统(虚拟机或者云服务器均可)
- vscode
- Mysql Workbench
5. 所需组件安装
5.1 gcc升级
1.CentOS 7 升级 GCC(适配 devtoolset 方式)
安装 SCL 仓库(软件集管理工具)
SCL(Software Collections)是 CentOS 官方提供的工具,用于在不替换系统默认 GCC 的前提下,安装并使用高版本 GCC(解决老编译器编译 cpp-httplib 报错问题)。执行以下命令安装:
sudoyuminstall-ycentos-release-scl scl-utils-build安装指定版本的 GCC
可选择 7/8/9 等版本(推荐 9 以适配 cpp-httplib),命令如下(以 9 为例,替换数字可装其他版本):
# 安装 GCC 9 及 C++ 编译器sudoyuminstall-ydevtoolset-9-gcc devtoolset-9-gcc-c++安装完成后,可通过
ls /opt/rh/验证,能看到devtoolset-9目录即表示安装成功。临时启用高版本 GCC(当前会话有效)
系统默认仍使用老版本 GCC,需手动启用新版本,该操作仅对当前终端会话生效:
sclenabledevtoolset-9bash执行后输入
gcc -v,可看到版本已切换为 9.x(而非系统默认的 4.8.5)。永久启用高版本 GCC(可选,推荐)
若希望每次登录终端自动启用新版本,需将启用命令写入
~/.bash_profile:编辑配置文件:
vi~/.bash_profile在文件末尾添加以下内容(以 GCC 9 为例):
# 自动启用 devtoolset-9 版本的 GCCsclenabledevtoolset-9bash保存退出后,执行
source ~/.bash_profile使配置立即生效,后续登录终端会自动切换到高版本 GCC。
2. Ubuntu 升级 GCC(适配 apt 仓库方式)
Ubuntu 无 devtoolset 工具,需通过官方仓库 / PPA 升级,流程如下:
更新系统软件源
先更新本地软件索引,确保能获取最新的 GCC 包:
sudoaptupdate查看可安装的 GCC 版本(可选)
确认系统支持的高版本 GCC:
aptsearch gcc|grep"^gcc-[0-9]"安装指定版本的 GCC(以 9 为例)
安装 GCC 9 及 C++ 编译器(适配 cpp-httplib):
sudoaptinstall-ygcc-9 g++-9设置默认 GCC 版本
Ubuntu 安装后不会自动切换,需手动配置默认版本:
先添加 GCC 候选版本:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-9 90 sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-9 90(数字 90 是优先级,数值越高越优先)
若需切换版本(比如有多个 GCC 版本),执行:
sudoupdate-alternatives--configgccsudoupdate-alternatives--configg++按提示输入对应版本的序号即可。
验证升级结果
执行
gcc -v和g++ -v,确认输出版本为 9.x 即完成升级。
5.2 安装jsoncpp
1. CentOS 7 安装 jsoncpp(仅 yum 方式)
先安装 EPEL 扩展源(CentOS 7 官方源无 jsoncpp):
sudoyuminstall-yepel-release安装 jsoncpp 及开发包(包含头文件和库文件):
sudoyuminstall-yjsoncpp jsoncpp-devel
2. Ubuntu 安装 jsoncpp(仅 apt 方式)
更新软件源索引:
sudoaptupdate安装 jsoncpp 开发包(包含头文件和库文件):
sudoaptinstall-ylibjsoncpp-dev
5.3 安装cpp-httplib
最新的cpp-httplib在使用的时候,如果gcc不是特别新的话有可能会有运行时错误的问题
建议:cpp-httplib 0.7.15。下载zip安装包,上传到服务器即可
cpp-httplib gitee链接:https://gitee.com/yuanfeng1897/cpp-httplib?_from=gitee_search
v0.7.15版本链接: https://gitee.com/yuanfeng1897/cpp-httplib/tree/v0.7.15
# 安装指令gitclone https://gitee.com/yuanfeng1897/cpp-httplib.git5.4 安装boost库
1. CentOS 7 安装 Boost 库(yum 方式)
先安装 EPEL 扩展源(CentOS 7 官方源的 Boost 版本较全,需依赖 EPEL):
sudo yum install -y epel-release安装 Boost 核心库及开发包(包含头文件和编译依赖):
sudo yum install -y boost boost-devel注:若需指定版本(如 Boost 1.7x+),yum 源版本可能偏低,需源码编译,但日常开发用 yum 安装的版本已满足基础需求(如字符串切割)。
2. Ubuntu 安装 Boost 库(apt 方式)
更新软件源索引:
sudo apt update安装 Boost 开发包(包含所有核心模块及头文件):
sudo apt install -y libboost-all-dev注:
libboost-all-dev会安装 Boost 全量模块,若只需特定模块(如仅字符串处理),可替换为
libboost-dev(核心开发包)+ 具体模块(如libboost-string-dev),但推荐直接装全量包避免依赖缺失。
5.5安装ctemplate
1. CentOS 7 安装 ctemplate(yum 方式)
ctemplate 是轻量级的 C++ 前端渲染库,CentOS 7 需先配置 EPEL 源才能通过 yum 安装:
安装 EPEL 扩展源:
sudoyuminstall-yepel-release安装 ctemplate 及开发包(包含头文件和库文件):
sudoyuminstall-yctemplate ctemplate-devel
2. Ubuntu 安装 ctemplate(apt 方式)
Ubuntu 官方源直接提供 ctemplate 包,无需额外配置源:
更新软件源索引:
sudoaptupdate安装 ctemplate 开发包(包含头文件和库文件):
sudoaptinstall-ylibctemplate-dev
5.6 Ace编辑器
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><title>Ace Editor-C++版本</title><style>*{margin:0;padding:0;box-sizing:border-box;}body{padding:20px;font-family:Arial,sans-serif;}/* 编辑器容器必须设置宽高+定位 */#editor{position:relative;width:100%;height:600px;border:1px solid #ddd;border-radius:4px;margin-top:10px;}.title{font-size:18px;font-weight:bold;color:#333;}</style></head><body><divclass="title">C++代码编辑器</div><div id="editor">// C++ 示例代码#include<iostream>#include<string>usingnamespacestd;// 主函数intmain(){string name="Ace Editor";cout<<"Hello, "<<name<<"!"<<endl;// 循环示例for(inti=0;i<5;i++){cout<<"循环次数: "<<i<<endl;}return0;}</div><!--引入 Ace 核心库--><script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.33.1/ace.js"></script><!--引入自动补全扩展--><script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.33.1/ext-language_tools.js"></script><script>// 初始化编辑器consteditor=ace.edit("editor");// 核心配置editor.setTheme("ace/theme/monokai");// 暗黑主题(最常用)editor.session.setMode("ace/mode/c_cpp");// C++ 语法模式editor.setOptions({fontSize:"14px",// 字体大小tabSize:4,// Tab 缩进宽度wrap:true,// 自动换行highlightActiveLine:true,// 高亮当前行showPrintMargin:false,// 隐藏打印边距线enableBasicAutocompletion:true,// 基础自动补全enableLiveAutocompletion:true,// 实时自动补全enableSnippets:true// 代码片段提示});// 监听内容变化(可选)editor.on("change",()=>{console.log("C++ 代码已修改:\n",editor.getValue());});</script></body></html>