@Override
    public void prepare() throws ServiceNotProvidedException, ModuleStartException {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(config.getBaseSleepTimeMs(), config.getMaxRetries());

        CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder()
                                                                         .retryPolicy(retryPolicy)
                                                                         .connectString(config.getHostPort());

        if (config.isEnableACL()) {
            String authInfo = config.getExpression();
            if ("digest".equals(config.getSchema())) {
                try {
                    authInfo = DigestAuthenticationProvider.generateDigest(authInfo);
                } catch (NoSuchAlgorithmException e) {
                    throw new ModuleStartException(e.getMessage(), e);
                }
            } else {
                throw new ModuleStartException("Support digest schema only.");
            }
            final List<ACL> acls = Lists.newArrayList();
            acls.add(new ACL(ZooDefs.Perms.ALL, new Id(config.getSchema(), authInfo)));
            acls.add(new ACL(ZooDefs.Perms.READ, ZooDefs.Ids.ANYONE_ID_UNSAFE));

            ACLProvider provider = new ACLProvider() {
                @Override
                public List<ACL> getDefaultAcl() {
                    return acls;
                }

                @Override
                public List<ACL> getAclForPath(String s) {
                    return acls;
                }
            };
            builder.aclProvider(provider);
            builder.authorization(config.getSchema(), config.getExpression().getBytes(StandardCharsets.UTF_8));
        }
        client = builder.build();

        String path = BASE_PATH + (StringUtil.isEmpty(config.getNamespace()) ? "" : "/" + config.getNamespace());

        serviceDiscovery = ServiceDiscoveryBuilder.builder(RemoteInstance.class)
                                                  .client(client)
                                                  .basePath(path)
                                                  .watchInstances(true)
                                                  .serializer(new SWInstanceSerializer())
                                                  .build();
        try {
            client.start();
            client.blockUntilConnected();
            serviceDiscovery.start();
            coordinator = new ZookeeperCoordinator(getManager(), config, serviceDiscovery);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            throw new ModuleStartException(e.getMessage(), e);
        }

        this.registerServiceImplementation(ClusterRegister.class, coordinator);
        this.registerServiceImplementation(ClusterNodesQuery.class, coordinator);
        this.registerServiceImplementation(ClusterCoordinator.class, coordinator);
    }
Use Zookeeper to manage all instances in SkyWalking cluster.
oap-server/server-cluster-plugin/cluster-zookeeper-plugin/src/main/java/org/apache/skywalking/oap/server/cluster/plugin/zookeeper/ClusterModuleZookeeperProvider.java