用 ZooKeeper 同步集群配置,当需要修改所有节点配置时,将配置更新到 ZooKeeper 的一个节点,引起这个节点数据发生变化,

其他所有需要同步配置的节点上的本地 Watcher 会立即发现节点状态的变化,并将最新数据更新到本地

官方Demo 改了改,响应 Watcher 时用 ConfFileUtil 更新一下本地配置就可以了

  1. public class Executor implements Watcher, Runnable,
  2. DataMonitor.DataMonitorListener {
  3. String znode;
  4. DataMonitor dm;
  5. ZooKeeper zk;
  6. String filename;
  7. public Executor(String hostPort, String znode, String filename)
  8. throws KeeperException, IOException {
  9. this.filename = filename;
  10. zk = new ZooKeeper(hostPort, 3000, this);
  11. dm = new DataMonitor(zk, znode, this);
  12. }
  13. public static void main(String[] args) {
  14. args = new String[3];
  15. args[0] = Constant.ZKPEER;
  16. args[1] = Constant.ZNODE;
  17. args[2] = "";
  18. String hostPort = args[0];
  19. String znode = args[1];
  20. String filename = args[2];
  21. try {
  22. new Executor(hostPort, znode, filename).run();
  23. } catch (Exception e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. public void process(WatchedEvent event) {
  28. dm.process(event);
  29. }
  30. public void run() {
  31. try {
  32. synchronized (this) {
  33. while (!dm.dead) {
  34. wait();
  35. }
  36. }
  37. } catch (InterruptedException e) {
  38. }
  39. }
  40. public void closing(int rc) {
  41. synchronized (this) {
  42. notifyAll();
  43. }
  44. }
  45. /**
  46. * 处理数据
  47. */
  48. public void exists(byte[] data) {
  49. System.out.println("...Invoked:Executor.exists(byte[] data)...");
  50. ConfFileUtil.sync(data);
  51. }
  52. }

上面的 Executor 用来和 znode 建立和维护连接

DataMonitor 仍旧负责接收事件 处理结果,这个类基本没改。

触发 Watcher 时, DataMonitor 委托 Executor 来更新本地配置

完整代码见 GITHUB

更新节点时需注意一点

  1. zk.setData(Constant.ZNODE, bytes, -1, null, null);

这个 byte[] 是有大小限制的,并且如果它超过了限制,ZooKeeper 也不会告诉你,官方文档说的是 1M,这个我没测试

当更新数据不成功且没有任何异常时,就需要检查这个数组是不是太长了

05-02 09:39