首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java,OrbitzWorld领事客户端-如何管理会话和锁?

java,OrbitzWorld领事客户端-如何管理会话和锁?
EN

Stack Overflow用户
提问于 2020-02-21 14:09:51
回答 2查看 601关注 0票数 1

使用java OrbitzWorld领事客户端,我试图通过acquireLock方法同步java应用程序的多个实例。

到目前为止我的代码:

注册应用为领事服务:

代码语言:javascript
复制
private void registerService(Config config) {
        String serviceId = config.getService().getId();
        String serviceName = config.getService().getName();
        long ttl = config.getService().getTtl();
        AgentClient agentClient = client.agentClient();
        Registration service = ImmutableRegistration.builder()
                .id(serviceId)
                .name(serviceName)
                .check(Registration.RegCheck.ttl(ttl))
                .build();
        agentClient.register(service);
        new HeartBeater(agentClient, serviceId, ttl).start();
    }

HeartBeater:

代码语言:javascript
复制
@Override
    public void run() {
        while(true) {
            try {
                client.pass(serviceId);
                Thread.sleep((Math.max(ttl / 2, 1)));
            } catch (NotRegisteredException | InterruptedException e) {}
        }
    }

上述代码在领事处成功刷新。

现在我想知道锁定的实现。

到目前为止,我写的是:

代码语言:javascript
复制
public boolean amILeader() {
    // return if current java app is leader
}

private String createSession() {
    final Session session = ImmutableSession.builder().name(config.getService().getName()).build();
    return client.sessionClient().createSession(session).getId();
}

private void watchLeaderLockStateChange() {
    KeyValueClient keyValueClient = client.keyValueClient();
    KVCache kvCache = KVCache.newCache(keyValueClient, Constants.LEADER_LOCK_KEY, config.getService().getWatchKey());
    kvCache.addListener(map -> {
        Value value = map.get(Constants.LEADER_LOCK_KEY);
        if(!value.getSession().isPresent()) {
            keyValueClient.acquireLock(Constants.LEADER_LOCK_KEY, ???); //create new session here ???
        }
    });
    kvCache.start();
}

我被困在这里,因为我不理解这个理论,也没有在文档中找到任何有用的东西。

我的问题:

  • 是通过acquireLock方法进行同步所必需的会话吗?如果是的话,应该何时以及如何通过acquireLock方法创建/同步会话?会话失效是常见的事情吗?根据文档,如果其中一个服务无法发送ttl,这通常会发生。
  • 如何使活的服务在创建新会话时同步?
  • 如何在锁上同步服务?

您能提供一些代码示例或填写我的实现吗?谢谢您的答复:]

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-02-21 16:58:24

我想我现在明白了。

理论是这样的:

  • 领事会话表示从单个服务到领事的连接。在我的示例中,它表示我的一个java应用程序实例与Consul
  • 之间的连接--会话用于获取锁。当客户来到领事并想获得锁时,领事将检查是否有任何与其相关的sessionId。如果没有,领事给客户一个锁,并将客户的sessionId与锁联系在一起。
  • 这锁不是什么稀奇的东西。它只是保存在领事节点上的KV映射中的一个键。
  • ,您可以检查锁,如果有任何sessionId与其关联,如:

代码语言:javascript
复制
    public class SessionFacade {
        private String leaderLock;
        private String sessionId;
        private Consul client;
        private Config config;

        public SessionFacade(Consul client, Config config) {
            this.client = client;
            this.config = config;
            this.leaderLock = "service/" + config.getService().getName() + "/leader";
            this.sessionId = createSession();
            new SessionHeartBeater(client, sessionId, config.getService().getSessionTtl()).start();
            watchLeaderLockStateChange(sessionId);
            client.keyValueClient().acquireLock(leaderLock, sessionId);
        }

        public boolean doIPossesLeaderLock() {
            Optional<Value> leaderValue = client.keyValueClient().getValue(leaderLock);
            if(leaderValue.isPresent()) {
                Optional<String> session = leaderValue.get().getSession();
                return session.isPresent() && session.get().equals(sessionId);
            }
            return false;
        }

        private String createSession() {
            int sessionTtl = config.getService().getSessionTtl();
            final Session session = ImmutableSession.builder()
                    .name(config.getService().getName())
                    .ttl(sessionTtl + "s")
                    .build();
            return client.sessionClient().createSession(session).getId();
        }

        private void watchLeaderLockStateChange(String sessionId) {
            KeyValueClient keyValueClient = client.keyValueClient();
            KVCache kvCache = KVCache.newCache(keyValueClient, leaderLock, config.getService().getWatchLockEach());
            kvCache.addListener(map -> {
                Value value = map.get(leaderLock);
                if(!value.getSession().isPresent()) {
                    keyValueClient.acquireLock(leaderLock, sessionId);
                }
            });
            kvCache.start();
        }
    }

请注意,由于我还没有对代码进行全面测试,所以代码可能是错误的。

票数 1
EN

Stack Overflow用户

发布于 2020-02-23 07:35:17

你读过https://learn.hashicorp.com/consul/developer-configuration/elections了吗?它在一个应用程序的层次上,使用领事进行领导人选举,完成了这个场景。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60340310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档