尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

详细介绍:负载均衡式的在线OJ项目编写(五)

详细介绍:负载均衡式的在线OJ项目编写(五)
📅 发布时间:2026/6/20 17:30:24

详细介绍:负载均衡式的在线OJ项目编写(五)

2025-10-13 14:11  tlnshuju  阅读(0)  评论(0)    收藏  举报

一.前期内容回顾

对前面的准备不熟悉的,可以看前面的内容,连接如下:

https://blog.csdn.net/weixin_60668256/article/details/152177454?fromshare=blogdetail&sharetype=blogdetail&sharerId=152177454&sharerefer=PC&sharesource=weixin_60668256&sharefrom=from_link

二.负载均衡器的编写

Judge实现思路如下:

/******************************************************* in_json:* id : 100* code : #include...* input : ""******************************************************/void Judge(const std::string in_json,std::string *out_json){//1. in_json进行反序列化,得到题目id,得到用户提交源代码,input//2. 重新拼接用户代码和测试用例代码//3. 选择负载最低的主机(差错处理)//4. 发起http请求,得到结果//5. 将结果赋值给out_json}

我们现在来设计负载均衡器,来选择负载最低的主机

Machine定义的代码:

class Machine{public:std::string ip; //编译服务的ipint port;       //编译服务的portuint64_t load;  //编译服务的负载  -> 负载的增加一定是原子的(引入锁)std::mutex* mtx;//mutex是禁止拷贝的,所以用指针来完成public:Machine():ip(""),port(0),load(0),mtx(nullptr){}~Machine(){}//提升主机负载void IncLoad(){if(mtx){mtx->lock();}load++;if(mtx){mtx->unlock();}}//减少主机负载void DecLoad(){if(mtx){mtx->lock();}load--;if(mtx){mtx->unlock();}}//获取主机负载uint64_t Load(){uint64_t _load = 0;if(mtx){mtx->lock();}_load = load;if(mtx){mtx->unlock();}return _load;}};

2.1LoadConf()函数的完成

bool LoadConf(const std::string& machine_conf){std::ifstream in(machine_conf);if(!in.is_open()){LOG(FATAL) << " 加载: " << machine_conf << "失败" << "\n";return false;}std::string line;while(std::getline(in,line)){std::vector tokens;StringUtil::SplitString(line,&tokens,":");if(tokens.size() != 2){LOG(WARNING) << " 切分 " << line << "失败" << "\n";continue;}Machine m;m.ip = tokens[0];m.port = atoi(tokens[1].c_str());m.load = 0;m.mtx = new std::mutex();online.push_back(machines.size());machines.push_back(m);}in.close();return true;}

2.2SmartChoice()函数的完成

bool SmartChoice(int* id,Machine** m){//1. 使用选择好的主机(更新该主机的负载)//2. 我们需要可能离线该主机mtx.lock();// 负载均衡的算法// 1. 随机数法+hash// 2. 轮询 + hashint online_num = online.size();if(online_num == 0){mtx.unlock();LOG(FATAL) << "所有的后端编译主机已经离线" << "\n";return false;}//遍历的方式找到负载最小的机器*id = online[0];*m = &machines[online[0]];uint64_t min_load = machines[online[0]].Load();for(int i=0;i curr_load){min_load = curr_load;*id = online[i];*m = &machines[online[i]];}}mtx.unlock();return true;}

有了  加载模块  和  选择模块  ,我们现在可以开始编写judge模块

2.3Judge()函数编写

/******************************************************* in_json:* code : #include...* input : ""******************************************************/void Judge(const std::string& number,const std::string in_json,std::string *out_json){//0.根据题目编号,直接拿到对应的题目细节Question q;model_.GetOneQUestion(number,&q);//1. in_json进行反序列化,得到题目id,得到用户提交源代码,inputJson::Reader reader;Json::Value in_value;reader.parse(in_json,in_value);std::string code = in_value["code"].asString();//2. 重新拼接用户代码和测试用例代码Json::Value compile_value;compile_value["input"] = in_value["input"].asString();compile_value["code"] = code + q.tail;compile_value["cpu_limit"] = q.cpu_limit;compile_value["mem_limit"] = q.mem_limit;Json::FastWriter writer;std::string compile_string = writer.write(compile_value);//3. 选择负载最低的主机(差错处理)//规则:一直选择,直到主机可用,否则,就是全部挂掉while(true){int id = 0;Machine* m = nullptr;if(!load_blance_.SmartChoice(&id,&m)){break;}LOG(INFO) << " 选择主机成功,主机id: " << id << "详情: " << m->ip << ":" <port <<"\n";//4. 发起请求,得到结果Client cli(m->ip,m->port);m->IncLoad();if(auto res = cli.Post("/compile_and_run",compile_string,"application/json;charset=utf-8")){//5. 将结果赋值给out_jsonif(res->status == 200){*out_json = res->body;m->DecLoad();LOG(INFO) << "请求编译和运行服务成功... " << "\n";break;}m->DecLoad();}else{//请求失败LOG(ERROR) << " 当前请求的主机id: " << id << "详情: " << m->ip << ":" <port << "可能已经离线" << "\n";load_blance_.OfflineMachine(id);load_blance_.ShowMachines();}}}

2.4OfflineMachine()函数的完成

void OfflineMachine(int id){mtx.lock();for(auto iter = online.begin();iter != online.end();iter++){if(*iter == id){//要离线的主机online.erase(iter);offline.push_back(id);break;//不考虑迭代器失效问题}}mtx.unlock();}

为了测试时,能更好的看到我们离线和在线的主机,我们设计了一个ShowMachines()函数

2.5ShowMachines()函数的实现

//for testvoid ShowMachines(){mtx.lock();std::cout << "当前在线主机列表:";for(auto& id:online){std::cout << id << " ";}std::cout << std::endl;std::cout << "当前离线主机列表:";for(auto& id:offline){std::cout << id << " ";}std::cout << std::endl;mtx.unlock();}

目前为止 我们的LoadBlance类中,还有一个 OnlineMachine() 函数还没有实现

三.postman测试

首先先进行编译

我们要将oj_server和compiler_server都要编译好

但是由于postman一次只能发送一条数据,还没办法检测我们的服务的抗压能力(后续用前端测试)

四.前端代码的编写

后端开发需要关系前端页面吗?不需要! 后续大家不想写,就直接复制粘贴即可

1.任何项目都要有前后端

2.后端虽然不关心页面,但是需要了解,前后端是如何进行交互的

一般编写页面的时候,需要三剑客:html , css , js

后续笔试面试,后续工作,后端不用管前端

4.1丐版的首页

所谓对样式进行调整,本质上是对html中的标签样式进行调整

对html中的标签样式进行调整

1.选中标签

2.设置样式

*号,表示通配符,下面的全部都会使用到这个

页面效果图:

代码实现:

这是我的个人oj系统
首页题库竞赛讨论求职登录注册

欢迎来到我们的OnlineJudge平台

这是我个人独立开发的一个在线OJ平台

点击我开始编程

4.2所有题目的列表

ctempalte渲染的网页,不能直接刷新,要重新启动程序,才能进行显示

网页效果

在线OJ-题目列表
首页题库竞赛讨论求职登录注册

OnlineJudge题目列表

{{#question_list}}{{/question_list}}
编号标题难度
{{number}}{{title}}{{star}}

@xxx大学

@计算机科学与技术学院

4.3指定题目的编写代码的页面 + 代码提交

代码编译器ace插件,直接引入就行

<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js"type="text/javascript"charset="utf-8"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/extlanguage_tools.js"type="text/javascript"charset="utf-8">

</script>

{{number}}.{{title}}<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js" type="text/javascript"charset="utf-8"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/extlanguage_tools.js"type="text/javascript"charset="utf-8"></script>

{{number}}.{{title}}.{{star}}

{{desc}}
<script>//初始化对象editor = ace.edit("code");//设置⻛格和语⾔(更多⻛格和语⾔,请到github上相应⽬录查看)// 主题⼤全:http://www.manongjc.com/detail/25-cfpdrwkkivkikmk.htmleditor.setTheme("ace/theme/monokai");editor.session.setMode("ace/mode/c_cpp");// 字体⼤⼩editor.setFontSize(16);// 设置默认制表符的⼤⼩:editor.getSession().setTabSize(4);// 设置只读(true时只读,⽤于展⽰代码)editor.setReadOnly(false);// 启⽤提⽰菜单ace.require("ace/ext/language_tools");editor.setOptions({enableBasicAutocompletion: true,enableSnippets: true,enableLiveAutocompletion: true});</script>

未完待续

相关新闻

  • 2025年10月冷却塔厂家最新推荐排行榜,闭式冷却塔,开式冷却塔,工业冷却塔,高效节能冷却塔公司推荐!
  • CF1882E1 Two Permutations (Easy Version)
  • 2025年10月实验室净化订做厂家最新推荐排行榜,专业定制与高效服务口碑之选

最新新闻

  • NXP智能门禁平台开发实战:BLE/UWB协同定位、人脸识别与Matter协议集成
  • 2026成都净化车间装修避坑指南:如何筛选靠谱的EPC总包服务商? - 洁净室推广助手
  • 如何快速使用SyncTV:远程同步观影的完整指南
  • Agentic RL基础设施实战地图:从Runtime到演化的四层构建指南
  • HandheldCompanion:5个技巧让你的掌机游戏体验完美升级
  • 如何集成Sidekiq-Statistic到Rails应用:从入门到精通

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号