Commit 363cab49 authored by 李丛阳's avatar 李丛阳

任务调度

parent e68a7ec9
......@@ -126,6 +126,8 @@
<version>1.1.0</version>
</dependency>
<!--devTools-->
<dependency>
<groupId>org.springframework.boot</groupId>
......@@ -135,6 +137,23 @@
<!--spring boot mybatis starter end-->
<!--spring boot starter !!!!!!!!!!!!!!!! end -->
<!-- 该依赖必加,里面有sping对schedule的支持
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
......
package org.rcisoft.business.bcode.service;
import org.rcisoft.business.bcode.model.BCodeLxc;
import org.rcisoft.core.result.CommandResult;
/**
* Created by lcy on 18/1/9.
......@@ -12,7 +13,7 @@ public interface BCodeLxcService {
* 打开code 容器
* @param lxc
*/
public void startBCodeLxc(BCodeLxc lxc);
public CommandResult startBCodeLxc(BCodeLxc lxc);
/**
......
package org.rcisoft.business.bcode.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.rcisoft.business.bcode.model.BCodeLxc;
import org.rcisoft.business.bcode.service.BCodeLxcService;
import org.rcisoft.business.bcode.task.StopLxcJob;
import org.rcisoft.common.component.Global;
import org.rcisoft.core.command.LxcCommand;
import org.rcisoft.core.result.CommandResult;
......@@ -10,10 +14,13 @@ import org.rcisoft.core.service.RcRedisService;
import org.rcisoft.core.service.SerializationUtils;
import org.rcisoft.core.util.FreemarkerUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
......@@ -23,6 +30,13 @@ import java.util.Map;
@Slf4j
public class BCodeLxcServiceImpl implements BCodeLxcService {
/*任务组名*/
private static final String JOB_LXC_GROUP = "lxc_job_group";
/*触发器组名*/
private static final String TRIGGER_LXC_GROUP = "lxc_trigger_group";
@Autowired
private RcRedisService rcRedisServiceImpl;
......@@ -32,34 +46,95 @@ public class BCodeLxcServiceImpl implements BCodeLxcService {
@Autowired
private FreemarkerUtil freemarkerUtil;
@Autowired
private SchedulerFactoryBean schedulerFactoryBean;
@Override
public void startBCodeLxc(BCodeLxc lxc) {
public CommandResult startBCodeLxc(BCodeLxc lxc) {
CommandResult result = null;
List<Integer> ports = null;
/*初始化port 20000 - 30000 */
Integer port = global.getLxcInitPort();
Integer maxPort = global.getLxcMaxPort();
byte[] portResult = rcRedisServiceImpl.getBytes("lxcPorts");
if(null != portResult)
ports = SerializationUtils.deserializer(portResult, List.class);
if(null == ports || 0 == ports.size())
ports = new ArrayList<>();
else
port = this.getIdleWithPorts(ports,port,maxPort);
/*端口满了*/
if(0 == port) {
return result;
}
ports.add(port);
/*1.freemarker 生成模板*/
Map param = new HashMap<>();
param.put("lxcName",lxc.getUserId());
param.put("lxcPort",22);
param.put("lxcPort",port);
param.put("lxcPath",lxc.getWorkingDir());
//rcRedisServiceImpl.getBytes("lxcPorts");
/* config path*/
String destPath = global.getBASE_UPLOAD_SERVER_LOCATION() + File.separator +
global.getLxcDockerfilePath() + File.separator + lxc.getUserId() ;
result = freemarkerUtil.generatorFileFromModel(this.getModelProject(lxc.getCode()),destPath
,param);
if(!result.isSuccess())
return;
return result;
/*2.docker-compose 起容器*/
result = LxcCommand.startOrDownLxc("");
result = LxcCommand.startOrDownLxc(destPath);
if(!result.isSuccess())
return;
return result;
/*3.redis 放置状态*/
rcRedisServiceImpl.setBytes(global.getLxcPrefix() + lxc.getUserId(),
SerializationUtils.serializer(lxc));
/*4.定时关闭 */
schedulerFactoryBean.getScheduler();
/*任务参数*/
Map jobParam = new HashMap();
jobParam.put("containerName","_" + lxc.getUserId());
jobParam.put("containerPath",destPath);
jobParam.put("containerPort",port);
JobDetail job = JobBuilder.newJob(StopLxcJob.class).
withIdentity(global.getLxcPrefix() + lxc.getUserId(), JOB_LXC_GROUP).
usingJobData(new JobDataMap(jobParam)).build();
/*5.端口放进去 */
ports.add(port);
rcRedisServiceImpl.setBytes("lxcPorts",
SerializationUtils.serializer(ports));
return result;
}
//SerializationUtils.deserializer(bytes, BCodeLxc.class);
/**
* 获取空闲的端口 加锁 synchronized
* @param ports
* @param port
* @param maxPort
* @return
*/
private synchronized Integer getIdleWithPorts(List<Integer> ports, Integer port, Integer maxPort) {
int choosePort = 0;
/*端口占用满了*/
if(ports.size() -1 == maxPort - port)
return choosePort;
boolean flag = false;
for(int i = port ; i < maxPort - port ; i++){
flag = false;
for (int j = 0 ; j < ports.size() ; j++){
if(port == ports.get(j)) {
flag = true;
break;
}
}
if (flag){
choosePort = port;
break;
}
}
return choosePort;
}
/**
......
package org.rcisoft.business.bcode.task;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.rcisoft.core.command.LxcCommand;
import org.rcisoft.core.result.CommandResult;
import org.rcisoft.core.service.RcRedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
/**
* Created by lcy on 18/1/10.
*/
@Component
@Slf4j
public class StopLxcJob implements Job {
@Autowired
private RcRedisService rcRedisServiceImpl;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
/*1.容器名称*/
String containerName = jobExecutionContext.getMergedJobDataMap().getString("containerName");
String containerPath = jobExecutionContext.getMergedJobDataMap().getString("containerPath");
String containerPort = jobExecutionContext.getMergedJobDataMap().getString("containerPort");
if(StringUtils.isEmpty(containerName) || StringUtils.isEmpty(containerPath)){
log.info("----任务异常----");
return;
}
File filePath = new File(containerPath);
if(!filePath.exists() || !filePath.isDirectory()){
log.info("----任务路径异常----");
return;
}
/*关闭容器*/
/*2.docker-compose 起容器*/
CommandResult commandResult = null;
commandResult = LxcCommand.startOrDownLxc(containerPath,false);
/*3.移除端口*/
}
}
......@@ -243,13 +243,19 @@ public class Global {
/**
* 容器
*/
@Value("${lxc.lxc_prefix")
@Value("${lxc.lxc_prefix}")
private String lxcPrefix;
@Value("${lxc.lxc_ports")
@Value("${lxc.lxc_ports}")
private String lxcPorts;
@Value("${lxc.lxc_dockerfilePath")
@Value("${lxc.lxc_dockerfilePath}")
private String lxcDockerfilePath;
@Value("${lxc.lxc_initPort}")
private Integer lxcInitPort;
@Value("${lxc.lxc_maxPort}")
private Integer lxcMaxPort;
}
package org.rcisoft.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
/**
* Created by lcy on 18/1/10.
*/
@Configuration
public class QuartzConfig {
/**
* attention:
* Details:定义quartz调度工厂
*/
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactory() {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
// 用于quartz集群,QuartzScheduler 启动时更新己存在的Job
bean.setOverwriteExistingJobs(true);
// 延时启动,应用启动1秒后
bean.setStartupDelay(1);
// 注册触发器
//bean.setTriggers(cronJobTrigger);
return bean;
}
}
package org.rcisoft.core.component;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
/**
* Created by lcy on 18/1/10.
*
*
* 注入了一个 自定义的JobFactory ,然后 把其设置为SchedulerFactoryBean 的 JobFactory。
其目的是因为我在具体的Job 中 需要Spring 注入一些Service。
所以我们要自定义一个jobfactory, 让其在具体job 类实例化时 使用Spring 的API 来进行依赖注入。
*/
@Component
public class RcJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
......@@ -13,7 +13,7 @@ server:
druid:
url: jdbc:mysql://127.0.0.1:3306/edu_db?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&useSSL=false
username: root
password: root
password: cy
initial-size: 1
min-idle: 1
max-active: 20
......@@ -71,6 +71,9 @@ spring:
lxc:
lxc_prefix: lessonLxc
lxc_ports: lxcPorts
lxc_dockerfilePath: /eduLxc
lxc_initPort: 20001
lxc_maxPort: 30000
springfox:
documentation:
swagger:
......
......@@ -74,6 +74,9 @@ springfox:
lxc:
lxc_prefix: lessonLxc
lxc_ports: lxcPorts
lxc_dockerfilePath: /eduLxc
lxc_initPort: 20001
lxc_maxPort: 30000
jwt:
header: Authorization
secret: mySecret
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment