Consul 分布式鎖

基于Consul的分布式鎖主要利用Key/Value存儲API中的acquire和release操作來實現(xiàn)。acquire和release操作是類似Check-And-Set的操作:

acquire操作只有當鎖不存在持有者時才會返回true,并且set設置的Value值,同時執(zhí)行操作的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;
    }

    /**
     * 創(chuàng)建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/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容