个人随笔
目录
六、zookeeper使用场景之:分布式JOB任务调度
2020-12-08 17:31:26

一、分布式JOB需求

1.多个服务节点只允许其中一个主节点运行JOB任务。
2.当主节点挂掉后能自动切换主节点,继续执行JOB任务

二、架构设计

node结构:

1./service-master
a./service-master/server0001:master
b./service-master/server0002:slave
c./service-master/server000n:slave

三、选举流程

1、服务启动

  • 1.在tuling-maste下创建server子节点,值为slave
  • 2.获取所有tuling-master 下所有子节点
  • 3.判断是否存在master 节点
  • 4.如果没有设置自己为master节点

2、子节点删除事件触发

  • 1.获取所有tuling-master 下所有子节点
  • 2.判断是否存在master 节点
  • 3.如果没有设置最小值序号为master 节点

四、代码实现

  1. public class MasterResolve {
  2. private ZkClient zkClient;
  3. private static final String rootPath = "/service-master";
  4. private static final String servicePath = rootPath + "/service";
  5. private String nodePath;
  6. private volatile boolean master = false;
  7. private static MasterResolve resolve;
  8. private MasterResolve() {
  9. String connectString = "192.168.209.4:2181";
  10. zkClient = new ZkClient(connectString, 50*1000);
  11. buildRoot();
  12. createServerNode();
  13. }
  14. public static MasterResolve getInstance() {
  15. if (resolve == null) {
  16. resolve= new MasterResolve();
  17. }
  18. return resolve;
  19. }
  20. // 构建根节点
  21. public void buildRoot() {
  22. if (!zkClient.exists(rootPath)) {
  23. zkClient.createPersistent(rootPath);
  24. }
  25. }
  26. // 创建server节点
  27. public void createServerNode() {
  28. nodePath = zkClient.createEphemeralSequential(servicePath, "slave");
  29. System.out.println("创建service节点:" + nodePath);
  30. initMaster();
  31. initListener();
  32. }
  33. private void initMaster() {
  34. boolean existMaster = zkClient.getChildren(rootPath)
  35. .stream()
  36. .map(p -> rootPath + "/" + p)
  37. .map(p -> zkClient.readData(p))
  38. .anyMatch(d -> "master".equals(d));
  39. if (!existMaster) {
  40. doElection();
  41. System.out.println("当前当选master");
  42. }
  43. }
  44. private void initListener() {
  45. zkClient.subscribeChildChanges(rootPath, (parentPath, currentChilds) -> {
  46. doElection();// 执行选举
  47. });
  48. }
  49. // 执行选举
  50. public void doElection() {
  51. Map<String, Object> childData = zkClient.getChildren(rootPath)
  52. .stream()
  53. .map(p -> rootPath + "/" + p)
  54. .collect(Collectors.toMap(p -> p, p -> zkClient.readData(p)));
  55. if (childData.containsValue("master")) {
  56. return;
  57. }
  58. childData.keySet().stream().sorted().findFirst().ifPresent(p -> {
  59. if (p.equals(nodePath)) { // 设置最小值序号为master 节点
  60. zkClient.writeData(nodePath, "master");
  61. master = true;
  62. System.out.println("当前当选master" + nodePath);
  63. }
  64. });
  65. }
  66. public static boolean isMaster() {
  67. return getInstance().master;
  68. }
  69. public static void main(String[] args) {
  70. MasterResolve instance = MasterResolve.getInstance();
  71. System.out.println("master"+ MasterResolve.isMaster());
  72. try {
  73. Thread.sleep(Integer.MAX_VALUE);
  74. } catch (InterruptedException e) {
  75. e.printStackTrace();
  76. }
  77. }
  78. }

这样JOB就可以在master执行啦,定时job运行的时候判断自己是否是master,如果是true就运行,否则就不运行!

 1067

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2