美文网首页
Consul 分布式锁

Consul 分布式锁

作者: sspa | 来源:发表于2020-07-10 17:46 被阅读0次

    基于Consul的分布式锁主要利用Key/Value存储API中的acquire和release操作来实现。acquire和release操作是类似Check-And-Set的操作:

    acquire操作只有当锁不存在持有者时才会返回true,并且set设置的Value值,同时执行操作的session会持有对该Key的锁,否则就返回false
    release操作则是使用指定的session来释放某个Key的锁,如果指定的session无效,那么会返回false,否则就会set设置Value值,并返回true

    未被上锁

    image.png

    被上锁

    image.png

    编码如下

    package com.qxwz.ops.station.change.util;
    
    import com.ecwid.consul.v1.ConsulClient;
    import com.ecwid.consul.v1.kv.model.PutParams;
    import com.ecwid.consul.v1.session.model.NewSession;
    
    import java.time.LocalDateTime;
    import java.util.Objects;
    
    /**
     * 基于Consul的互斥锁
     *
     * @author muxin.sun
     */
    public class Lock {
    
        private static final String prefix = "lock/";  // 同步锁参数前缀
        private volatile String sessionId;
        private final ConsulClient consulClient;
        private final String sessionName;
        private final String lockKey;
    
        /**
         *
         * @param consulClient  consul client
         * @param sessionName   同步锁的session名称
         * @param lockKey       同步锁在consul的KV存储中的Key路径,会自动增加prefix前缀,方便归类查询
         */
        public Lock(final ConsulClient consulClient,
                    final String sessionName,
                    final String lockKey) {
            this.consulClient = consulClient;
            this.sessionName = sessionName;
            this.lockKey = prefix + lockKey;
        }
    
        /**
         * 获取同步锁
         *
         * @param block     是否阻塞,直到获取到锁为止
         * @return true OR false 获取锁成功
         */
        public Boolean lock(boolean block) throws RuntimeException {
            if (Objects.isNull(sessionId)) {
                synchronized (Lock.class) {
                    if (Objects.isNull(sessionId)) {
                        sessionId = createSession(sessionName);
                        while(true) {
                            PutParams putParams = new PutParams();
                            putParams.setAcquireSession(sessionId);
                            if(consulClient.setKVValue(lockKey, "lock:" + LocalDateTime.now(), putParams).getValue()) {
                                return true;
                            } else if (block) {
                                continue;
                            }
                            return false;
                        }
                    }
                }
            }
            throw new RuntimeException(sessionId + " - Already locked!");
        }
    
        /**
         * 释放同步锁
         *
         * @return true OR false 释放同步锁成功
         */
        public Boolean unlock() {
            PutParams putParams = new PutParams();
            putParams.setReleaseSession(sessionId);
            boolean result = consulClient.setKVValue(lockKey, "unlock:" + LocalDateTime.now(), putParams).getValue();
            consulClient.sessionDestroy(sessionId, null);
            return result;
        }
    
        /**
         * 创建session
         * @param sessionName session name
         * @return sessionId
         */
        private String createSession(final String sessionName) {
            NewSession newSession = new NewSession();
            newSession.setName(sessionName);
            return consulClient.sessionCreate(newSession, null).getValue();
        }
    
    }
    
    

    参考如下:http://blog.didispace.com/spring-cloud-consul-lock-and-semphore/

    相关文章

      网友评论

          本文标题:Consul 分布式锁

          本文链接:https://www.haomeiwen.com/subject/iugmcktx.html