执行器新增"注册方式"和"机器地址"属性,支持手动录入机器地址;
This commit is contained in:
parent
a057b2d00e
commit
338d3b62a5
12
README.md
12
README.md
|
@ -732,12 +732,12 @@ Tips: 历史版本(V1.3.x)目前已经Release至稳定版本, 进入维护阶段
|
|||
- 8、GLUE依赖注入逻辑优化,支持别名注入;
|
||||
|
||||
#### 6.11 版本 V1.6.0 特性(CODING)
|
||||
- 1、通讯:hex 通讯调整为 http-rpc 模式;
|
||||
- 2、线程模型统一;
|
||||
- 3、执行器支持手动设置执行地址列表,提供开关切换使用注册地址还是手动设置的地址;
|
||||
- 4、执行器路由规则:第一个、循环、随机、顺序故障(默认)转移;
|
||||
- 5、CleanCode,清理无效的历史参数;
|
||||
- 6、规范系统配置数据,通过配置文件统一管理;
|
||||
- 1、通讯方案升级,原基于HEX的通讯模型调整为基于HTTP的二进制RPC的通讯模型;
|
||||
- 2、规范线程模型统一,统一线程销毁方案;
|
||||
- 3、CleanCode,清理无效的历史参数;
|
||||
- 4、规范系统配置数据,通过配置文件统一管理;
|
||||
- 5、执行器支持手动设置执行地址列表,提供开关切换使用注册地址还是手动设置的地址;
|
||||
- 6、执行器路由规则:第一个、循环、随机、顺序故障(默认)转移;
|
||||
|
||||
#### TODO LIST
|
||||
- 1、支持脚本JOB(源码或指定路径), 即shell/python/php等, 日志实时输出并支持在线监控;定制JobHandler实现;
|
||||
|
|
|
@ -201,14 +201,17 @@ CREATE TABLE XXL_JOB_QRTZ_TRIGGER_REGISTRY (
|
|||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE XXL_JOB_QRTZ_TRIGGER_GROUP (
|
||||
CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_GROUP` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`app_name` varchar(64) NOT NULL,
|
||||
`title` varchar(12) NOT NULL,
|
||||
`order` tinyint(4) NOT NULL,
|
||||
`app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
|
||||
`title` varchar(12) NOT NULL COMMENT '执行器名称',
|
||||
`order` tinyint(4) NOT NULL DEFAULT '0' COMMENT '排序',
|
||||
`address_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
|
||||
`address_list` varchar(200) DEFAULT NULL COMMENT '执行器地址列表,多地址逗号分隔',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
INSERT INTO `XXL_JOB_QRTZ_TRIGGER_GROUP` VALUES ('1', 'xxl-job-executor-example', '示例执行器', '1');
|
||||
|
||||
INSERT INTO `XXL_JOB_QRTZ_TRIGGER_GROUP` ( `app_name`, `title`, `order`, `address_type`, `address_list`) values ( 'xxl-job-executor-example', '示例执行器', '1', '0', null);
|
||||
|
||||
commit;
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
|
@ -40,7 +41,14 @@ public class JobGroupController {
|
|||
|
||||
if (CollectionUtils.isNotEmpty(list)) {
|
||||
for (XxlJobGroup group: list) {
|
||||
List<String> registryList = JobRegistryHelper.discover(RegistHelper.RegistType.EXECUTOR.name(), group.getAppName());
|
||||
List<String> registryList = null;
|
||||
if (group.getAddressType() == 0) {
|
||||
registryList = JobRegistryHelper.discover(RegistHelper.RegistType.EXECUTOR.name(), group.getAppName());
|
||||
} else {
|
||||
if (StringUtils.isNotBlank(group.getAddressList())) {
|
||||
registryList = Arrays.asList(group.getAddressList().split(","));
|
||||
}
|
||||
}
|
||||
group.setRegistryList(registryList);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +72,17 @@ public class JobGroupController {
|
|||
if (xxlJobGroup.getTitle()==null || StringUtils.isBlank(xxlJobGroup.getTitle())) {
|
||||
return new ReturnT<String>(500, "请输入名称");
|
||||
}
|
||||
if (xxlJobGroup.getAddressType()!=0) {
|
||||
if (StringUtils.isBlank(xxlJobGroup.getAddressList())) {
|
||||
return new ReturnT<String>(500, "手动录入注册方式,机器地址不可为空");
|
||||
}
|
||||
String[] addresss = xxlJobGroup.getAddressList().split(",");
|
||||
for (String item: addresss) {
|
||||
if (StringUtils.isBlank(item)) {
|
||||
return new ReturnT<String>(500, "机器地址非法");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ret = xxlJobGroupDao.save(xxlJobGroup);
|
||||
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
|
||||
|
@ -82,6 +101,17 @@ public class JobGroupController {
|
|||
if (xxlJobGroup.getTitle()==null || StringUtils.isBlank(xxlJobGroup.getTitle())) {
|
||||
return new ReturnT<String>(500, "请输入名称");
|
||||
}
|
||||
if (xxlJobGroup.getAddressType()!=0) {
|
||||
if (StringUtils.isBlank(xxlJobGroup.getAddressList())) {
|
||||
return new ReturnT<String>(500, "手动录入注册方式,机器地址不可为空");
|
||||
}
|
||||
String[] addresss = xxlJobGroup.getAddressList().split(",");
|
||||
for (String item: addresss) {
|
||||
if (StringUtils.isBlank(item)) {
|
||||
return new ReturnT<String>(500, "机器地址非法");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ret = xxlJobGroupDao.update(xxlJobGroup);
|
||||
return (ret>0)?ReturnT.SUCCESS:ReturnT.FAIL;
|
||||
|
|
|
@ -11,9 +11,11 @@ public class XxlJobGroup {
|
|||
private String appName;
|
||||
private String title;
|
||||
private int order;
|
||||
private int addressType; // 执行器地址类型:0=自动注册、1=手动录入
|
||||
private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入)
|
||||
|
||||
// registry list
|
||||
private List<String> registryList;
|
||||
private List<String> registryList; // 执行器地址列表(系统注册)
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
@ -54,4 +56,20 @@ public class XxlJobGroup {
|
|||
public void setRegistryList(List<String> registryList) {
|
||||
this.registryList = registryList;
|
||||
}
|
||||
|
||||
public int getAddressType() {
|
||||
return addressType;
|
||||
}
|
||||
|
||||
public void setAddressType(int addressType) {
|
||||
this.addressType = addressType;
|
||||
}
|
||||
|
||||
public String getAddressList() {
|
||||
return addressList;
|
||||
}
|
||||
|
||||
public void setAddressList(String addressList) {
|
||||
this.addressList = addressList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,11 @@ public class JobRegistryHelper {
|
|||
XxlJobDynamicScheduler.xxlJobRegistryDao.registrySave(RegistHelper.RegistType.ADMIN.name(), RegistHelper.RegistType.ADMIN.name(), XxlJobDynamicScheduler.getCallbackAddress());
|
||||
}
|
||||
|
||||
// remove dead admin/executor
|
||||
XxlJobDynamicScheduler.xxlJobRegistryDao.removeDead(RegistHelper.TIMEOUT*2);
|
||||
|
||||
// fresh registry map
|
||||
ConcurrentHashMap<String, List<String>> temp = new ConcurrentHashMap<String, List<String>>();
|
||||
XxlJobDynamicScheduler.xxlJobRegistryDao.removeDead(RegistHelper.TIMEOUT*2);
|
||||
List<XxlJobRegistry> list = XxlJobDynamicScheduler.xxlJobRegistryDao.findAll(RegistHelper.TIMEOUT*2);
|
||||
if (list != null) {
|
||||
for (XxlJobRegistry item: list) {
|
||||
|
|
|
@ -8,13 +8,17 @@
|
|||
<result column="app_name" property="appName" />
|
||||
<result column="title" property="title" />
|
||||
<result column="order" property="order" />
|
||||
<result column="address_type" property="addressType" />
|
||||
<result column="address_list" property="addressList" />
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
t.id,
|
||||
t.app_name,
|
||||
t.title,
|
||||
t.order
|
||||
t.order,
|
||||
t.address_type,
|
||||
t.address_list
|
||||
</sql>
|
||||
|
||||
<select id="findAll" parameterType="java.lang.Integer" resultMap="XxlJobGroup">
|
||||
|
@ -24,15 +28,17 @@
|
|||
</select>
|
||||
|
||||
<insert id="save" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" >
|
||||
INSERT INTO XXL_JOB_QRTZ_TRIGGER_GROUP ( `app_name`, `title`, `order`)
|
||||
values ( #{appName}, #{title}, #{order});
|
||||
INSERT INTO XXL_JOB_QRTZ_TRIGGER_GROUP ( `app_name`, `title`, `order`, `address_type`, `address_list`)
|
||||
values ( #{appName}, #{title}, #{order}, #{addressType}, #{addressList});
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="com.xxl.job.admin.core.model.XxlJobGroup" >
|
||||
UPDATE XXL_JOB_QRTZ_TRIGGER_GROUP
|
||||
SET `app_name` = #{appName},
|
||||
`title` = #{title},
|
||||
`order` = #{order}
|
||||
`order` = #{order},
|
||||
`address_type` = #{addressType},
|
||||
`address_list` = #{addressList}
|
||||
WHERE id = #{id}
|
||||
</update>
|
||||
|
||||
|
|
|
@ -33,16 +33,17 @@
|
|||
<h3 class="box-title">执行器列表</h3>
|
||||
<button class="btn btn-info btn-xs pull-left2 add" >+新增执行器</button>
|
||||
|
||||
调度中心OnLine:<#if adminAddressList?exists><#list adminAddressList as item><span class="badge bg-green">${item}</span></#list></#if>
|
||||
调度中心OnLine机器:<#if adminAddressList?exists><#list adminAddressList as item><span class="badge bg-green">${item}</span></#list></#if>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<table id="joblog_list" class="table table-bordered table-striped display" width="100%" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th name="id" >ID</th>
|
||||
<#--<th name="id" >ID</th>-->
|
||||
<th name="order" >排序</th>
|
||||
<th name="appName" >AppName</th>
|
||||
<th name="title" >名称</th>
|
||||
<th name="order" >排序</th>
|
||||
<th name="addressType" >注册方式</th>
|
||||
<th name="registryList" >OnLine 机器</th>
|
||||
<th name="operate" >操作</th>
|
||||
</tr>
|
||||
|
@ -51,13 +52,20 @@
|
|||
<#if list?exists && list?size gt 0>
|
||||
<#list list as group>
|
||||
<tr>
|
||||
<td>${group.id}</td>
|
||||
<#--<td>${group.id}</td>-->
|
||||
<td>${group.order}</td>
|
||||
<td>${group.appName}</td>
|
||||
<td>${group.title}</td>
|
||||
<td>${group.order}</td>
|
||||
<td><#if group.addressType==0>自动注册<#else>手动录入</#if></td>
|
||||
<td><#if group.registryList?exists><#list group.registryList as item><span class="badge bg-green">${item}</span><br></#list></#if></td>
|
||||
<td>
|
||||
<button class="btn btn-warning btn-xs update" id="${group.id}" appName="${group.appName}" title="${group.title}" order="${group.order}" >编辑</button>
|
||||
<button class="btn btn-warning btn-xs update"
|
||||
id="${group.id}"
|
||||
appName="${group.appName}"
|
||||
title="${group.title}"
|
||||
order="${group.order}"
|
||||
addressType="${group.addressType}"
|
||||
addressList="${group.addressList}" >编辑</button>
|
||||
<button class="btn btn-danger btn-xs remove" id="${group.id}" >删除</button>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -93,6 +101,18 @@
|
|||
<label for="lastname" class="col-sm-2 control-label">排序<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="order" placeholder="请输入“排序”" maxlength="50" ></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">注册方式<font color="red">*</font></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="radio" name="addressType" value="0" checked />自动注册
|
||||
|
||||
<input type="radio" name="addressType" value="1" />手动录入
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">机器地址<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="addressList" placeholder="请输入执行器地址列表,多地址逗号分隔" maxlength="200" readonly="readonly" ></div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-6">
|
||||
|
@ -127,6 +147,18 @@
|
|||
<label for="lastname" class="col-sm-2 control-label">排序<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="order" placeholder="请输入“排序”" maxlength="50" ></div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">注册方式<font color="red">*</font></label>
|
||||
<div class="col-sm-10">
|
||||
<input type="radio" name="addressType" value="0" />自动注册
|
||||
|
||||
<input type="radio" name="addressType" value="1" />手动录入
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="lastname" class="col-sm-2 control-label">机器地址<font color="red">*</font></label>
|
||||
<div class="col-sm-10"><input type="text" class="form-control" name="addressList" placeholder="请输入执行器地址列表,多地址逗号分隔" maxlength="200" readonly="readonly" ></div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-6">
|
||||
|
|
|
@ -107,12 +107,33 @@ $(function() {
|
|||
$("#addModal .form .form-group").removeClass("has-error");
|
||||
});
|
||||
|
||||
// 注册方式,切换
|
||||
$("#addModal input[name=addressType], #updateModal input[name=addressType]").click(function(){
|
||||
var addressType = $(this).val();
|
||||
var $addressList = $(this).parents("form").find("input[name=addressList]");
|
||||
if (addressType == 0) {
|
||||
$addressList.val("");
|
||||
$addressList.attr("readonly","readonly");
|
||||
} else {
|
||||
$addressList.removeAttr("readonly");
|
||||
}
|
||||
});
|
||||
|
||||
// update
|
||||
$('.update').on('click', function(){
|
||||
$("#updateModal .form input[name='id']").val($(this).attr("id"));
|
||||
$("#updateModal .form input[name='appName']").val($(this).attr("appName"));
|
||||
$("#updateModal .form input[name='title']").val($(this).attr("title"));
|
||||
$("#updateModal .form input[name='order']").val($(this).attr("order"));
|
||||
|
||||
// 注册方式
|
||||
var addressType = $(this).attr("addressType");
|
||||
$("#updateModal .form input[name='addressType']").removeAttr('checked');
|
||||
//$("#updateModal .form input[name='addressType'][value='"+ addressType +"']").attr('checked', 'true');
|
||||
$("#updateModal .form input[name='addressType'][value='"+ addressType +"']").click();
|
||||
// 机器地址
|
||||
$("#updateModal .form input[name='addressList']").val($(this).attr("addressList"));
|
||||
|
||||
$('#updateModal').modal({backdrop: false, keyboard: false}).modal('show');
|
||||
});
|
||||
var updateModalValidate = $("#updateModal .form").validate({
|
||||
|
|
|
@ -16,9 +16,9 @@ import java.util.regex.Pattern;
|
|||
public class IpUtil {
|
||||
private static final Logger logger = LoggerFactory.getLogger(IpUtil.class);
|
||||
|
||||
public static final String ANYHOST = "0.0.0.0";
|
||||
public static final String LOCALHOST = "127.0.0.1";
|
||||
private static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
|
||||
private static final String ANYHOST = "0.0.0.0";
|
||||
private static final String LOCALHOST = "127.0.0.1";
|
||||
public static final Pattern IP_PATTERN = Pattern.compile("\\d{1,3}(\\.\\d{1,3}){3,5}$");
|
||||
|
||||
private static volatile InetAddress LOCAL_ADDRESS = null;
|
||||
|
||||
|
|
Loading…
Reference in New Issue