From cd90da2b5a5b6ba486a95d50951bbf21e562a1d0 Mon Sep 17 00:00:00 2001 From: Himit_ZH <372347736@qq.com> Date: Wed, 22 Dec 2021 13:12:42 +0800 Subject: [PATCH] change judge dispather --- README.md | 2 +- docs/docs/deploy/docker.md | 10 +-- .../top/hcode/hoj/judge/AbstractReceiver.java | 23 +++++++ .../judge/remote/RemoteJudgeDispatcher.java | 7 ++- .../hoj/judge/remote/RemoteJudgeReceiver.java | 63 ++++++++++--------- .../hcode/hoj/judge/self/JudgeDispatcher.java | 9 ++- .../hcode/hoj/judge/self/JudgeReceiver.java | 28 +++++---- .../java/top/hcode/hoj/utils/Constants.java | 22 ++++++- 8 files changed, 115 insertions(+), 49 deletions(-) create mode 100644 hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/AbstractReceiver.java diff --git a/README.md b/README.md index 7c45d332..6a98966b 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ **注意:** -**1. 正式部署请自行修改配置,不要使用默认配置,例如mysql或redis的密码** +**1. 正式部署请自行修改配置,不要使用默认配置的密码,例如mysql、redis、nacos的密码** **2. 如果已经为了测试而使用默认配置启动来部署,建议删掉当前文件夹,重新执行以下部署流程,修改默认配置** diff --git a/docs/docs/deploy/docker.md b/docs/docs/deploy/docker.md index e131aa5a..878f632b 100644 --- a/docs/docs/deploy/docker.md +++ b/docs/docs/deploy/docker.md @@ -2,6 +2,8 @@ > 前提:已经在上一步准备好docker与docker-compose +**注意:如果正式部署运用HOJ,请修改默认配置的密码,例如Redis、MySQL、Nacos的密码!!!** + ## 一、单机部署 1. 选择好需要安装的位置,运行下面命令 @@ -106,7 +108,7 @@ vim docker-compose.yml -如果不改动,则以默认参数启动 +如果不改动,则以默认参数启动(**测试可以不改,但正式部署请修改默认配置的密码!**) ```shell docker-compose up -d @@ -125,9 +127,9 @@ docker ps -a > 以下默认参数说明 - 默认超级管理员账号与密码:root / hoj123456 - - 默认redis密码:hoj123456 - - 默认mysql账号与密码:root / hoj123456 - - 默认nacos管理员账号与密码:root / hoj123456 + - 默认redis密码:hoj123456(**正式部署请修改**) + - 默认mysql账号与密码:root / hoj123456(**正式部署请修改**) + - 默认nacos管理员账号与密码:root / hoj123456(**正式部署请修改**) - 默认不开启https,开启需修改文件同时提供证书文件 - 判题并发数默认:cpu核心数+1 - 默认开启vj判题,需要手动修改添加账号与密码,如果不添加不能vj判题! diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/AbstractReceiver.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/AbstractReceiver.java new file mode 100644 index 00000000..5a3a3e06 --- /dev/null +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/AbstractReceiver.java @@ -0,0 +1,23 @@ +package top.hcode.hoj.judge; + +/** + * @Author: Himit_ZH + * @Date: 2021/12/22 12:40 + * @Description: + */ + +public abstract class AbstractReceiver { + + public void handleWaitingTask(String... queues) { + for (String queue : queues) { + String taskJsonStr = getTaskByRedis(queue); + if (taskJsonStr != null) { + handleJudgeMsg(taskJsonStr); + } + } + } + + public abstract String getTaskByRedis(String queue); + + public abstract void handleJudgeMsg(String taskJsonStr); +} \ No newline at end of file diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeDispatcher.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeDispatcher.java index 156938ba..78652e56 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeDispatcher.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeDispatcher.java @@ -35,7 +35,12 @@ public class RemoteJudgeDispatcher { task.set("tryAgainNum", tryAgainNum); task.set("isHasSubmitIdRemoteReJudge", isHasSubmitIdRemoteReJudge); try { - boolean isOk = redisUtils.llPush(Constants.Judge.STATUS_REMOTE_JUDGE_WAITING_HANDLE.getName(), JSONUtil.toJsonStr(task)); + boolean isOk; + if (isContest){ + isOk = redisUtils.llPush(Constants.Queue.CONTEST_REMOTE_JUDGE_WAITING_HANDLE.getName(), JSONUtil.toJsonStr(task)); + }else{ + isOk = redisUtils.llPush(Constants.Queue.GENERAL_REMOTE_JUDGE_WAITING_HANDLE.getName(), JSONUtil.toJsonStr(task)); + } if (!isOk) { judgeService.updateById(new Judge() .setSubmitId(judge.getSubmitId()) diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeReceiver.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeReceiver.java index 8eb3eacb..406216f3 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeReceiver.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/remote/RemoteJudgeReceiver.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; +import top.hcode.hoj.judge.AbstractReceiver; import top.hcode.hoj.judge.ChooseUtils; import top.hcode.hoj.judge.Dispatcher; import top.hcode.hoj.pojo.entity.judge.Judge; @@ -25,7 +26,7 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; @Component -public class RemoteJudgeReceiver { +public class RemoteJudgeReceiver extends AbstractReceiver { @Autowired private JudgeServiceImpl judgeService; @@ -48,37 +49,43 @@ public class RemoteJudgeReceiver { @Async("judgeTaskAsyncPool") public void processWaitingTask() { - // 如果队列中还有任务,则继续处理 - if (redisUtils.lGetListSize(Constants.Judge.STATUS_REMOTE_JUDGE_WAITING_HANDLE.getName()) > 0) { - String taskJsonStr = (String) redisUtils.lrPop(Constants.Judge.STATUS_REMOTE_JUDGE_WAITING_HANDLE.getName()); - // 再次检查 - if (taskJsonStr != null) { + // 优先处理比赛的提交 + // 其次处理普通提交的提交 + handleWaitingTask(Constants.Queue.CONTEST_REMOTE_JUDGE_WAITING_HANDLE.getName(), + Constants.Queue.GENERAL_REMOTE_JUDGE_WAITING_HANDLE.getName()); + } - JSONObject task = JSONUtil.parseObj(taskJsonStr); - - Judge judge = task.get("judge", Judge.class); - String token = task.getStr("token"); - String remoteJudgeProblem = task.getStr("remoteJudgeProblem"); - Boolean isContest = task.getBool("isContest"); - Integer tryAgainNum = task.getInt("tryAgainNum"); - Boolean isHasSubmitIdRemoteReJudge = task.getBool("isHasSubmitIdRemoteReJudge"); - - String remoteOJName = remoteJudgeProblem.split("-")[0].toUpperCase(); - - handleJudgeMsg(judge, - token, - remoteJudgeProblem, - isContest, - tryAgainNum, - isHasSubmitIdRemoteReJudge, - remoteOJName); - } + @Override + public String getTaskByRedis(String queue) { + if (redisUtils.lGetListSize(queue) > 0) { + return (String) redisUtils.lrPop(queue); + } else { + return null; } } - public void handleJudgeMsg(Judge judge, String token, String remoteJudgeProblem, Boolean isContest, - Integer tryAgainNum, - Boolean isHasSubmitIdRemoteReJudge, String remoteOJName) { + @Override + public void handleJudgeMsg(String taskJsonStr) { + JSONObject task = JSONUtil.parseObj(taskJsonStr); + + Judge judge = task.get("judge", Judge.class); + String token = task.getStr("token"); + String remoteJudgeProblem = task.getStr("remoteJudgeProblem"); + Integer tryAgainNum = task.getInt("tryAgainNum"); + Boolean isHasSubmitIdRemoteReJudge = task.getBool("isHasSubmitIdRemoteReJudge"); + String remoteOJName = remoteJudgeProblem.split("-")[0].toUpperCase(); + + dispatchRemoteJudge(judge, + token, + remoteJudgeProblem, + tryAgainNum, + isHasSubmitIdRemoteReJudge, + remoteOJName); + } + + private void dispatchRemoteJudge(Judge judge, String token, String remoteJudgeProblem, + Integer tryAgainNum, + Boolean isHasSubmitIdRemoteReJudge, String remoteOJName) { ToJudge toJudge = new ToJudge(); toJudge.setJudge(judge) diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeDispatcher.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeDispatcher.java index 2b78476f..900d90da 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeDispatcher.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeDispatcher.java @@ -14,7 +14,7 @@ import top.hcode.hoj.utils.RedisUtils; /** * @Author: Himit_ZH * @Date: 2021/2/5 16:44 - * @Description: 判题信息的发布者,通过主题发布到特定频道内 + * @Description: */ @Component @Slf4j(topic = "hoj") @@ -36,7 +36,12 @@ public class JudgeDispatcher { task.set("isContest", isContest); task.set("tryAgainNum", tryAgainNum); try { - boolean isOk = redisUtils.llPush(Constants.Judge.STATUS_JUDGE_WAITING.getName(), JSONUtil.toJsonStr(task)); + boolean isOk; + if (isContest){ + isOk = redisUtils.llPush(Constants.Queue.CONTEST_JUDGE_WAITING.getName(), JSONUtil.toJsonStr(task)); + }else{ + isOk = redisUtils.llPush(Constants.Queue.GENERAL_JUDGE_WAITING.getName(), JSONUtil.toJsonStr(task)); + } if (!isOk) { judgeService.updateById(new Judge() .setSubmitId(judge.getSubmitId()) diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeReceiver.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeReceiver.java index eb9d42d0..2e6fd18c 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeReceiver.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/judge/self/JudgeReceiver.java @@ -6,6 +6,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Component; +import top.hcode.hoj.judge.AbstractReceiver; import top.hcode.hoj.judge.Dispatcher; import top.hcode.hoj.pojo.entity.judge.Judge; import top.hcode.hoj.pojo.entity.judge.ToJudge; @@ -15,13 +16,11 @@ import top.hcode.hoj.utils.RedisUtils; /** * @Author: Himit_ZH * @Date: 2021/2/5 16:43 - * @Description: 1. 判题信息的接受者,调用判题服务,对提交代码进行判断, - * 2. 若无空闲判题服务器,会自动进入熔断机制,重新将该判题信息发布到频道内, - * 3. 再次接受到信息,再次查询是否有空闲判题服务器,若有则进行判题,否则回到2 + * @Description: */ @Component @Slf4j(topic = "hoj") -public class JudgeReceiver { +public class JudgeReceiver extends AbstractReceiver { @Autowired private Dispatcher dispatcher; @@ -31,16 +30,23 @@ public class JudgeReceiver { @Async("judgeTaskAsyncPool") public void processWaitingTask() { - // 如果队列中还有任务,则继续处理 - if (redisUtils.lGetListSize(Constants.Judge.STATUS_JUDGE_WAITING.getName()) > 0) { - String taskJsonStr = (String) redisUtils.lrPop(Constants.Judge.STATUS_JUDGE_WAITING.getName()); - // 再次检查 - if (taskJsonStr != null) { - handleJudgeMsg(taskJsonStr); - } + // 优先处理比赛的提交 + // 其次处理普通提交的提交 + handleWaitingTask(Constants.Queue.CONTEST_JUDGE_WAITING.getName(), + Constants.Queue.GENERAL_JUDGE_WAITING.getName()); + } + + + @Override + public String getTaskByRedis(String queue) { + if (redisUtils.lGetListSize(queue) > 0) { + return (String) redisUtils.lrPop(queue); + } else { + return null; } } + @Override public void handleJudgeMsg(String taskJsonStr) { JSONObject task = JSONUtil.parseObj(taskJsonStr); diff --git a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/Constants.java b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/Constants.java index 3259f499..47747c24 100644 --- a/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/Constants.java +++ b/hoj-springboot/DataBackup/src/main/java/top/hcode/hoj/utils/Constants.java @@ -29,8 +29,6 @@ public class Constants { STATUS_SUBMITTING(9, "Submitting", null), STATUS_SUBMITTED_FAILED(10, "Submitted Failed", null), STATUS_NULL(15, "No Status", null), - STATUS_JUDGE_WAITING(-100, "Waiting Queue", null), - STATUS_REMOTE_JUDGE_WAITING_HANDLE(-200, "Remote Waiting Handle Queue", null), JUDGE_SERVER_SUBMIT_PREFIX(-1002, "Judge SubmitId-ServerId:", null); private Judge(Integer status, String name, String columnName) { @@ -56,6 +54,26 @@ public class Constants { } } + /** + * 等待判题的redis队列 + * @Since 2021/12/22 + */ + + public enum Queue{ + CONTEST_JUDGE_WAITING("Contest_Waiting_Handle_Queue"), + GENERAL_JUDGE_WAITING("General_Waiting_Handle_Queue"), + CONTEST_REMOTE_JUDGE_WAITING_HANDLE("Contest_Remote_Waiting_Handle_Queue"), + GENERAL_REMOTE_JUDGE_WAITING_HANDLE("General_Remote_Waiting_Handle_Queue"); + + private Queue(String name) { + this.name = name; + } + private final String name; + public String getName() { + return name; + } + } + public enum RemoteOJ { HDU("HDU"), CODEFORCES("CF"),