change judge dispather
This commit is contained in:
parent
6844f5e712
commit
cd90da2b5a
|
@ -32,7 +32,7 @@
|
|||
|
||||
**注意:**
|
||||
|
||||
**1. 正式部署请自行修改配置,不要使用默认配置,例如mysql或redis的密码**
|
||||
**1. 正式部署请自行修改配置,不要使用默认配置的密码,例如mysql、redis、nacos的密码**
|
||||
|
||||
**2. 如果已经为了测试而使用默认配置启动来部署,建议删掉当前文件夹,重新执行以下部署流程,修改默认配置**
|
||||
|
||||
|
|
|
@ -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判题!
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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())
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"),
|
||||
|
|
Loading…
Reference in New Issue