【负载均衡式在线OJ】实现负载均衡

devtools/2025/2/9 10:57:52/

目录

管理服务器

增加负载 && 减少负载

重置负载 && 获得负载

负载均衡

添加配置信息

什么是负载均衡

如何实现?


管理服务器

增加负载 && 减少负载

客户端访问一次服务器,负载就加1。客户端结束访问服务器,负载就需要减1。

因为负载是临界资源,存在多台客户端访问同一台服务器的情况,有的客户端要增加服务器的负载,有的客户端要减少服务器的负载,如果不对负载这个临界资源做保护,就会存在数据不一致的情况。

所以需要加锁,保护临界资源。

        // 增加负载void InLoad(){// 判断锁不是空指针if (_mtx)_mtx->lock();++_load;if (_mtx)_mtx->unlock();}// 减少负载void DeLoad(){// 锁不是空指针if (_mtx)_mtx->lock();--_load;if (_mtx)_mtx->unlock();}

重置负载 && 获得负载

如果服务器下线了,就需要重置负载。

当该服务器再次上线时,才可以保证负载是正确的,不受过去数据的影响。

对于获取负载,为了在获取负载时保证数据一致,就需要加锁,如果在加锁后直接 return,就会导致锁没有释放。

为了既保证数据一致,又能释放锁,就需要定义局部变量 load。

        // 重置负载void ResetLoad(){// 锁不是空指针if (_mtx)_mtx->lock();_load = 0;if (_mtx)_mtx->unlock();}// 获取该主机的负载uint64_t Load(){uint64_t load = 0;if (_mtx)_mtx->lock();load = _load;if (_mtx)_mtx->unlock();return load;}

负载均衡

添加配置信息

设置一个配置文件,文件中记录服务器的 IP 和 端口号,为了方便测试,IP 设为环回地址:

什么是负载均衡

通过在多个服务器之间分散工作负载,即使某个服务器出现故障,其他服务器也能继续处理请求,从而提高了系统的可靠性和可用性。负载均衡可以智能地将请求分发给当前负载较低的服务器,这有助于减少响应时间,并提高整体系统性能。

如何实现?

遍历在线列表中的服务器,得出负载最小的服务器,把用户提交的代码和测试用例合并之后,封装成报文发给负载最小的服务器。

  • 如果应答报文为空:在本项目中,服务器下线时不会对外发送退出信号,所以请求服务时,服务器可能已经下线了,如果应答报文为空,说明主机下线了,请求服务失败,此时需要重新选择服务器;
  • 如果应答报文不为空:
    • 如果应答报文的状态码为 200,说明服务器成功编译并运行了报文中的代码,此时不需要再选择服务器了;
    • 如果应答报文的状态码不为 200,说明请求服务失败了,就重新选择服务器。
        // 判题// in_json:用户提交的代码的序列化字符串,out_json:输出型参数,返回判题结果void Judge(const std::string &number, const std::string in_json, std::string *out_json){// 获取对应的题目信息struct Question q;_model.GetOneQuestion(number, &q);Json::Reader reader;Json::Value in_value;reader.parse(in_json, in_value);std::string code = in_value["code"].asString();// 序列化Json::Value compile_value;compile_value["code"] = code + "\n" + q.tail;compile_value["input"] = in_value["input"].asString();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);// 循环式选择主机while (true){// 选择主机Machine *m = nullptr;int id = 0;if (!_loadbalance.SmartChoice(&id, &m)){// 没有主机在线break;}// 得到主机Client cli(m->_ip, m->_port);// 增加负载m->InLoad();LOG(INFO) << " 选择主机成功,主机id:" << id << " 详情:" << m->_ip << ":" << m->_port << " 当前主机的负载是:" << m->Load() << "\n";// 发起请求/// compile_and_run:要请求的资源,auto res = cli.Post("/compile_and_run", compile_string, "application/json;charset=utf-8");if (res){// 请求成功if (res->status == 200)// 判题成功{// 收到判题结果*out_json = res->body;// 减少负载m->DeLoad();LOG(INFO) << "请求编译合运行服务成功..." << "\n";// 得到编译运行结果,判题成功,退出循环break;}// 判题失败,状态码不是200// 减少负载m->DeLoad();// 因为请求结果错误,故继续循环,继续选择主机,继续请求}else{// 请求失败,返回值 res 为 nullptr,可能是主机下线导致的LOG(ERROR) << " 当前请求的主机id:" << id << " 详情:" << m->_ip << ":" << m->_port << " 可能已经离线" << "\n";// 从在线列表中下线该主机_loadbalance.OfflineMachine(id);// 打印日志信息,用于测试_loadbalance.ShowMachines();// 继续循环,继续请求}}


http://www.ppmy.cn/devtools/157330.html

相关文章

驱动开发系列34 - Linux Graphics Intel 动态显存技术的实现

一:概述 动态显存技术(Dynamic Video Memory Technology, DVMT)是一种由 Intel 提出的内存分配技术,主要用于整合显卡(集成显卡)系统中,以便动态地调整显存大小,从而在不同的负载场景下优化内存使用和系统性能。 动态显存技术的核心在于共享系统内存。集成显卡没有独立…

基于html和vue.js以及其他编程技术打造一个仿京东购物网站平台

效果展示 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>仿京东商城</title><link re…

两栏布局、三栏布局、水平垂直居中

文章目录 1 两栏布局1.1 浮动 margin1.2 浮动 BFC1.3 flex布局1.4 左绝父相 margin1.5 右绝父相 方向定位 2 三栏布局2.1 子绝父相 margin2.2 flex布局2.3 浮动 margin2.4 圣杯布局2.5 双飞翼布局 3 水平垂直居中3.1 绝对定位 translate3.2 绝对定位 margin3.3 绝对定位…

Sentinel——Spring Boot 应用接入 Sentinel 后内存开销增长计算方式

接入 Sentinel 对 Spring Boot 应用的内存消耗影响主要取决于 规则数量、资源数量、监控粒度、并发量 等因素。 1. 核心内存消耗来源 (1) Sentinel 核心库 默认依赖&#xff1a;Sentinel Core 本身占用较小&#xff0c;通常在 10~50MB&#xff08;取决于资源数量和规则复杂度…

保姆级AI开发环境搭建

目录 windows下环境搭建1. Python环境搭建2. 下载vLLM2.1 安装CUDA2.2 安装Pytorch2.3 安装vllm 3. 部署Deepseek&#xff08;huggingface&#xff09;3.1 DeepSeek的优化建议 4. ollama快速部署Deepseek4.1 下载Ollama4.2 配置Ollma4.2 运行模型4.3 其他Ollama命令 linux下环境…

被裁与人生的意义--春节随想

还有两个月就要被迫离开工作了十多年的公司了&#xff0c;整个中国分支全部干掉。不过我有幸安安稳稳的过了一个春节&#xff0c;很知足! 分六七批走人&#xff0c;我是最后一批离开&#xff0c;一百多号同事都没“活到”蛇年。看着一批批仁人志士被“秋后斩首”&#xff0c;马…

java 日常下拉框接口字典封装

Operation(description "字典") GetMapping("/dict") public Result dict() {Long userItemId super.getUserItemId();Page<Manure> objectPage new Page<>();objectPage.setSize(100000);objectPage.setCurrent(1);Page<Manure> pag…

YOLOv11-ultralytics-8.3.67部分代码阅读笔记-downloads.py

downloads.py ultralytics\utils\downloads.py 目录 downloads.py 1.所需的库和模块 2.def is_url(url, checkFalse): 3.def delete_dsstore(path, files_to_delete(".DS_Store", "__MACOSX")): 4.def zip_directory(directory, compressTrue, ex…