MST

星途 面试题库

面试题:微服务架构下Spring Cloud全局锁实现方法之中等难度问题

在Spring Cloud微服务架构中,简述基于Redis实现全局锁的基本原理及核心代码实现步骤。
43.2万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

基本原理

  1. 唯一性:利用Redis的单线程特性,当多个客户端尝试使用相同的key来获取锁时,只有一个客户端能成功设置这个key,这就保证了锁的唯一性。例如,一个抢购场景中,众多请求同时尝试获取锁,只有第一个成功设置key的请求能进入抢购逻辑。
  2. 有效期:为获取的锁设置一个合理的过期时间,防止因持有锁的服务崩溃等异常情况导致锁无法释放,出现死锁。比如设置过期时间为10秒,如果10秒内服务处理完业务逻辑,就会主动释放锁;若未处理完,10秒后锁也会自动释放。

核心代码实现步骤

  1. 引入依赖:在Spring Boot项目的pom.xml文件中添加Redis相关依赖,例如:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置Redis:在application.yml中配置Redis连接信息,如:
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password:
    database: 0
  1. 编写获取锁方法
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class RedisLockUtil {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public boolean tryLock(String lockKey, String requestId, int expireTime) {
        // 使用setIfAbsent方法尝试设置锁
        Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId);
        if (result != null && result) {
            // 设置锁的过期时间
            redisTemplate.expire(lockKey, expireTime, TimeUnit.SECONDS);
            return true;
        }
        return false;
    }
}

这里lockKey是锁的唯一标识,requestId用于标识请求,防止误删其他请求的锁,expireTime是锁的过期时间。 4. 编写释放锁方法

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

@Component
public class RedisLockUtil {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    public void unlock(String lockKey, String requestId) {
        // 先获取锁的值
        String value = redisTemplate.opsForValue().get(lockKey);
        if (requestId.equals(value)) {
            // 如果值与请求标识相同,删除锁
            redisTemplate.delete(lockKey);
        }
    }
}

在业务代码中使用锁时,先调用tryLock方法获取锁,成功后执行业务逻辑,最后调用unlock方法释放锁。例如:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ExampleController {

    @Autowired
    private RedisLockUtil redisLockUtil;

    @GetMapping("/example")
    public String example() {
        String lockKey = "example_lock";
        String requestId = "123456";
        int expireTime = 10;
        if (redisLockUtil.tryLock(lockKey, requestId, expireTime)) {
            try {
                // 执行业务逻辑
                return "业务处理成功";
            } finally {
                redisLockUtil.unlock(lockKey, requestId);
            }
        } else {
            return "获取锁失败";
        }
    }
}