一、分布式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 节点
四、代码实现
public class MasterResolve {private ZkClient zkClient;private static final String rootPath = "/service-master";private static final String servicePath = rootPath + "/service";private String nodePath;private volatile boolean master = false;private static MasterResolve resolve;private MasterResolve() {String connectString = "192.168.209.4:2181";zkClient = new ZkClient(connectString, 50*1000);buildRoot();createServerNode();}public static MasterResolve getInstance() {if (resolve == null) {resolve= new MasterResolve();}return resolve;}// 构建根节点public void buildRoot() {if (!zkClient.exists(rootPath)) {zkClient.createPersistent(rootPath);}}// 创建server节点public void createServerNode() {nodePath = zkClient.createEphemeralSequential(servicePath, "slave");System.out.println("创建service节点:" + nodePath);initMaster();initListener();}private void initMaster() {boolean existMaster = zkClient.getChildren(rootPath).stream().map(p -> rootPath + "/" + p).map(p -> zkClient.readData(p)).anyMatch(d -> "master".equals(d));if (!existMaster) {doElection();System.out.println("当前当选master");}}private void initListener() {zkClient.subscribeChildChanges(rootPath, (parentPath, currentChilds) -> {doElection();// 执行选举});}// 执行选举public void doElection() {Map<String, Object> childData = zkClient.getChildren(rootPath).stream().map(p -> rootPath + "/" + p).collect(Collectors.toMap(p -> p, p -> zkClient.readData(p)));if (childData.containsValue("master")) {return;}childData.keySet().stream().sorted().findFirst().ifPresent(p -> {if (p.equals(nodePath)) { // 设置最小值序号为master 节点zkClient.writeData(nodePath, "master");master = true;System.out.println("当前当选master" + nodePath);}});}public static boolean isMaster() {return getInstance().master;}public static void main(String[] args) {MasterResolve instance = MasterResolve.getInstance();System.out.println("master"+ MasterResolve.isMaster());try {Thread.sleep(Integer.MAX_VALUE);} catch (InterruptedException e) {e.printStackTrace();}}}
这样JOB就可以在master执行啦,定时job运行的时候判断自己是否是master,如果是true就运行,否则就不运行!
