浅谈Java基于Consul创建分布式锁

 更新时间:2023年07月12日 10:13:24   作者:Blue92120  
这篇文章主要介绍了浅谈基于Consul创建分布式锁,Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置Consul是分布式的、高可用的、可横向扩展的,需要的朋友可以参考下

Consul

Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置。

Consul是分布式的、高可用的、可横向扩展的。它具备以下特性 :

  • 服务发现:consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易。
  • 健康检查:健康检测使consul可以快速的告警在集群中的操作。
  • 键/值存储:一个用来存储动态配置的系统。提供简单的HTTP接口,可以在任何地方操作。
  • 多数据中心:无需复杂的配置,即可支持任意数量的区域。

一句话概况:Consul既可以用于注册中心和配置中心,也可以做keyValue存储。使用Consul做分布式锁的底层原理就是keyValue存储。

基于consul的分布式锁

ConsulClient 是一个比较核心的类(consul客户端),keyvalue存储要用。

    private ConsulClient consulClient;
    @PostConstruct
    public void init(){
        consulClient = new ConsulClient(consulLockConfig.getHost(),consulLockConfig.getPort());
    }

createSession方法用于创建一个会话并返回sessionId,ttl是过期时间。我们在释放锁的时候会用到这个sessionId。

    /**
     * 创建一个sessionId
     * @param lockName
     * @param ttlSeconds
     * @return
     */
    private String createSession(String lockName,int ttlSeconds){
        NewSession session = new NewSession();
        //session.setBehavior(Session.Behavior.DELETE);
        session.setBehavior(Session.Behavior.RELEASE);
        session.setName("session " + lockName);
        session.setTtl(ttlSeconds + "s");
        return consulClient.sessionCreate(session, null).getValue();
    }

加锁的实现:

/**
 * 获取锁
 * @param lockName 锁的名称(key)
 * @param ttlSeconds 锁的超时时间
 * @return
 */
private boolean tryLock(String lockName,int ttlSeconds){
	try {
		PutParams putParams = new PutParams();
		String sessionId = createSession(lockName, ttlSeconds);
		SessionIdHolder.setSessionId(sessionId);
		log.info("consul加锁开始(线程:{},锁名称:{},sessionId:{})",Thread.currentThread().getName(), lockName,sessionId);
		putParams.setAcquireSession(sessionId);
		//2.将构件好的LockContext存储在consul中
		String key = consulLockConfig.PREFIX+lockName;
		//加锁成功
		Boolean value = consulClient.setKVValue(key, sessionId, putParams).getValue();
		if(value){
			//开起一个新的线程去执行锁续命--调用看门狗的方式实现
			if(consulLockConfig.isRenewal()){  //如果续期
				new ConsulWatchDog(consulClient).watchSession(sessionId,ttlSeconds);//启动看门狗
			}
			log.info("consul加锁成功(线程:{},锁名称:{},sessionId:{})",Thread.currentThread().getName(), lockName,sessionId);
			return true;
		}else{
			//将sessionId删除
			//consulClient.deleteKVValue(key);
			log.info("consul加锁失败(线程:{},锁名称:{},sessionId:{})",Thread.currentThread().getName(), lockName,sessionId);
			return false;
		}
	}catch (Exception e){
		e.printStackTrace();
		return false;
	}
}

解锁的实现:

/**
 * 释放锁
 */
public boolean unLock(String lockName){
	//log.info("consul释放锁开始(线程:{},锁名称:{})",Thread.currentThread().getName(),lockName);
	String sessionId = SessionIdHolder.getSessionId();
	try {
		//先根据锁名称找到对应的sessionId   session 是需要进行存储的  现在我们是通过一个lockContnt 假如说业务上不在一个微服务里释放锁 对应的 其他微服务如何获取到这把锁呢
		String key = consulLockConfig.PREFIX+lockName;
		Response<GetValue> kvValue = consulClient.getKVValue(key);
		if(kvValue==null) return false;
		GetValue value = kvValue.getValue();
		if(value==null) return false;
		//log.info("consul释放锁开始(线程:{},锁名称:{},sessionId:{})",Thread.currentThread().getName(),lockName,sessionId);
		PutParams putParams = new PutParams();
		putParams.setReleaseSession(sessionId);
		consulClient.setKVValue(key, sessionId, putParams);
		//String sessionId = value.getDecodedValue();
		consulClient.sessionDestroy(sessionId, null);// key value也会被删除 是使用的DELETE
		//删除对应的 sessionId存储
		//consulClient.deleteKVValue(key);
		log.info("consul释放锁成功(线程:{},锁名称:{},sessionId:{})",Thread.currentThread().getName(),lockName,sessionId);
		return true;
	}catch (Exception e){
		e.printStackTrace();
		log.info("consul释放锁出错(线程:{},锁名称:{},sessionId:{})",Thread.currentThread().getName(),lockName,sessionId);
		return false;
	}
}

到此这篇关于浅谈Java基于Consul创建分布锁的文章就介绍到这了,更多相关Consul创建分布锁内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringCloud中分析讲解Feign组件添加请求头有哪些坑梳理

    SpringCloud中分析讲解Feign组件添加请求头有哪些坑梳理

    在spring cloud的项目中用到了feign组件,简单配置过后即可完成请求的调用。又因为有向请求添加Header头的需求,查阅了官方示例后,就觉得很简单,然后一顿操作之后调试报错...下面我们来详细了解
    2022-06-06
  • Java日期毫秒值和常见日期时间格式相互转换方法

    Java日期毫秒值和常见日期时间格式相互转换方法

    这篇文章主要给大家介绍了关于Java日期毫秒值和常见日期时间格式相互转换的相关资料,在Java的日常开发中,会随时遇到需要对时间处理的情况,文中给出了详细的示例代码,需要的朋友可以参考下
    2023-07-07
  • springboot中RestTemplate发送HTTP请求的实现示例

    springboot中RestTemplate发送HTTP请求的实现示例

    RestTemplate是一个 spring-web 提供的执行HTTP请求的同步阻塞式工具类,本文就来介绍一下RestTemplate发送HTTP请求,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • SpringBoot中使用tkMapper的方法详解

    SpringBoot中使用tkMapper的方法详解

    这篇文章主要介绍了SpringBoot中使用tkMapper的方法详解
    2022-11-11
  • SpringBoot操作Mongodb的实现示例

    SpringBoot操作Mongodb的实现示例

    本文主要介绍了SpringBoot操作Mongodb的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • java实现轻轻松松控制台斗地主的示例代码

    java实现轻轻松松控制台斗地主的示例代码

    这篇文章主要介绍了java实现轻轻松松控制台斗地主,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 聊聊Spring循环依赖三级缓存是否可以减少为二级缓存的情况

    聊聊Spring循环依赖三级缓存是否可以减少为二级缓存的情况

    这篇文章主要介绍了聊聊Spring循环依赖三级缓存是否可以减少为二级缓存的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02
  • 利用Java读取二进制文件实例详解

    利用Java读取二进制文件实例详解

    这篇文章主要给大家介绍了利用Java读取二进制文件的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者使用java具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧。
    2017-08-08
  • java实现多选批量删除功能

    java实现多选批量删除功能

    工作中批量删除可以提高我们的工作效率,今天这篇文章主要介绍了java实现多选批量删除功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • java 获取内存使用率的流程实例详解

    java 获取内存使用率的流程实例详解

    这篇文章主要为大家介绍了java 获取内存使用率的流程实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12

最新评论