千家信息网

如何利用consul在spring boot中实现分布式锁场景

发表于:2025-11-15 作者:千家信息网编辑
千家信息网最后更新 2025年11月15日,本篇内容介绍了"如何利用consul在spring boot中实现分布式锁场景"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家
千家信息网最后更新 2025年11月15日如何利用consul在spring boot中实现分布式锁场景

本篇内容介绍了"如何利用consul在spring boot中实现分布式锁场景"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

以下是锁实现代码:

package com.lyb.consullock;import com.ecwid.consul.v1.ConsulClient;import com.ecwid.consul.v1.agent.model.NewCheck;import com.ecwid.consul.v1.kv.model.PutParams;import com.ecwid.consul.v1.session.model.NewSession;import com.ecwid.consul.v1.session.model.Session;import lombok.Data;import java.time.LocalDateTime;import java.util.ArrayList;import java.util.List;public class DistributedLock{    private ConsulClient consulClient;    /**     * 构造函数     * @param consulHost 注册consul的client或服务端的Ip或主机名,或域名     * @param consulPort 端口号     */    public DistributedLock(String consulHost,int consulPort){        consulClient = new ConsulClient(consulHost,consulPort);    }    /**     * 获得锁的方法     * @param lockName 竞争的资源名     * @param ttlSeconds 锁的超时时间,超过该时间自动释放     * @return     */    public LockContext getLock(String lockName,int ttlSeconds){        LockContext lockContext = new LockContext();        if(ttlSeconds<10 || ttlSeconds > 86400) ttlSeconds = 60;        String sessionId = createSession(lockName,ttlSeconds);        boolean success = lock(lockName,sessionId);        if(success == false){            consulClient.sessionDestroy(sessionId,null);            lockContext.setGetLock(false);            return lockContext;        }        lockContext.setSession(sessionId);        lockContext.setGetLock(true);        return lockContext;    }    /**     * 释放锁     * @param sessionID     */    public void releaseLock(String sessionID){        consulClient.sessionDestroy(sessionID,null);    }    private String createSession(String lockName,int ttlSeconds){        NewCheck check = new NewCheck();        check.setId("check "+lockName);        check.setName(check.getId());        check.setTtl(ttlSeconds+"s"); //该值和session ttl共同决定决定锁定时长        check.setTimeout("10s");        consulClient.agentCheckRegister(check);        consulClient.agentCheckPass(check.getId());        NewSession session = new NewSession();        session.setBehavior(Session.Behavior.RELEASE);        session.setName("session "+lockName);        session.setLockDelay(1);        session.setTtl(ttlSeconds + "s"); //和check ttl共同决定锁时长        List checks = new ArrayList<>();        checks.add(check.getId());        session.setChecks(checks);        String sessionId = consulClient.sessionCreate(session,null).getValue();        return sessionId;    }    private boolean lock(String lockName,String sessionId){        PutParams putParams = new PutParams();        putParams.setAcquireSession(sessionId);        boolean isSuccess = consulClient.setKVValue(lockName,"lock:"+ LocalDateTime.now(),putParams).getValue();        return isSuccess;    }    /**     * 竞争锁时返回的对象     */    @Data    public class LockContext{        /**         * 获得锁成功返回该值,比便后面用该值来释放锁         */        private String session;        /**         * 是否获得到锁         */        private boolean isGetLock;    }}

pom文件

    4.0.0            org.springframework.boot        spring-boot-starter-parent        2.1.6.RELEASE                 com.lyb    consul-lock    0.0.1-SNAPSHOT    consul-lock    Demo project for Spring Boot            1.8        Greenwich.SR2                            org.springframework.boot            spring-boot-starter-web                            org.springframework.cloud            spring-cloud-starter-consul-discovery                            org.springframework.boot            spring-boot-starter-actuator                            org.projectlombok            lombok            1.18.8            true                            org.springframework.boot            spring-boot-starter-test            test                                                    org.springframework.cloud                spring-cloud-dependencies                ${spring-cloud.version}                pom                import                                                                org.springframework.boot                spring-boot-maven-plugin                        

测试代码:

package com.lyb.consullock;import org.junit.Assert;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;@RunWith(SpringRunner.class)@SpringBootTestpublic class ConsulLockApplicationTests {    @Autowired    private ServiceConfig serviceConfig;    @Test    public void lockSameResourer() {        //针对相同资源在同一时刻只有一个线程会获得锁        ExecutorService threadPool = Executors.newFixedThreadPool(10);        for (int a=0;a<20;a++){            threadPool.submit(                    () -> {                        for (int i = 0;i < 100; i++) {                            DistributedLock lock = new DistributedLock(                                    serviceConfig.getConsulRegisterHost(),                                    serviceConfig.getConsulRegisterPort());                            DistributedLock.LockContext lockContext = lock.getLock("test lock", 10);                            if (lockContext.isGetLock()) {                                System.out.println(Thread.currentThread().getName() + "获得了锁");                                try {                                    TimeUnit.SECONDS.sleep(1);                                    lock.releaseLock(lockContext.getSession());                                } catch (InterruptedException e) {                                    e.printStackTrace();                                }                            }else {                                //System.out.println(Thread.currentThread().getName() + "没有获得锁");                            }                        }                    });        }        try {            TimeUnit.MINUTES.sleep(2);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    @Test    public void lockDiffResource(){        //针对不通的资源所有线程都应该能获得锁        ExecutorService threadPool = Executors.newFixedThreadPool(10);        for (int a=0;a<20;a++){            threadPool.submit(                    () -> {                        for (int i = 0;i < 100; i++) {                            DistributedLock lock = new DistributedLock(                                    serviceConfig.getConsulRegisterHost(),                                    serviceConfig.getConsulRegisterPort());                            DistributedLock.LockContext lockContext = lock.getLock("test lock"+Thread.currentThread().getName(), 10);                            if (lockContext.isGetLock()) {                                System.out.println(Thread.currentThread().getName() + "获得了锁");                                try {                                    TimeUnit.SECONDS.sleep(1);                                    lock.releaseLock(lockContext.getSession());                                } catch (InterruptedException e) {                                    e.printStackTrace();                                }                            }else {                                //System.out.println(Thread.currentThread().getName() + "没有获得锁");                                Assert.assertTrue(lockContext.isGetLock());                            }                        }                    });        }        try {            TimeUnit.MINUTES.sleep(2);        } catch (InterruptedException e) {            e.printStackTrace();        }    }}

"如何利用consul在spring boot中实现分布式锁场景"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

0