Browse Source

[Improvement][WorkerGroup] Optimize and reduce database and zookeeper queries and replace worker address input with multiple-select (#5182)

* [Improvement][Server] Optimize and reduce database and ZooKeeper query

* [Improvement][WorkerGroup] Replace worker address input with multiple-select

* [Improvement][WorkerGroup] Fix unit test

* [Improvement][API&UI] Optimize long host to short host and long host display in k8s
pull/3/MERGE
Shiwen Cheng 4 years ago committed by GitHub
parent
commit
1c1f6663a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java
  2. 17
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkerGroupController.java
  3. 1
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java
  4. 7
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/WorkerGroupService.java
  5. 22
      dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkerGroupServiceImpl.java
  6. 3
      dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/NetUtils.java
  7. 2
      dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/NetUtilsTest.java
  8. 10
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java
  9. 23
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/executor/NettyExecutorManager.java
  10. 71
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/CommonHostManager.java
  11. 1
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/HostManager.java
  12. 44
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/LowerWeightHostManager.java
  13. 2
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/RandomHostManager.java
  14. 1
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/RoundRobinHostManager.java
  15. 167
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/registry/ServerNodeManager.java
  16. 11
      dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java
  17. 4
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/consumer/TaskPriorityQueueConsumerTest.java
  18. 9
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/dispatch/ExecutorDispatcherTest.java
  19. 9
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/dispatch/executor/NettyExecutorManagerTest.java
  20. 13
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/dispatch/host/RoundRobinHostManagerTest.java
  21. 33
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/ServerNodeManagerTest.java
  22. 26
      dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/worker/processor/TaskCallbackServiceTest.java
  23. 65
      dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/zk/AbstractZKClient.java
  24. 2
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue
  25. 2
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/_source/list.vue
  26. 50
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/createWorker.vue
  27. 16
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/index.vue
  28. 9
      dolphinscheduler-ui/src/js/conf/home/store/security/actions.js
  29. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  30. 4
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
  31. 2
      pom.xml
  32. 5
      sql/dolphinscheduler_mysql.sql
  33. 5
      sql/dolphinscheduler_postgre.sql
  34. 2
      sql/upgrade/1.3.6_schema/mysql/dolphinscheduler_ddl.sql
  35. 9
      sql/upgrade/1.3.6_schema/postgresql/dolphinscheduler_ddl.sql

8
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/ApiApplicationServer.java

@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.dolphinscheduler.api; package org.apache.dolphinscheduler.api;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
@ -25,15 +26,12 @@ import org.springframework.context.annotation.FilterType;
@SpringBootApplication @SpringBootApplication
@ServletComponentScan @ServletComponentScan
@ComponentScan(basePackages = {"org.apache.dolphinscheduler"}, @ComponentScan(value = "org.apache.dolphinscheduler",
excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = "org.apache.dolphinscheduler.server.*"))
pattern = "org.apache.dolphinscheduler.server.*"))
public class ApiApplicationServer extends SpringBootServletInitializer { public class ApiApplicationServer extends SpringBootServletInitializer {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(ApiApplicationServer.class, args); SpringApplication.run(ApiApplicationServer.class, args);
} }
} }

17
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/WorkerGroupController.java

@ -18,6 +18,7 @@
package org.apache.dolphinscheduler.api.controller; package org.apache.dolphinscheduler.api.controller;
import static org.apache.dolphinscheduler.api.enums.Status.DELETE_WORKER_GROUP_FAIL; import static org.apache.dolphinscheduler.api.enums.Status.DELETE_WORKER_GROUP_FAIL;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_WORKER_ADDRESS_LIST_FAIL;
import static org.apache.dolphinscheduler.api.enums.Status.QUERY_WORKER_GROUP_FAIL; import static org.apache.dolphinscheduler.api.enums.Status.QUERY_WORKER_GROUP_FAIL;
import static org.apache.dolphinscheduler.api.enums.Status.SAVE_ERROR; import static org.apache.dolphinscheduler.api.enums.Status.SAVE_ERROR;
@ -159,4 +160,20 @@ public class WorkerGroupController extends BaseController {
return returnDataList(result); return returnDataList(result);
} }
/**
* query worker address list
*
* @param loginUser login user
* @return all worker address list
*/
@ApiOperation(value = "queryWorkerAddressList", notes = "QUERY_WORKER_ADDRESS_LIST_NOTES")
@GetMapping(value = "/worker-address-list")
@ResponseStatus(HttpStatus.OK)
@ApiException(QUERY_WORKER_ADDRESS_LIST_FAIL)
public Result queryWorkerAddressList(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser) {
logger.info("query worker address list: login user {}", RegexUtils.escapeNRT(loginUser.getUserName()));
Map<String, Object> result = workerGroupService.getWorkerAddressList();
return returnDataList(result);
}
} }

1
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/enums/Status.java

@ -209,6 +209,7 @@ public enum Status {
CREATE_WORKER_GROUP_FORBIDDEN_IN_DOCKER(10175, "create worker group forbidden in docker ", "创建worker分组在docker中禁止"), CREATE_WORKER_GROUP_FORBIDDEN_IN_DOCKER(10175, "create worker group forbidden in docker ", "创建worker分组在docker中禁止"),
DELETE_WORKER_GROUP_FORBIDDEN_IN_DOCKER(10176, "delete worker group forbidden in docker ", "删除worker分组在docker中禁止"), DELETE_WORKER_GROUP_FORBIDDEN_IN_DOCKER(10176, "delete worker group forbidden in docker ", "删除worker分组在docker中禁止"),
WORKER_ADDRESS_INVALID(10177, "worker address {0} invalid", "worker地址[{0}]无效"), WORKER_ADDRESS_INVALID(10177, "worker address {0} invalid", "worker地址[{0}]无效"),
QUERY_WORKER_ADDRESS_LIST_FAIL(10178, "query worker address list fail ", "查询worker地址列表失败"),
UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found", "UDF函数不存在"), UDF_FUNCTION_NOT_EXIST(20001, "UDF function not found", "UDF函数不存在"),
UDF_FUNCTION_EXISTS(20002, "UDF function already exists", "UDF函数已存在"), UDF_FUNCTION_EXISTS(20002, "UDF function already exists", "UDF函数已存在"),

7
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/WorkerGroupService.java

@ -62,4 +62,11 @@ public interface WorkerGroupService {
*/ */
Map<String, Object> deleteWorkerGroupById(User loginUser, Integer id); Map<String, Object> deleteWorkerGroupById(User loginUser, Integer id);
/**
* query all worker address list
*
* @return all worker address list
*/
Map<String, Object> getWorkerAddressList();
} }

22
dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/WorkerGroupServiceImpl.java

@ -81,10 +81,6 @@ public class WorkerGroupServiceImpl extends BaseServiceImpl implements WorkerGro
if (isNotAdmin(loginUser, result)) { if (isNotAdmin(loginUser, result)) {
return result; return result;
} }
if (Constants.DOCKER_MODE && !Constants.KUBERNETES_MODE) {
putMsg(result, Status.CREATE_WORKER_GROUP_FORBIDDEN_IN_DOCKER);
return result;
}
if (StringUtils.isEmpty(name)) { if (StringUtils.isEmpty(name)) {
putMsg(result, Status.NAME_NULL); putMsg(result, Status.NAME_NULL);
return result; return result;
@ -303,10 +299,6 @@ public class WorkerGroupServiceImpl extends BaseServiceImpl implements WorkerGro
if (isNotAdmin(loginUser, result)) { if (isNotAdmin(loginUser, result)) {
return result; return result;
} }
if (Constants.DOCKER_MODE && !Constants.KUBERNETES_MODE) {
putMsg(result, Status.DELETE_WORKER_GROUP_FORBIDDEN_IN_DOCKER);
return result;
}
WorkerGroup workerGroup = workerGroupMapper.selectById(id); WorkerGroup workerGroup = workerGroupMapper.selectById(id);
if (workerGroup == null) { if (workerGroup == null) {
putMsg(result, Status.DELETE_WORKER_GROUP_NOT_EXIST); putMsg(result, Status.DELETE_WORKER_GROUP_NOT_EXIST);
@ -323,4 +315,18 @@ public class WorkerGroupServiceImpl extends BaseServiceImpl implements WorkerGro
return result; return result;
} }
/**
* query all worker address list
*
* @return all worker address list
*/
@Override
public Map<String, Object> getWorkerAddressList() {
Map<String, Object> result = new HashMap<>();
List<String> serverNodeList = zookeeperMonitor.getServerNodeList(ZKNodeType.WORKER, true);
result.put(Constants.DATA_LIST, serverNodeList);
putMsg(result, Status.SUCCESS);
return result;
}
} }

3
dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/NetUtils.java

@ -86,6 +86,9 @@ public class NetUtils {
if (STS_PATTERN.matcher(host).find()) { if (STS_PATTERN.matcher(host).find()) {
return String.format("%s.%s", host, host.replaceFirst("\\d+$", "headless")); return String.format("%s.%s", host, host.replaceFirst("\\d+$", "headless"));
} }
} else if (canonicalHost.contains(".")) {
String[] items = canonicalHost.split("\\.");
return String.format("%s.%s", items[0], items[1]);
} }
return canonicalHost; return canonicalHost;
} }

2
dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/NetUtilsTest.java

@ -50,7 +50,7 @@ public class NetUtilsTest {
when(address.getHostAddress()).thenReturn("172.17.0.15"); when(address.getHostAddress()).thenReturn("172.17.0.15");
assertEquals("172.17.0.15", NetUtils.getHost(address)); assertEquals("172.17.0.15", NetUtils.getHost(address));
CommonTest.setFinalStatic(Constants.class.getDeclaredField("KUBERNETES_MODE"), true); CommonTest.setFinalStatic(Constants.class.getDeclaredField("KUBERNETES_MODE"), true);
assertEquals("dolphinscheduler-worker-0.dolphinscheduler-worker-headless.default.svc.cluster.local", NetUtils.getHost(address)); assertEquals("dolphinscheduler-worker-0.dolphinscheduler-worker-headless", NetUtils.getHost(address));
address = mock(InetAddress.class); address = mock(InetAddress.class);
when(address.getCanonicalHostName()).thenReturn("dolphinscheduler-worker-0"); when(address.getCanonicalHostName()).thenReturn("dolphinscheduler-worker-0");
when(address.getHostName()).thenReturn("dolphinscheduler-worker-0"); when(address.getHostName()).thenReturn("dolphinscheduler-worker-0");

10
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/MasterServer.java

@ -28,7 +28,6 @@ import org.apache.dolphinscheduler.server.master.processor.TaskAckProcessor;
import org.apache.dolphinscheduler.server.master.processor.TaskKillResponseProcessor; import org.apache.dolphinscheduler.server.master.processor.TaskKillResponseProcessor;
import org.apache.dolphinscheduler.server.master.processor.TaskResponseProcessor; import org.apache.dolphinscheduler.server.master.processor.TaskResponseProcessor;
import org.apache.dolphinscheduler.server.master.runner.MasterSchedulerService; import org.apache.dolphinscheduler.server.master.runner.MasterSchedulerService;
import org.apache.dolphinscheduler.server.worker.WorkerServer;
import org.apache.dolphinscheduler.server.zk.ZKMasterClient; import org.apache.dolphinscheduler.server.zk.ZKMasterClient;
import org.apache.dolphinscheduler.service.bean.SpringApplicationContext; import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
import org.apache.dolphinscheduler.service.quartz.QuartzExecutors; import org.apache.dolphinscheduler.service.quartz.QuartzExecutors;
@ -45,8 +44,15 @@ import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType; import org.springframework.context.annotation.FilterType;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* master server
*/
@ComponentScan(value = "org.apache.dolphinscheduler", excludeFilters = { @ComponentScan(value = "org.apache.dolphinscheduler", excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {WorkerServer.class}) @ComponentScan.Filter(type = FilterType.REGEX, pattern = {
"org.apache.dolphinscheduler.server.worker.*",
"org.apache.dolphinscheduler.server.monitor.*",
"org.apache.dolphinscheduler.server.log.*"
})
}) })
@EnableTransactionManagement @EnableTransactionManagement
public class MasterServer implements IStoppable { public class MasterServer implements IStoppable {

23
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/executor/NettyExecutorManager.java

@ -17,8 +17,6 @@
package org.apache.dolphinscheduler.server.master.dispatch.executor; package org.apache.dolphinscheduler.server.master.dispatch.executor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.dolphinscheduler.common.thread.ThreadUtils; import org.apache.dolphinscheduler.common.thread.ThreadUtils;
import org.apache.dolphinscheduler.remote.NettyRemotingClient; import org.apache.dolphinscheduler.remote.NettyRemotingClient;
import org.apache.dolphinscheduler.remote.command.Command; import org.apache.dolphinscheduler.remote.command.Command;
@ -31,17 +29,22 @@ import org.apache.dolphinscheduler.server.master.dispatch.exceptions.ExecuteExce
import org.apache.dolphinscheduler.server.master.processor.TaskAckProcessor; import org.apache.dolphinscheduler.server.master.processor.TaskAckProcessor;
import org.apache.dolphinscheduler.server.master.processor.TaskKillResponseProcessor; import org.apache.dolphinscheduler.server.master.processor.TaskKillResponseProcessor;
import org.apache.dolphinscheduler.server.master.processor.TaskResponseProcessor; import org.apache.dolphinscheduler.server.master.processor.TaskResponseProcessor;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager; import org.apache.dolphinscheduler.server.registry.ServerNodeManager;
import org.apache.commons.collections.CollectionUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.*;
/** /**
* netty executor manager * netty executor manager
*/ */
@ -51,10 +54,10 @@ public class NettyExecutorManager extends AbstractExecutorManager<Boolean>{
private final Logger logger = LoggerFactory.getLogger(NettyExecutorManager.class); private final Logger logger = LoggerFactory.getLogger(NettyExecutorManager.class);
/** /**
* zookeeper node manager * server node manager
*/ */
@Autowired @Autowired
private ZookeeperNodeManager zookeeperNodeManager; private ServerNodeManager serverNodeManager;
/** /**
* netty remote client * netty remote client
@ -182,7 +185,7 @@ public class NettyExecutorManager extends AbstractExecutorManager<Boolean>{
ExecutorType executorType = context.getExecutorType(); ExecutorType executorType = context.getExecutorType();
switch (executorType){ switch (executorType){
case WORKER: case WORKER:
nodes = zookeeperNodeManager.getWorkerGroupNodes(context.getWorkerGroup()); nodes = serverNodeManager.getWorkerGroupNodes(context.getWorkerGroup());
break; break;
case CLIENT: case CLIENT:
break; break;

71
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/CommonHostManager.java

@ -18,55 +18,32 @@
package org.apache.dolphinscheduler.server.master.dispatch.host; package org.apache.dolphinscheduler.server.master.dispatch.host;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.ZKNodeType;
import org.apache.dolphinscheduler.common.utils.CollectionUtils; import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.ResInfo; import org.apache.dolphinscheduler.common.utils.ResInfo;
import org.apache.dolphinscheduler.common.utils.StringUtils; import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.dao.entity.WorkerGroup;
import org.apache.dolphinscheduler.dao.mapper.WorkerGroupMapper;
import org.apache.dolphinscheduler.remote.utils.Host; import org.apache.dolphinscheduler.remote.utils.Host;
import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext; import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext;
import org.apache.dolphinscheduler.server.master.dispatch.enums.ExecutorType; import org.apache.dolphinscheduler.server.master.dispatch.enums.ExecutorType;
import org.apache.dolphinscheduler.server.master.dispatch.host.assign.HostWorker; import org.apache.dolphinscheduler.server.master.dispatch.host.assign.HostWorker;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager; import org.apache.dolphinscheduler.server.registry.ServerNodeManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.server.zk.ZKMasterClient;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
/** /**
* round robin host manager * common host manager
*/ */
public abstract class CommonHostManager implements HostManager { public abstract class CommonHostManager implements HostManager {
/** /**
* zookeeper registry center * server node manager
*/ */
@Autowired @Autowired
protected ZookeeperRegistryCenter registryCenter; protected ServerNodeManager serverNodeManager;
/**
* zookeeper node manager
*/
@Autowired
protected ZookeeperNodeManager zookeeperNodeManager;
/**
* zk master client
*/
@Autowired
protected ZKMasterClient zkMasterClient;
/**
* worker group mapper
*/
@Autowired
protected WorkerGroupMapper workerGroupMapper;
/** /**
* select host * select host
@ -80,10 +57,7 @@ public abstract class CommonHostManager implements HostManager {
ExecutorType executorType = context.getExecutorType(); ExecutorType executorType = context.getExecutorType();
switch (executorType) { switch (executorType) {
case WORKER: case WORKER:
candidates = getHostWorkersFromDatabase(workerGroup); candidates = getWorkerCandidates(workerGroup);
if (candidates.isEmpty()) {
candidates = getHostWorkersFromZookeeper(workerGroup);
}
break; break;
case CLIENT: case CLIENT:
break; break;
@ -99,31 +73,12 @@ public abstract class CommonHostManager implements HostManager {
protected abstract HostWorker select(Collection<HostWorker> nodes); protected abstract HostWorker select(Collection<HostWorker> nodes);
protected List<HostWorker> getHostWorkersFromDatabase(String workerGroup) { protected List<HostWorker> getWorkerCandidates(String workerGroup) {
List<HostWorker> hostWorkers = new ArrayList<>(); List<HostWorker> hostWorkers = new ArrayList<>();
List<WorkerGroup> workerGroups = workerGroupMapper.queryWorkerGroupByName(workerGroup); Set<String> nodes = serverNodeManager.getWorkerGroupNodes(workerGroup);
if (CollectionUtils.isNotEmpty(workerGroups)) {
Map<String, String> serverMaps = zkMasterClient.getServerMaps(ZKNodeType.WORKER, true);
for (WorkerGroup wg : workerGroups) {
for (String addr : wg.getAddrList().split(Constants.COMMA)) {
if (serverMaps.containsKey(addr)) {
String heartbeat = serverMaps.get(addr);
int hostWeight = getWorkerHostWeightFromHeartbeat(heartbeat);
hostWorkers.add(HostWorker.of(addr, hostWeight, workerGroup));
}
}
}
}
return hostWorkers;
}
protected List<HostWorker> getHostWorkersFromZookeeper(String workerGroup) {
List<HostWorker> hostWorkers = new ArrayList<>();
Collection<String> nodes = zookeeperNodeManager.getWorkerGroupNodes(workerGroup);
if (CollectionUtils.isNotEmpty(nodes)) { if (CollectionUtils.isNotEmpty(nodes)) {
for (String node : nodes) { for (String node : nodes) {
String workerGroupPath = registryCenter.getWorkerGroupPath(workerGroup); String heartbeat = serverNodeManager.getWorkerNodeInfo(node);
String heartbeat = registryCenter.getRegisterOperator().get(workerGroupPath + "/" + node);
int hostWeight = getWorkerHostWeightFromHeartbeat(heartbeat); int hostWeight = getWorkerHostWeightFromHeartbeat(heartbeat);
hostWorkers.add(HostWorker.of(node, hostWeight, workerGroup)); hostWorkers.add(HostWorker.of(node, hostWeight, workerGroup));
} }
@ -142,12 +97,4 @@ public abstract class CommonHostManager implements HostManager {
return hostWeight; return hostWeight;
} }
public void setZookeeperNodeManager(ZookeeperNodeManager zookeeperNodeManager) {
this.zookeeperNodeManager = zookeeperNodeManager;
}
public ZookeeperNodeManager getZookeeperNodeManager() {
return zookeeperNodeManager;
}
} }

1
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/HostManager.java

@ -17,7 +17,6 @@
package org.apache.dolphinscheduler.server.master.dispatch.host; package org.apache.dolphinscheduler.server.master.dispatch.host;
import org.apache.dolphinscheduler.remote.utils.Host; import org.apache.dolphinscheduler.remote.utils.Host;
import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext; import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext;

44
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/LowerWeightHostManager.java

@ -18,11 +18,9 @@
package org.apache.dolphinscheduler.server.master.dispatch.host; package org.apache.dolphinscheduler.server.master.dispatch.host;
import org.apache.dolphinscheduler.common.Constants; import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.common.enums.ZKNodeType;
import org.apache.dolphinscheduler.common.utils.CollectionUtils; import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.DateUtils; import org.apache.dolphinscheduler.common.utils.DateUtils;
import org.apache.dolphinscheduler.common.utils.ResInfo; import org.apache.dolphinscheduler.common.utils.ResInfo;
import org.apache.dolphinscheduler.dao.entity.WorkerGroup;
import org.apache.dolphinscheduler.remote.utils.Host; import org.apache.dolphinscheduler.remote.utils.Host;
import org.apache.dolphinscheduler.remote.utils.NamedThreadFactory; import org.apache.dolphinscheduler.remote.utils.NamedThreadFactory;
import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext; import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext;
@ -30,11 +28,9 @@ import org.apache.dolphinscheduler.server.master.dispatch.host.assign.HostWeight
import org.apache.dolphinscheduler.server.master.dispatch.host.assign.HostWorker; import org.apache.dolphinscheduler.server.master.dispatch.host.assign.HostWorker;
import org.apache.dolphinscheduler.server.master.dispatch.host.assign.LowerWeightRoundRobin; import org.apache.dolphinscheduler.server.master.dispatch.host.assign.LowerWeightRoundRobin;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -51,17 +47,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* round robin host manager * lower weight host manager
*/ */
public class LowerWeightHostManager extends CommonHostManager { public class LowerWeightHostManager extends CommonHostManager {
private final Logger logger = LoggerFactory.getLogger(LowerWeightHostManager.class); private final Logger logger = LoggerFactory.getLogger(LowerWeightHostManager.class);
/**
* round robin host manager
*/
private RoundRobinHostManager roundRobinHostManager;
/** /**
* selector * selector
*/ */
@ -89,8 +80,6 @@ public class LowerWeightHostManager extends CommonHostManager {
this.lock = new ReentrantLock(); this.lock = new ReentrantLock();
this.executorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("LowerWeightHostManagerExecutor")); this.executorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("LowerWeightHostManagerExecutor"));
this.executorService.scheduleWithFixedDelay(new RefreshResourceTask(),0, 5, TimeUnit.SECONDS); this.executorService.scheduleWithFixedDelay(new RefreshResourceTask(),0, 5, TimeUnit.SECONDS);
this.roundRobinHostManager = new RoundRobinHostManager();
this.roundRobinHostManager.setZookeeperNodeManager(getZookeeperNodeManager());
} }
@PreDestroy @PreDestroy
@ -142,43 +131,22 @@ public class LowerWeightHostManager extends CommonHostManager {
public void run() { public void run() {
try { try {
Map<String, Set<HostWeight>> workerHostWeights = new HashMap<>(); Map<String, Set<HostWeight>> workerHostWeights = new HashMap<>();
// from database Map<String, Set<String>> workerGroupNodes = serverNodeManager.getWorkerGroupNodes();
List<WorkerGroup> workerGroups = workerGroupMapper.queryAllWorkerGroup(); for (Map.Entry<String, Set<String>> entry : workerGroupNodes.entrySet()) {
if (CollectionUtils.isNotEmpty(workerGroups)) {
Map<String, String> serverMaps = zkMasterClient.getServerMaps(ZKNodeType.WORKER, true);
for (WorkerGroup wg : workerGroups) {
String workerGroup = wg.getName();
List<String> addrs = Arrays.asList(wg.getAddrList().split(Constants.COMMA));
Set<HostWeight> hostWeights = new HashSet<>(addrs.size());
for (String addr : addrs) {
if (serverMaps.containsKey(addr)) {
String heartbeat = serverMaps.get(addr);
HostWeight hostWeight = getHostWeight(addr, workerGroup, heartbeat);
if (hostWeight != null) {
hostWeights.add(hostWeight);
}
}
}
workerHostWeights.put(workerGroup, hostWeights);
}
}
// from zookeeper
Map<String, Set<String>> workerGroupNodes = zookeeperNodeManager.getWorkerGroupNodes();
Set<Map.Entry<String, Set<String>>> entries = workerGroupNodes.entrySet();
for (Map.Entry<String, Set<String>> entry : entries) {
String workerGroup = entry.getKey(); String workerGroup = entry.getKey();
Set<String> nodes = entry.getValue(); Set<String> nodes = entry.getValue();
String workerGroupPath = registryCenter.getWorkerGroupPath(workerGroup);
Set<HostWeight> hostWeights = new HashSet<>(nodes.size()); Set<HostWeight> hostWeights = new HashSet<>(nodes.size());
for (String node : nodes) { for (String node : nodes) {
String heartbeat = registryCenter.getRegisterOperator().get(workerGroupPath + "/" + node); String heartbeat = serverNodeManager.getWorkerNodeInfo(node);
HostWeight hostWeight = getHostWeight(node, workerGroup, heartbeat); HostWeight hostWeight = getHostWeight(node, workerGroup, heartbeat);
if (hostWeight != null) { if (hostWeight != null) {
hostWeights.add(hostWeight); hostWeights.add(hostWeight);
} }
} }
if (!hostWeights.isEmpty()) {
workerHostWeights.put(workerGroup, hostWeights); workerHostWeights.put(workerGroup, hostWeights);
} }
}
syncWorkerHostWeight(workerHostWeights); syncWorkerHostWeight(workerHostWeights);
} catch (Throwable ex) { } catch (Throwable ex) {
logger.error("RefreshResourceTask error", ex); logger.error("RefreshResourceTask error", ex);

2
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/RandomHostManager.java

@ -23,7 +23,7 @@ import org.apache.dolphinscheduler.server.master.dispatch.host.assign.RandomSele
import java.util.Collection; import java.util.Collection;
/** /**
* round robin host manager * random host manager
*/ */
public class RandomHostManager extends CommonHostManager { public class RandomHostManager extends CommonHostManager {

1
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/master/dispatch/host/RoundRobinHostManager.java

@ -22,7 +22,6 @@ import org.apache.dolphinscheduler.server.master.dispatch.host.assign.RoundRobin
import java.util.Collection; import java.util.Collection;
/** /**
* round robin host manager * round robin host manager
*/ */

167
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/registry/ZookeeperNodeManager.java → dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/registry/ServerNodeManager.java

@ -17,36 +17,49 @@
package org.apache.dolphinscheduler.server.registry; package org.apache.dolphinscheduler.server.registry;
import org.apache.commons.collections.CollectionUtils; import org.apache.dolphinscheduler.common.Constants;
import org.apache.curator.framework.CuratorFramework; import org.apache.dolphinscheduler.common.enums.ZKNodeType;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.dolphinscheduler.common.utils.StringUtils; import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.dao.AlertDao; import org.apache.dolphinscheduler.dao.AlertDao;
import org.apache.dolphinscheduler.dao.entity.WorkerGroup;
import org.apache.dolphinscheduler.dao.mapper.WorkerGroupMapper;
import org.apache.dolphinscheduler.remote.utils.NamedThreadFactory;
import org.apache.dolphinscheduler.service.zk.AbstractListener; import org.apache.dolphinscheduler.service.zk.AbstractListener;
import org.slf4j.Logger; import org.apache.dolphinscheduler.service.zk.AbstractZKClient;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean; import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.apache.curator.framework.CuratorFramework;
import org.springframework.stereotype.Service; import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import static org.apache.dolphinscheduler.common.Constants.DEFAULT_WORKER_GROUP; import javax.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
/** /**
* zookeeper node manager * server node manager
*/ */
@Service @Service
public class ZookeeperNodeManager implements InitializingBean { public class ServerNodeManager implements InitializingBean {
private final Logger logger = LoggerFactory.getLogger(ZookeeperNodeManager.class); private final Logger logger = LoggerFactory.getLogger(ServerNodeManager.class);
/** /**
* master lock * master lock
@ -58,6 +71,11 @@ public class ZookeeperNodeManager implements InitializingBean {
*/ */
private final Lock workerGroupLock = new ReentrantLock(); private final Lock workerGroupLock = new ReentrantLock();
/**
* worker node info lock
*/
private final Lock workerNodeInfoLock = new ReentrantLock();
/** /**
* worker group nodes * worker group nodes
*/ */
@ -68,12 +86,34 @@ public class ZookeeperNodeManager implements InitializingBean {
*/ */
private final Set<String> masterNodes = new HashSet<>(); private final Set<String> masterNodes = new HashSet<>();
/**
* worker node info
*/
private final Map<String, String> workerNodeInfo = new HashMap<>();
/**
* executor service
*/
private ScheduledExecutorService executorService;
/**
* zk client
*/
@Autowired
private ZKClient zkClient;
/** /**
* zookeeper registry center * zookeeper registry center
*/ */
@Autowired @Autowired
private ZookeeperRegistryCenter registryCenter; private ZookeeperRegistryCenter registryCenter;
/**
* worker group mapper
*/
@Autowired
private WorkerGroupMapper workerGroupMapper;
/** /**
* alert dao * alert dao
*/ */
@ -90,6 +130,11 @@ public class ZookeeperNodeManager implements InitializingBean {
* load nodes from zookeeper * load nodes from zookeeper
*/ */
load(); load();
/**
* init executor service
*/
executorService = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("ServerNodeManagerExecutor"));
executorService.scheduleWithFixedDelay(new WorkerNodeInfoAndGroupDbSyncTask(), 0, 10, TimeUnit.SECONDS);
/** /**
* init MasterNodeListener listener * init MasterNodeListener listener
*/ */
@ -107,8 +152,8 @@ public class ZookeeperNodeManager implements InitializingBean {
/** /**
* master nodes from zookeeper * master nodes from zookeeper
*/ */
Set<String> masterNodes = registryCenter.getMasterNodesDirectly(); Set<String> initMasterNodes = registryCenter.getMasterNodesDirectly();
syncMasterNodes(masterNodes); syncMasterNodes(initMasterNodes);
/** /**
* worker group nodes from zookeeper * worker group nodes from zookeeper
@ -119,6 +164,43 @@ public class ZookeeperNodeManager implements InitializingBean {
} }
} }
/**
* zookeeper client
*/
@Component
static class ZKClient extends AbstractZKClient {}
/**
* worker node info and worker group db sync task
*/
class WorkerNodeInfoAndGroupDbSyncTask implements Runnable {
@Override
public void run() {
// sync worker node info
Map<String, String> newWorkerNodeInfo = zkClient.getServerMaps(ZKNodeType.WORKER, true);
syncWorkerNodeInfo(newWorkerNodeInfo);
// sync worker group nodes from database
List<WorkerGroup> workerGroupList = workerGroupMapper.queryAllWorkerGroup();
if (CollectionUtils.isNotEmpty(workerGroupList)) {
for (WorkerGroup wg : workerGroupList) {
String workerGroup = wg.getName();
Set<String> nodes = new HashSet<>();
String[] addrs = wg.getAddrList().split(Constants.COMMA);
for (String addr : addrs) {
if (newWorkerNodeInfo.containsKey(addr)) {
nodes.add(addr);
}
}
if (!nodes.isEmpty()) {
syncWorkerGroupNodes(workerGroup, nodes);
}
}
}
}
}
/** /**
* worker group node listener * worker group node listener
*/ */
@ -141,8 +223,8 @@ public class ZookeeperNodeManager implements InitializingBean {
syncWorkerGroupNodes(group, currentNodes); syncWorkerGroupNodes(group, currentNodes);
alertDao.sendServerStopedAlert(1, path, "WORKER"); alertDao.sendServerStopedAlert(1, path, "WORKER");
} }
} catch (IllegalArgumentException ignore) { } catch (IllegalArgumentException ex) {
logger.warn(ignore.getMessage()); logger.warn(ex.getMessage());
} catch (Exception ex) { } catch (Exception ex) {
logger.error("WorkerGroupListener capture data change and get data failed", ex); logger.error("WorkerGroupListener capture data change and get data failed", ex);
} }
@ -150,16 +232,14 @@ public class ZookeeperNodeManager implements InitializingBean {
} }
private String parseGroup(String path) { private String parseGroup(String path) {
String[] parts = path.split("\\/"); String[] parts = path.split("/");
if (parts.length < 6) { if (parts.length < 6) {
throw new IllegalArgumentException(String.format("worker group path : %s is not valid, ignore", path)); throw new IllegalArgumentException(String.format("worker group path : %s is not valid, ignore", path));
} }
String group = parts[parts.length - 2]; return parts[parts.length - 2];
return group;
} }
} }
/** /**
* master node listener * master node listener
*/ */
@ -244,7 +324,7 @@ public class ZookeeperNodeManager implements InitializingBean {
workerGroupLock.lock(); workerGroupLock.lock();
try { try {
if (StringUtils.isEmpty(workerGroup)) { if (StringUtils.isEmpty(workerGroup)) {
workerGroup = DEFAULT_WORKER_GROUP; workerGroup = Constants.DEFAULT_WORKER_GROUP;
} }
workerGroup = workerGroup.toLowerCase(); workerGroup = workerGroup.toLowerCase();
Set<String> nodes = workerGroupNodes.get(workerGroup); Set<String> nodes = workerGroupNodes.get(workerGroup);
@ -258,9 +338,48 @@ public class ZookeeperNodeManager implements InitializingBean {
} }
/** /**
* close * get worker node info
* @return worker node info
*/ */
public void close(){ public Map<String, String> getWorkerNodeInfo() {
return Collections.unmodifiableMap(workerNodeInfo);
}
/**
* get worker node info
* @param workerNode worker node
* @return worker node info
*/
public String getWorkerNodeInfo(String workerNode) {
workerNodeInfoLock.lock();
try {
return workerNodeInfo.getOrDefault(workerNode, null);
} finally {
workerNodeInfoLock.unlock();
}
}
/**
* sync worker node info
* @param newWorkerNodeInfo new worker node info
*/
private void syncWorkerNodeInfo(Map<String, String> newWorkerNodeInfo) {
workerNodeInfoLock.lock();
try {
workerNodeInfo.clear();
workerNodeInfo.putAll(newWorkerNodeInfo);
} finally {
workerNodeInfoLock.unlock();
}
}
/**
* destroy
*/
@PreDestroy
public void destroy() {
executorService.shutdownNow();
registryCenter.close(); registryCenter.close();
} }
} }

11
dolphinscheduler-server/src/main/java/org/apache/dolphinscheduler/server/worker/WorkerServer.java

@ -45,12 +45,21 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.WebApplicationType; import org.springframework.boot.WebApplicationType;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.EnableTransactionManagement;
/** /**
* worker server * worker server
*/ */
@ComponentScan("org.apache.dolphinscheduler") @ComponentScan(value = "org.apache.dolphinscheduler", excludeFilters = {
@ComponentScan.Filter(type = FilterType.REGEX, pattern = {
"org.apache.dolphinscheduler.server.master.*",
"org.apache.dolphinscheduler.server.monitor.*",
"org.apache.dolphinscheduler.server.log.*",
"org.apache.dolphinscheduler.server.zk.ZKMasterClient",
"org.apache.dolphinscheduler.server.registry.ServerNodeManager"
})
})
@EnableTransactionManagement @EnableTransactionManagement
public class WorkerServer implements IStoppable { public class WorkerServer implements IStoppable {

4
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/consumer/TaskPriorityQueueConsumerTest.java

@ -39,7 +39,7 @@ import org.apache.dolphinscheduler.server.master.dispatch.ExecutorDispatcher;
import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager; import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager;
import org.apache.dolphinscheduler.server.master.registry.MasterRegistry; import org.apache.dolphinscheduler.server.master.registry.MasterRegistry;
import org.apache.dolphinscheduler.server.registry.DependencyConfig; import org.apache.dolphinscheduler.server.registry.DependencyConfig;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager; import org.apache.dolphinscheduler.server.registry.ServerNodeManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter; import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.server.zk.SpringZKServer; import org.apache.dolphinscheduler.server.zk.SpringZKServer;
import org.apache.dolphinscheduler.server.zk.ZKMasterClient; import org.apache.dolphinscheduler.server.zk.ZKMasterClient;
@ -70,7 +70,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {DependencyConfig.class, SpringApplicationContext.class, SpringZKServer.class, CuratorZookeeperClient.class, @ContextConfiguration(classes = {DependencyConfig.class, SpringApplicationContext.class, SpringZKServer.class, CuratorZookeeperClient.class,
NettyExecutorManager.class, ExecutorDispatcher.class, ZookeeperRegistryCenter.class, ZKMasterClient.class, TaskPriorityQueueConsumer.class, NettyExecutorManager.class, ExecutorDispatcher.class, ZookeeperRegistryCenter.class, ZKMasterClient.class, TaskPriorityQueueConsumer.class,
ZookeeperNodeManager.class, RegisterOperator.class, ZookeeperConfig.class, MasterConfig.class, MasterRegistry.class, ServerNodeManager.class, RegisterOperator.class, ZookeeperConfig.class, MasterConfig.class, MasterRegistry.class,
CuratorZookeeperClient.class, SpringConnectionFactory.class}) CuratorZookeeperClient.class, SpringConnectionFactory.class})
public class TaskPriorityQueueConsumerTest { public class TaskPriorityQueueConsumerTest {

9
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/dispatch/ExecutorDispatcherTest.java

@ -14,16 +14,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.dolphinscheduler.server.master.dispatch;
package org.apache.dolphinscheduler.server.master.dispatch;
import org.apache.dolphinscheduler.dao.datasource.SpringConnectionFactory;
import org.apache.dolphinscheduler.remote.NettyRemotingServer; import org.apache.dolphinscheduler.remote.NettyRemotingServer;
import org.apache.dolphinscheduler.remote.config.NettyServerConfig; import org.apache.dolphinscheduler.remote.config.NettyServerConfig;
import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext; import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext;
import org.apache.dolphinscheduler.server.master.dispatch.exceptions.ExecuteException; import org.apache.dolphinscheduler.server.master.dispatch.exceptions.ExecuteException;
import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager; import org.apache.dolphinscheduler.server.master.dispatch.executor.NettyExecutorManager;
import org.apache.dolphinscheduler.server.registry.DependencyConfig; import org.apache.dolphinscheduler.server.registry.DependencyConfig;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager; import org.apache.dolphinscheduler.server.registry.ServerNodeManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter; import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.server.utils.ExecutionContextTestUtils; import org.apache.dolphinscheduler.server.utils.ExecutionContextTestUtils;
import org.apache.dolphinscheduler.server.worker.config.WorkerConfig; import org.apache.dolphinscheduler.server.worker.config.WorkerConfig;
@ -34,6 +35,7 @@ import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
import org.apache.dolphinscheduler.service.zk.CuratorZookeeperClient; import org.apache.dolphinscheduler.service.zk.CuratorZookeeperClient;
import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator; import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator;
import org.apache.dolphinscheduler.service.zk.ZookeeperConfig; import org.apache.dolphinscheduler.service.zk.ZookeeperConfig;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.Mockito; import org.mockito.Mockito;
@ -47,7 +49,8 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={DependencyConfig.class, SpringApplicationContext.class, SpringZKServer.class, WorkerRegistry.class, @ContextConfiguration(classes={DependencyConfig.class, SpringApplicationContext.class, SpringZKServer.class, WorkerRegistry.class,
NettyExecutorManager.class, ExecutorDispatcher.class, ZookeeperRegistryCenter.class, WorkerConfig.class, NettyExecutorManager.class, ExecutorDispatcher.class, ZookeeperRegistryCenter.class, WorkerConfig.class,
ZookeeperNodeManager.class, ZookeeperCachedOperator.class, ZookeeperConfig.class, CuratorZookeeperClient.class}) ServerNodeManager.class, ZookeeperCachedOperator.class, ZookeeperConfig.class, CuratorZookeeperClient.class,
SpringConnectionFactory.class})
public class ExecutorDispatcherTest { public class ExecutorDispatcherTest {
@Autowired @Autowired

9
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/dispatch/executor/NettyExecutorManagerTest.java

@ -18,6 +18,7 @@ package org.apache.dolphinscheduler.server.master.dispatch.executor;
import org.apache.dolphinscheduler.common.enums.CommandType; import org.apache.dolphinscheduler.common.enums.CommandType;
import org.apache.dolphinscheduler.common.utils.NetUtils; import org.apache.dolphinscheduler.common.utils.NetUtils;
import org.apache.dolphinscheduler.dao.datasource.SpringConnectionFactory;
import org.apache.dolphinscheduler.dao.entity.ProcessDefinition; import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.ProcessInstance; import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
import org.apache.dolphinscheduler.dao.entity.TaskInstance; import org.apache.dolphinscheduler.dao.entity.TaskInstance;
@ -30,7 +31,7 @@ import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionConte
import org.apache.dolphinscheduler.server.master.dispatch.enums.ExecutorType; import org.apache.dolphinscheduler.server.master.dispatch.enums.ExecutorType;
import org.apache.dolphinscheduler.server.master.dispatch.exceptions.ExecuteException; import org.apache.dolphinscheduler.server.master.dispatch.exceptions.ExecuteException;
import org.apache.dolphinscheduler.server.registry.DependencyConfig; import org.apache.dolphinscheduler.server.registry.DependencyConfig;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager; import org.apache.dolphinscheduler.server.registry.ServerNodeManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter; import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.server.worker.config.WorkerConfig; import org.apache.dolphinscheduler.server.worker.config.WorkerConfig;
import org.apache.dolphinscheduler.server.worker.processor.TaskExecuteProcessor; import org.apache.dolphinscheduler.server.worker.processor.TaskExecuteProcessor;
@ -40,6 +41,7 @@ import org.apache.dolphinscheduler.service.bean.SpringApplicationContext;
import org.apache.dolphinscheduler.service.zk.CuratorZookeeperClient; import org.apache.dolphinscheduler.service.zk.CuratorZookeeperClient;
import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator; import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator;
import org.apache.dolphinscheduler.service.zk.ZookeeperConfig; import org.apache.dolphinscheduler.service.zk.ZookeeperConfig;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -53,8 +55,9 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={DependencyConfig.class, SpringZKServer.class, WorkerRegistry.class, @ContextConfiguration(classes={DependencyConfig.class, SpringZKServer.class, WorkerRegistry.class,
ZookeeperNodeManager.class, ZookeeperRegistryCenter.class, WorkerConfig.class, CuratorZookeeperClient.class, ServerNodeManager.class, ZookeeperRegistryCenter.class, WorkerConfig.class, CuratorZookeeperClient.class,
ZookeeperCachedOperator.class, ZookeeperConfig.class, SpringApplicationContext.class, NettyExecutorManager.class}) ZookeeperCachedOperator.class, ZookeeperConfig.class, SpringApplicationContext.class, NettyExecutorManager.class,
SpringConnectionFactory.class})
public class NettyExecutorManagerTest { public class NettyExecutorManagerTest {
@Autowired @Autowired

13
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/master/dispatch/host/RoundRobinHostManagerTest.java

@ -17,12 +17,10 @@
package org.apache.dolphinscheduler.server.master.dispatch.host; package org.apache.dolphinscheduler.server.master.dispatch.host;
import com.google.common.collect.Sets;
import org.apache.dolphinscheduler.common.utils.StringUtils; import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.dolphinscheduler.remote.utils.Host; import org.apache.dolphinscheduler.remote.utils.Host;
import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext; import org.apache.dolphinscheduler.server.master.dispatch.context.ExecutionContext;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager; import org.apache.dolphinscheduler.server.registry.ServerNodeManager;
import org.apache.dolphinscheduler.server.utils.ExecutionContextTestUtils; import org.apache.dolphinscheduler.server.utils.ExecutionContextTestUtils;
import org.junit.Assert; import org.junit.Assert;
@ -33,6 +31,8 @@ import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import com.google.common.collect.Sets;
/** /**
* round robin host manager test * round robin host manager test
@ -40,16 +40,15 @@ import org.mockito.junit.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class) @RunWith(MockitoJUnitRunner.class)
public class RoundRobinHostManagerTest { public class RoundRobinHostManagerTest {
@Mock @Mock
private ZookeeperNodeManager zookeeperNodeManager; private ServerNodeManager serverNodeManager;
@InjectMocks @InjectMocks
RoundRobinHostManager roundRobinHostManager; RoundRobinHostManager roundRobinHostManager;
@Test @Test
public void testSelectWithEmptyResult() { public void testSelectWithEmptyResult() {
Mockito.when(zookeeperNodeManager.getWorkerGroupNodes("default")).thenReturn(null); Mockito.when(serverNodeManager.getWorkerGroupNodes("default")).thenReturn(null);
ExecutionContext context = ExecutionContextTestUtils.getExecutionContext(10000); ExecutionContext context = ExecutionContextTestUtils.getExecutionContext(10000);
Host emptyHost = roundRobinHostManager.select(context); Host emptyHost = roundRobinHostManager.select(context);
Assert.assertTrue(StringUtils.isEmpty(emptyHost.getAddress())); Assert.assertTrue(StringUtils.isEmpty(emptyHost.getAddress()));
@ -57,7 +56,7 @@ public class RoundRobinHostManagerTest {
@Test @Test
public void testSelectWithResult() { public void testSelectWithResult() {
Mockito.when(zookeeperNodeManager.getWorkerGroupNodes("default")).thenReturn(Sets.newHashSet("192.168.1.1:22:100")); Mockito.when(serverNodeManager.getWorkerGroupNodes("default")).thenReturn(Sets.newHashSet("192.168.1.1:22"));
ExecutionContext context = ExecutionContextTestUtils.getExecutionContext(10000); ExecutionContext context = ExecutionContextTestUtils.getExecutionContext(10000);
Host host = roundRobinHostManager.select(context); Host host = roundRobinHostManager.select(context);
Assert.assertTrue(StringUtils.isNotEmpty(host.getAddress())); Assert.assertTrue(StringUtils.isNotEmpty(host.getAddress()));

33
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/ZookeeperNodeManagerTest.java → dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/registry/ServerNodeManagerTest.java

@ -14,14 +14,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.apache.dolphinscheduler.server.registry;
import java.util.Map; package org.apache.dolphinscheduler.server.registry;
import java.util.Set;
import org.apache.dolphinscheduler.common.utils.CollectionUtils; import org.apache.dolphinscheduler.common.utils.CollectionUtils;
import org.apache.dolphinscheduler.common.utils.NetUtils; import org.apache.dolphinscheduler.common.utils.NetUtils;
import org.apache.dolphinscheduler.dao.datasource.SpringConnectionFactory;
import org.apache.dolphinscheduler.server.master.config.MasterConfig; import org.apache.dolphinscheduler.server.master.config.MasterConfig;
import org.apache.dolphinscheduler.server.master.registry.MasterRegistry; import org.apache.dolphinscheduler.server.master.registry.MasterRegistry;
import org.apache.dolphinscheduler.server.worker.config.WorkerConfig; import org.apache.dolphinscheduler.server.worker.config.WorkerConfig;
@ -30,6 +28,10 @@ import org.apache.dolphinscheduler.server.zk.SpringZKServer;
import org.apache.dolphinscheduler.service.zk.CuratorZookeeperClient; import org.apache.dolphinscheduler.service.zk.CuratorZookeeperClient;
import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator; import org.apache.dolphinscheduler.service.zk.ZookeeperCachedOperator;
import org.apache.dolphinscheduler.service.zk.ZookeeperConfig; import org.apache.dolphinscheduler.service.zk.ZookeeperConfig;
import java.util.Map;
import java.util.Set;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -38,16 +40,16 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/** /**
* zookeeper node manager test * server node manager test
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={DependencyConfig.class, SpringZKServer.class, MasterRegistry.class,WorkerRegistry.class, @ContextConfiguration(classes={DependencyConfig.class, SpringZKServer.class, MasterRegistry.class,WorkerRegistry.class,
ZookeeperRegistryCenter.class, MasterConfig.class, WorkerConfig.class, ZookeeperRegistryCenter.class, MasterConfig.class, WorkerConfig.class, SpringConnectionFactory.class,
ZookeeperCachedOperator.class, ZookeeperConfig.class, ZookeeperNodeManager.class, CuratorZookeeperClient.class}) ZookeeperCachedOperator.class, ZookeeperConfig.class, ServerNodeManager.class, CuratorZookeeperClient.class})
public class ZookeeperNodeManagerTest { public class ServerNodeManagerTest {
@Autowired @Autowired
private ZookeeperNodeManager zookeeperNodeManager; private ServerNodeManager serverNodeManager;
@Autowired @Autowired
private MasterRegistry masterRegistry; private MasterRegistry masterRegistry;
@ -68,11 +70,11 @@ public class ZookeeperNodeManagerTest {
public void testGetMasterNodes(){ public void testGetMasterNodes(){
masterRegistry.registry(); masterRegistry.registry();
try { try {
//let the zookeeperNodeManager catch the registry event //let the serverNodeManager catch the registry event
Thread.sleep(2000); Thread.sleep(2000);
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
} }
Set<String> masterNodes = zookeeperNodeManager.getMasterNodes(); Set<String> masterNodes = serverNodeManager.getMasterNodes();
Assert.assertTrue(CollectionUtils.isNotEmpty(masterNodes)); Assert.assertTrue(CollectionUtils.isNotEmpty(masterNodes));
Assert.assertEquals(1, masterNodes.size()); Assert.assertEquals(1, masterNodes.size());
Assert.assertEquals(NetUtils.getAddr(masterConfig.getListenPort()), masterNodes.iterator().next()); Assert.assertEquals(NetUtils.getAddr(masterConfig.getListenPort()), masterNodes.iterator().next());
@ -83,11 +85,11 @@ public class ZookeeperNodeManagerTest {
public void testGetWorkerGroupNodes(){ public void testGetWorkerGroupNodes(){
workerRegistry.registry(); workerRegistry.registry();
try { try {
//let the zookeeperNodeManager catch the registry event //let the serverNodeManager catch the registry event
Thread.sleep(2000); Thread.sleep(2000);
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
} }
Map<String, Set<String>> workerGroupNodes = zookeeperNodeManager.getWorkerGroupNodes(); Map<String, Set<String>> workerGroupNodes = serverNodeManager.getWorkerGroupNodes();
Assert.assertEquals(1, workerGroupNodes.size()); Assert.assertEquals(1, workerGroupNodes.size());
Assert.assertEquals("default".trim(), workerGroupNodes.keySet().iterator().next()); Assert.assertEquals("default".trim(), workerGroupNodes.keySet().iterator().next());
workerRegistry.unRegistry(); workerRegistry.unRegistry();
@ -97,12 +99,11 @@ public class ZookeeperNodeManagerTest {
public void testGetWorkerGroupNodesWithParam(){ public void testGetWorkerGroupNodesWithParam(){
workerRegistry.registry(); workerRegistry.registry();
try { try {
//let the zookeeperNodeManager catch the registry event //let the serverNodeManager catch the registry event
Thread.sleep(3000); Thread.sleep(3000);
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {
} }
Map<String, Set<String>> workerGroupNodes = zookeeperNodeManager.getWorkerGroupNodes(); Set<String> workerNodes = serverNodeManager.getWorkerGroupNodes("default");
Set<String> workerNodes = zookeeperNodeManager.getWorkerGroupNodes("default");
Assert.assertTrue(CollectionUtils.isNotEmpty(workerNodes)); Assert.assertTrue(CollectionUtils.isNotEmpty(workerNodes));
Assert.assertEquals(1, workerNodes.size()); Assert.assertEquals(1, workerNodes.size());
Assert.assertEquals(NetUtils.getAddr(workerConfig.getListenPort()), workerNodes.iterator().next()); Assert.assertEquals(NetUtils.getAddr(workerConfig.getListenPort()), workerNodes.iterator().next());

26
dolphinscheduler-server/src/test/java/org/apache/dolphinscheduler/server/worker/processor/TaskCallbackServiceTest.java

@ -19,6 +19,7 @@ package org.apache.dolphinscheduler.server.worker.processor;
import org.apache.dolphinscheduler.common.thread.Stopper; import org.apache.dolphinscheduler.common.thread.Stopper;
import org.apache.dolphinscheduler.common.utils.JSONUtils; import org.apache.dolphinscheduler.common.utils.JSONUtils;
import org.apache.dolphinscheduler.dao.datasource.SpringConnectionFactory;
import org.apache.dolphinscheduler.remote.NettyRemotingClient; import org.apache.dolphinscheduler.remote.NettyRemotingClient;
import org.apache.dolphinscheduler.remote.NettyRemotingServer; import org.apache.dolphinscheduler.remote.NettyRemotingServer;
import org.apache.dolphinscheduler.remote.command.CommandType; import org.apache.dolphinscheduler.remote.command.CommandType;
@ -34,7 +35,7 @@ import org.apache.dolphinscheduler.server.master.processor.TaskAckProcessor;
import org.apache.dolphinscheduler.server.master.processor.TaskResponseProcessor; import org.apache.dolphinscheduler.server.master.processor.TaskResponseProcessor;
import org.apache.dolphinscheduler.server.master.processor.queue.TaskResponseService; import org.apache.dolphinscheduler.server.master.processor.queue.TaskResponseService;
import org.apache.dolphinscheduler.server.master.registry.MasterRegistry; import org.apache.dolphinscheduler.server.master.registry.MasterRegistry;
import org.apache.dolphinscheduler.server.registry.ZookeeperNodeManager; import org.apache.dolphinscheduler.server.registry.ServerNodeManager;
import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter; import org.apache.dolphinscheduler.server.registry.ZookeeperRegistryCenter;
import org.apache.dolphinscheduler.server.worker.cache.impl.TaskExecutionContextCacheManagerImpl; import org.apache.dolphinscheduler.server.worker.cache.impl.TaskExecutionContextCacheManagerImpl;
import org.apache.dolphinscheduler.server.worker.config.WorkerConfig; import org.apache.dolphinscheduler.server.worker.config.WorkerConfig;
@ -63,24 +64,11 @@ import io.netty.channel.Channel;
*/ */
@RunWith(SpringJUnit4ClassRunner.class) @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { @ContextConfiguration(classes = {
TaskCallbackServiceTestConfig.class, TaskCallbackServiceTestConfig.class, SpringZKServer.class, SpringApplicationContext.class,
SpringZKServer.class, SpringConnectionFactory.class, MasterRegistry.class, WorkerRegistry.class, ZookeeperRegistryCenter.class,
SpringApplicationContext.class, MasterConfig.class, WorkerConfig.class, RegisterOperator.class, ZookeeperConfig.class, ServerNodeManager.class,
MasterRegistry.class, TaskCallbackService.class, TaskResponseService.class, TaskAckProcessor.class, TaskResponseProcessor.class,
WorkerRegistry.class, TaskExecuteProcessor.class, CuratorZookeeperClient.class, TaskExecutionContextCacheManagerImpl.class,
ZookeeperRegistryCenter.class,
MasterConfig.class,
WorkerConfig.class,
RegisterOperator.class,
ZookeeperConfig.class,
ZookeeperNodeManager.class,
TaskCallbackService.class,
TaskResponseService.class,
TaskAckProcessor.class,
TaskResponseProcessor.class,
TaskExecuteProcessor.class,
CuratorZookeeperClient.class,
TaskExecutionContextCacheManagerImpl.class,
WorkerManagerThread.class}) WorkerManagerThread.class})
public class TaskCallbackServiceTest { public class TaskCallbackServiceTest {

65
dolphinscheduler-service/src/main/java/org/apache/dolphinscheduler/service/zk/AbstractZKClient.java

@ -29,9 +29,12 @@ import org.apache.dolphinscheduler.common.utils.StringUtils;
import org.apache.curator.framework.recipes.locks.InterProcessMutex; import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -100,15 +103,12 @@ public abstract class AbstractZKClient extends RegisterOperator {
} }
/** /**
* get server list map. * get server zk nodes.
* *
* @param zkNodeType zookeeper node type * @param zkNodeType zookeeper node type
* @param hostOnly host only * @return result : list<zknode>
* @return result : {host : resource info}
*/ */
public Map<String, String> getServerMaps(ZKNodeType zkNodeType, boolean hostOnly) { public List<String> getServerZkNodes(ZKNodeType zkNodeType) {
Map<String, String> serverMap = new HashMap<>();
try {
String path = getZNodeParentPath(zkNodeType); String path = getZNodeParentPath(zkNodeType);
List<String> serverList = super.getChildrenKeys(path); List<String> serverList = super.getChildrenKeys(path);
if (zkNodeType == ZKNodeType.WORKER) { if (zkNodeType == ZKNodeType.WORKER) {
@ -121,6 +121,21 @@ public abstract class AbstractZKClient extends RegisterOperator {
} }
serverList = workerList; serverList = workerList;
} }
return serverList;
}
/**
* get server list map.
*
* @param zkNodeType zookeeper node type
* @param hostOnly host only
* @return result : {host : resource info}
*/
public Map<String, String> getServerMaps(ZKNodeType zkNodeType, boolean hostOnly) {
Map<String, String> serverMap = new HashMap<>();
try {
String path = getZNodeParentPath(zkNodeType);
List<String> serverList = getServerZkNodes(zkNodeType);
for (String server : serverList) { for (String server : serverList) {
String host = server; String host = server;
if (zkNodeType == ZKNodeType.WORKER && hostOnly) { if (zkNodeType == ZKNodeType.WORKER && hostOnly) {
@ -145,6 +160,44 @@ public abstract class AbstractZKClient extends RegisterOperator {
return getServerMaps(zkNodeType, false); return getServerMaps(zkNodeType, false);
} }
/**
* get server node set.
*
* @param zkNodeType zookeeper node type
* @param hostOnly host only
* @return result : set<host>
*/
public Set<String> getServerNodeSet(ZKNodeType zkNodeType, boolean hostOnly) {
Set<String> serverSet = new HashSet<>();
try {
List<String> serverList = getServerZkNodes(zkNodeType);
for (String server : serverList) {
String host = server;
if (zkNodeType == ZKNodeType.WORKER && hostOnly) {
host = server.split(Constants.SLASH)[1];
}
serverSet.add(host);
}
} catch (Exception e) {
logger.error("get server node set failed", e);
}
return serverSet;
}
/**
* get server node list.
*
* @param zkNodeType zookeeper node type
* @param hostOnly host only
* @return result : list<host>
*/
public List<String> getServerNodeList(ZKNodeType zkNodeType, boolean hostOnly) {
Set<String> serverSet = getServerNodeSet(zkNodeType, hostOnly);
List<String> serverList = new ArrayList<>(serverSet);
Collections.sort(serverList);
return serverList;
}
/** /**
* check the zookeeper node already exists * check the zookeeper node already exists
* *

2
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/instance/pages/list/_source/list.vue

@ -64,7 +64,7 @@
<el-table-column prop="runTimes" :label="$t('Run Times')"></el-table-column> <el-table-column prop="runTimes" :label="$t('Run Times')"></el-table-column>
<el-table-column prop="recovery" :label="$t('fault-tolerant sign')"></el-table-column> <el-table-column prop="recovery" :label="$t('fault-tolerant sign')"></el-table-column>
<el-table-column prop="executorName" :label="$t('Executor')"></el-table-column> <el-table-column prop="executorName" :label="$t('Executor')"></el-table-column>
<el-table-column prop="host" :label="$t('host')" min-width="190"></el-table-column> <el-table-column prop="host" :label="$t('host')" min-width="210"></el-table-column>
<el-table-column :label="$t('Operation')" width="240" fixed="right"> <el-table-column :label="$t('Operation')" width="240" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<div v-show="scope.row.disabled"> <div v-show="scope.row.disabled">

2
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/taskInstance/_source/list.vue

@ -59,7 +59,7 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="retryTimes" :label="$t('Retry Count')"></el-table-column> <el-table-column prop="retryTimes" :label="$t('Retry Count')"></el-table-column>
<el-table-column :label="$t('host')" min-width="190"> <el-table-column :label="$t('host')" min-width="210">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{scope.row.host | filterNull}}</span> <span>{{scope.row.host | filterNull}}</span>
</template> </template>

50
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/createWorker.vue

@ -19,7 +19,8 @@
ref="popover" ref="popover"
:ok-text="item ? $t('Edit') : $t('Submit')" :ok-text="item ? $t('Edit') : $t('Submit')"
@ok="_ok" @ok="_ok"
@close="close"> @close="close"
style="width: 700px;">
<template slot="content"> <template slot="content">
<div class="create-worker-model"> <div class="create-worker-model">
<m-list-box-f> <m-list-box-f>
@ -37,16 +38,7 @@
<m-list-box-f> <m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Worker Addresses')}}</template> <template slot="name"><strong>*</strong>{{$t('Worker Addresses')}}</template>
<template slot="content"> <template slot="content">
<el-input <treeselect :options="this.workerAddressList" v-model="addrList" :multiple="true" :placeholder="$t('Please select the worker addresses')"></treeselect>
:autosize="{ minRows: 4, maxRows: 6 }"
type="textarea"
size="mini"
v-model.trim="addrList"
:placeholder="$t('Please enter the worker addresses separated by commas')">
</el-input>
<div class="cwm-tip">
<span>{{$t('Note: Multiple worker addresses have been comma separated')}}</span>
</div>
</template> </template>
</m-list-box-f> </m-list-box-f>
</div> </div>
@ -58,6 +50,8 @@
import store from '@/conf/home/store' import store from '@/conf/home/store'
import mPopover from '@/module/components/popup/popover' import mPopover from '@/module/components/popup/popover'
import mListBoxF from '@/module/components/listBoxF/listBoxF' import mListBoxF from '@/module/components/listBoxF/listBoxF'
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
export default { export default {
name: 'create-warning', name: 'create-warning',
@ -66,11 +60,12 @@
store, store,
id: 0, id: 0,
name: '', name: '',
addrList: '' addrList: []
} }
}, },
props: { props: {
item: Object item: Object,
workerAddressList: Object
}, },
methods: { methods: {
_ok () { _ok () {
@ -79,35 +74,23 @@
this._submit() this._submit()
} }
}, },
checkIpAndPorts (addrs) {
let reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5]):\d{1,5}$/
return addrs.split(',').every(item => reg.test(item))
},
checkFqdnAndPorts (addrs) {
let reg = /^([\w-]+\.)*[\w-]+:\d{1,5}$/i
return addrs.split(',').every(item => reg.test(item))
},
_verification () { _verification () {
// group name // group name
if (!this.name) { if (!this.name) {
this.$message.warning(`${i18n.$t('Please enter group name')}`) this.$message.warning(`${i18n.$t('Please enter group name')}`)
return false return false
} }
if (!this.addrList) { if (!this.addrList.length) {
this.$message.warning(`${i18n.$t('Worker addresses cannot be empty')}`) this.$message.warning(`${i18n.$t('Worker addresses cannot be empty')}`)
return false return false
} }
if (!this.checkIpAndPorts(this.addrList) && !this.checkFqdnAndPorts(this.addrList)) {
this.$message.warning(`${i18n.$t('Please enter the correct worker addresses')}`)
return false
}
return true return true
}, },
_submit () { _submit () {
let param = { let param = {
id: this.id, id: this.id,
name: this.name, name: this.name,
addrList: this.addrList addrList: this.addrList.join(',')
} }
if (this.item) { if (this.item) {
param.id = this.item.id param.id = this.item.id
@ -131,20 +114,11 @@
if (this.item) { if (this.item) {
this.id = this.item.id this.id = this.item.id
this.name = this.item.name this.name = this.item.name
this.addrList = this.item.addrList this.addrList = this.item.addrList.split(',')
} }
}, },
mounted () { mounted () {
}, },
components: { mPopover, mListBoxF } components: { mPopover, mListBoxF, Treeselect }
} }
</script> </script>
<style lang="scss" rel="stylesheet/scss">
.create-worker-model {
.cwm-tip {
color: #999;
padding-top: 4px;
display: block;
}
}
</style>

16
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/index.vue

@ -24,8 +24,8 @@
:title="item ? $t('Edit worker group') : $t('Create worker group')" :title="item ? $t('Edit worker group') : $t('Create worker group')"
v-if="createWorkerGroupDialog" v-if="createWorkerGroupDialog"
:visible.sync="createWorkerGroupDialog" :visible.sync="createWorkerGroupDialog"
width="auto"> width="50%">
<m-create-worker :item="item" @onUpdate="onUpdate" @close="close"></m-create-worker> <m-create-worker :item="item" :worker-address-list="workerAddressList" @onUpdate="onUpdate" @close="close"></m-create-worker>
</el-dialog> </el-dialog>
</template> </template>
</m-conditions> </m-conditions>
@ -77,6 +77,7 @@
total: null, total: null,
isLoading: false, isLoading: false,
workerGroupList: [], workerGroupList: [],
workerAddressList: [],
searchParams: { searchParams: {
pageSize: 10, pageSize: 10,
pageNo: 1, pageNo: 1,
@ -90,7 +91,7 @@
mixins: [listUrlParamHandle], mixins: [listUrlParamHandle],
props: {}, props: {},
methods: { methods: {
...mapActions('security', ['getWorkerGroups']), ...mapActions('security', ['getWorkerGroups', 'getWorkerAddresses']),
/** /**
* Inquire * Inquire
*/ */
@ -135,6 +136,11 @@
}).catch(e => { }).catch(e => {
this.isLoading = false this.isLoading = false
}) })
},
_getWorkerAddressList () {
this.getWorkerAddresses().then(res => {
this.workerAddressList = res.data.map(x => ({ id: x, label: x }))
})
} }
}, },
watch: { watch: {
@ -144,7 +150,9 @@
this.searchParams.pageNo = _.isEmpty(a.query) ? 1 : a.query.pageNo this.searchParams.pageNo = _.isEmpty(a.query) ? 1 : a.query.pageNo
} }
}, },
created () {}, created () {
this._getWorkerAddressList()
},
mounted () { mounted () {
}, },
components: { mList, mListConstruction, mConditions, mSpin, mNoData, mCreateWorker } components: { mList, mListConstruction, mConditions, mSpin, mNoData, mCreateWorker }

9
dolphinscheduler-ui/src/js/conf/home/store/security/actions.js

@ -630,5 +630,14 @@ export default {
reject(e) reject(e)
}) })
}) })
},
getWorkerAddresses ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('worker-group/worker-address-list', payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
} }
} }

4
dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js

@ -504,8 +504,7 @@ export default {
'Edit token': 'Edit token', 'Edit token': 'Edit token',
Addresses: 'Addresses', Addresses: 'Addresses',
'Worker Addresses': 'Worker Addresses', 'Worker Addresses': 'Worker Addresses',
'Please enter the worker addresses separated by commas': 'Please enter the worker addresses separated by commas', 'Please select the worker addresses': 'Please select the worker addresses',
'Note: Multiple worker addresses have been comma separated': 'Note: Multiple worker addresses have been comma separated',
'Failure time': 'Failure time', 'Failure time': 'Failure time',
'Expiration time': 'Expiration time', 'Expiration time': 'Expiration time',
User: 'User', User: 'User',
@ -571,7 +570,6 @@ export default {
'Please Enter Http Condition': 'Please Enter Http Condition', 'Please Enter Http Condition': 'Please Enter Http Condition',
'There is no data for this period of time': 'There is no data for this period of time', 'There is no data for this period of time': 'There is no data for this period of time',
'Worker addresses cannot be empty': 'Worker addresses cannot be empty', 'Worker addresses cannot be empty': 'Worker addresses cannot be empty',
'Please enter the correct worker addresses': 'Please enter the correct worker addresses',
'Please generate token': 'Please generate token', 'Please generate token': 'Please generate token',
'Spark Version': 'Spark Version', 'Spark Version': 'Spark Version',
TargetDataBase: 'target database', TargetDataBase: 'target database',

4
dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -504,8 +504,7 @@ export default {
'Edit token': '编辑令牌', 'Edit token': '编辑令牌',
Addresses: '地址', Addresses: '地址',
'Worker Addresses': 'Worker地址', 'Worker Addresses': 'Worker地址',
'Please enter the worker addresses separated by commas': '请输入Worker地址多个用英文逗号隔开', 'Please select the worker addresses': '请选择Worker地址',
'Note: Multiple worker addresses have been comma separated': '注意多个Worker地址以英文逗号分割',
'Failure time': '失效时间', 'Failure time': '失效时间',
'Expiration time': '失效时间', 'Expiration time': '失效时间',
User: '用户', User: '用户',
@ -571,7 +570,6 @@ export default {
'Please Enter Http Condition': '请填写校验内容', 'Please Enter Http Condition': '请填写校验内容',
'There is no data for this period of time': '该时间段无数据', 'There is no data for this period of time': '该时间段无数据',
'Worker addresses cannot be empty': 'Worker地址不能为空', 'Worker addresses cannot be empty': 'Worker地址不能为空',
'Please enter the correct worker addresses': '请输入正确的Worker地址',
'Please generate token': '请生成Token', 'Please generate token': '请生成Token',
'Spark Version': 'Spark版本', 'Spark Version': 'Spark版本',
TargetDataBase: '目标库', TargetDataBase: '目标库',

2
pom.xml

@ -934,7 +934,7 @@
<include>**/server/master/processor/TaskAckProcessorTest.java</include> <include>**/server/master/processor/TaskAckProcessorTest.java</include>
<include>**/server/master/processor/TaskKillResponseProcessorTest.java</include> <include>**/server/master/processor/TaskKillResponseProcessorTest.java</include>
<include>**/server/master/processor/queue/TaskResponseServiceTest.java</include> <include>**/server/master/processor/queue/TaskResponseServiceTest.java</include>
<include>**/server/register/ZookeeperNodeManagerTest.java</include> <include>**/server/register/ServerNodeManagerTest.java</include>
<include>**/server/register/ZookeeperRegistryCenterTest.java</include> <include>**/server/register/ZookeeperRegistryCenterTest.java</include>
<include>**/server/utils/DataxUtilsTest.java</include> <include>**/server/utils/DataxUtilsTest.java</include>
<include>**/server/utils/ExecutionContextTestUtils.java</include> <include>**/server/utils/ExecutionContextTestUtils.java</include>

5
sql/dolphinscheduler_mysql.sql

@ -795,11 +795,12 @@ CREATE TABLE `t_ds_user` (
DROP TABLE IF EXISTS `t_ds_worker_group`; DROP TABLE IF EXISTS `t_ds_worker_group`;
CREATE TABLE `t_ds_worker_group` ( CREATE TABLE `t_ds_worker_group` (
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'id', `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(256) NULL DEFAULT NULL COMMENT 'worker group name', `name` varchar(256) NOT NULL COMMENT 'worker group name',
`addr_list` text NULL DEFAULT NULL COMMENT 'worker addr list. split by [,]', `addr_list` text NULL DEFAULT NULL COMMENT 'worker addr list. split by [,]',
`create_time` datetime NULL DEFAULT NULL COMMENT 'create time', `create_time` datetime NULL DEFAULT NULL COMMENT 'create time',
`update_time` datetime NULL DEFAULT NULL COMMENT 'update time', `update_time` datetime NULL DEFAULT NULL COMMENT 'update time',
PRIMARY KEY (`id`) PRIMARY KEY (`id`),
UNIQUE KEY `name_unique` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- ---------------------------- -- ----------------------------

5
sql/dolphinscheduler_postgre.sql

@ -658,11 +658,12 @@ create index version_index on t_ds_version(version);
DROP TABLE IF EXISTS t_ds_worker_group; DROP TABLE IF EXISTS t_ds_worker_group;
CREATE TABLE t_ds_worker_group ( CREATE TABLE t_ds_worker_group (
id bigint NOT NULL , id bigint NOT NULL ,
name varchar(256) DEFAULT NULL , name varchar(256) NOT NULL ,
addr_list text DEFAULT NULL , addr_list text DEFAULT NULL ,
create_time timestamp DEFAULT NULL , create_time timestamp DEFAULT NULL ,
update_time timestamp DEFAULT NULL , update_time timestamp DEFAULT NULL ,
PRIMARY KEY (id) PRIMARY KEY (id) ,
CONSTRAINT name_unique UNIQUE (name)
) ; ) ;
-- --

2
sql/upgrade/1.3.6_schema/mysql/dolphinscheduler_ddl.sql

@ -28,6 +28,8 @@ BEGIN
AND COLUMN_NAME ='ip_list') AND COLUMN_NAME ='ip_list')
THEN THEN
ALTER TABLE t_ds_worker_group CHANGE COLUMN `ip_list` `addr_list` text; ALTER TABLE t_ds_worker_group CHANGE COLUMN `ip_list` `addr_list` text;
ALTER TABLE t_ds_worker_group MODIFY COLUMN `name` varchar(256) NOT NULL;
ALTER TABLE t_ds_worker_group ADD UNIQUE KEY `name_unique` (`name`);
END IF; END IF;
END; END;

9
sql/upgrade/1.3.6_schema/postgresql/dolphinscheduler_ddl.sql

@ -15,7 +15,6 @@
* limitations under the License. * limitations under the License.
*/ */
-- uc_dolphin_T_t_ds_worker_group_A_ip_list -- uc_dolphin_T_t_ds_worker_group_A_ip_list
delimiter d// delimiter d//
CREATE OR REPLACE FUNCTION uc_dolphin_T_t_ds_worker_group_A_ip_list() RETURNS void AS $$ CREATE OR REPLACE FUNCTION uc_dolphin_T_t_ds_worker_group_A_ip_list() RETURNS void AS $$
@ -24,8 +23,10 @@ BEGIN
WHERE TABLE_NAME='t_ds_worker_group' WHERE TABLE_NAME='t_ds_worker_group'
AND COLUMN_NAME ='ip_list') AND COLUMN_NAME ='ip_list')
THEN THEN
ALTER TABLE t_ds_worker_group rename ip_list TO addr_list; ALTER TABLE t_ds_worker_group RENAME ip_list TO addr_list;
ALTER TABLE t_ds_worker_group ALTER column addr_list type text; ALTER TABLE t_ds_worker_group ALTER COLUMN addr_list type text;
ALTER TABLE t_ds_worker_group ALTER COLUMN name type varchar(256), ALTER COLUMN name SET NOT NULL;
ALTER TABLE t_ds_worker_group ADD CONSTRAINT name_unique UNIQUE (name);
END IF; END IF;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
@ -36,5 +37,5 @@ SELECT uc_dolphin_T_t_ds_worker_group_A_ip_list();
DROP FUNCTION IF EXISTS uc_dolphin_T_t_ds_worker_group_A_ip_list(); DROP FUNCTION IF EXISTS uc_dolphin_T_t_ds_worker_group_A_ip_list();
-- Add foreign key constraints for t_ds_task_instance -- -- Add foreign key constraints for t_ds_task_instance --
delimiter ;
ALTER TABLE t_ds_task_instance ADD CONSTRAINT foreign_key_instance_id FOREIGN KEY(process_instance_id) REFERENCES t_ds_process_instance(id) ON DELETE CASCADE; ALTER TABLE t_ds_task_instance ADD CONSTRAINT foreign_key_instance_id FOREIGN KEY(process_instance_id) REFERENCES t_ds_process_instance(id) ON DELETE CASCADE;

Loading…
Cancel
Save