侧边栏壁纸
  • 累计撰写 31 篇文章
  • 累计创建 6 个标签
  • 累计收到 2 条评论
标签搜索

目 录CONTENT

文章目录

spring cloud网站简易接入基于redis的分布式锁(基于https://spring.academy/guides/spring-spring-distributed-lock)

lj2508_com
2024-05-21 / 0 评论 / 0 点赞 / 83 阅读 / 829 字

spring cloud网站简易接入基于redis的分布式锁(基于https://spring.academy/guides/spring-spring-distributed-lock)
前言:在19年自己写了一套spring cloud系统,当时对并发和锁这块并没有做任何处理,基本上是按照单节点来开发,突然想对系统进行一波改造升级。如果懂英文的话,可以直接参看参考网站,里面有详细的描述,本文仅使用我自己的系统来说明原文点我
准备条件: spring cloud系统 redis

1. 导入依赖

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
        <!-- spring distributed lock  -->
        <dependency>
		    <groupId>org.springframework.boot</groupId>
		    <artifactId>spring-boot-starter-integration</artifactId>
		</dependency>
         <dependency>
		    <groupId>org.springframework.integration</groupId>
		    <artifactId>spring-integration-redis</artifactId>
		 </dependency>
		 <dependency>
		    <groupId>io.lettuce</groupId>
		    <artifactId>lettuce-core</artifactId>
		 </dependency>

2. 注入实体类。如果和我一样又common模块的,可以将这部分直接写到common模块中

image
代码如下,参考链接完成。lock_name 可以自定义,是写入到redis中时的一部分

package com.lj2508.common.lock.redis.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.integration.redis.util.RedisLockRegistry;

@Configuration
public class RedisLockConfig {
	private static final String LOCK_NAME = "lj2508-distributed-lock";

	@Bean(destroyMethod = "destroy")
	public RedisLockRegistry redisLockRegistry( RedisConnectionFactory redisConnectionFactory ) {
	  return new RedisLockRegistry(redisConnectionFactory, LOCK_NAME);
	}
}


3. 在系统中使用分布式锁

  • 注入在需要使用的类中注入分布式锁
 	   @Autowired
    private LockRegistry redisLockReistry;
  • 代码中的应用
 Lock lock = null;
    	  String key = "saveBanner-1";
    	  try {
    		  lock =  redisLockReistry.obtain(key);
    	  } catch (Exception e) {
    	    // in a production environment this should be a log statement
    	    System.out.println(String.format("Unable to obtain lock: %s", key));
    	  }
    	  Mess returnVal = null;
    	  try {
    	    if (lock.tryLock()) {
				//此处用来执行之前的业务代码
    	      System.out.println("get lock successful");
    	      returnVal = wxService.saveBanner(banner);;
    	    } else {
    	    	 System.out.println("get lock unsuccessful");
    	      returnVal =  new Mess(2006, "微服务不可用,分布式锁获取失败,请稍后再试!");
    	    }
    	    return returnVal;
    	  } catch (Exception e) {
    	    // in a production environment this should log and do something else
			  e.printStackTrace();
	    	  if (e.getMessage().equals("com.netflix.client.ClientException: Load balancer does not have available server for client: Wxapp")) 
	    		  return new Mess(2006, "微服务不可用,请稍后再试!"); 
	    	  return new Mess(40001,"新增失败,请检查内容是否正确!"); 
    	  } finally {
    	    // always have this in a `finally` block in case anything goes wrong
    	    lock.unlock();
    	  }

然后测试,在第一个业务进行实。第二个请求,无法在进行操作

4. 原理猜测

image-1716349292311
通过查看redis的数据来看,是根据设置的lock_name和获取锁时的字符串来形成key,然后随机生成一个key存到redis中,并设置过期时间来判断锁是否有效, 和防止删除其他人设置的锁来实现的,其中应该还有一些过期时间的设置,以及其中可能涉及一些刷新锁的效果,我并没有去研究,因为目前对系统来说已经足够用。4中的代码也是参考文中链接来实现。链接来源google搜索 spring cloud distributed lock redis第一篇文章
如有错误,可在评论中指出

0

评论区