Przeglądaj źródła

执行器新增"注册方式"和"机器地址"属性,支持手动录入机器地址;

xueli.xue 8 lat temu
rodzic
commit
338d3b62a5

+ 6 - 6
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实现;

+ 8 - 5
db/tables_xxl_job.sql

@@ -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;
 

+ 31 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/controller/JobGroupController.java

@@ -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;

+ 19 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/model/XxlJobGroup.java

@@ -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;
+    }
 }

+ 3 - 1
xxl-job-admin/src/main/java/com/xxl/job/admin/core/thread/JobRegistryHelper.java

@@ -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) {

+ 10 - 4
xxl-job-admin/src/main/resources/mybatis-mapper/XxlJobGroupMapper.xml

@@ -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>
 

+ 38 - 6
xxl-job-admin/src/main/webapp/WEB-INF/template/jobgroup/jobgroup.index.ftl

@@ -33,16 +33,17 @@
 							<h3 class="box-title">执行器列表</h3>&nbsp;&nbsp;
                             <button class="btn btn-info btn-xs pull-left2 add" >+新增执行器</button>
                             &nbsp;&nbsp;&nbsp;&nbsp;
-                            调度中心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 />自动注册
+                                &nbsp;&nbsp;&nbsp;&nbsp;
+                                <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" />自动注册
+                                &nbsp;&nbsp;&nbsp;&nbsp;
+                                <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">

+ 21 - 0
xxl-job-admin/src/main/webapp/static/js/jobgroup.index.1.js

@@ -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({

+ 3 - 3
xxl-job-core/src/main/java/com/xxl/job/core/util/IpUtil.java

@@ -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;