[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"solution-scenes-menu":3,"tech-detail-2405":4},true,{"id":5,"title":6,"content":7,"picUrl":8,"keyWords":9,"htmlDescribe":10,"htmlUrl":11,"gmtCreate":12,"gmtModified":12,"articleInfoId":13},"2405","美畅物联丨分布式锁实战：Spring Boot项目中的Redis应用","\u003Cp style=\"text-align:center\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F19\u002F86e99cb6-20fc-4e05-b7d4-51ad55399261.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left\">\u003Cspan style=\"font-size:16px\">在分布式系统里，多个节点或许会同时对共享资源进行访问与操作。为防止出现数据不一致、资源竞争等状况，就需要一种机制来对这些并发访问加以协调，于是分布式锁就出现了。它如同一把全局的钥匙，在同一时刻仅有一个节点能够获取该钥匙以访问共享资源，进而确保了数据的一致性以及系统的稳定性。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left\">\u003Cspan style=\"font-size:16px\">在Spring Boot应用里，利用Redis达成分布式锁是一种常见的操作方式，Redis提供了简洁且有效的机制以实现该功能。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left\">\u003Cspan style=\"font-size:16px\">以下为在Spring Boot中运用Redis实现分布式锁的步骤：\u003C\u002Fspan>\u003C\u002Fp>\u003Ch2 style=\"text-align:justify\">\u003Cstrong>一、搭建 Spring Boot 项目并引入 Redis 依赖\u003C\u002Fstrong>\u003C\u002Fh2>\u003Ch2 style=\"text-align:justify\">\u003Cstrong>1、创建 Spring Boot 项目\u003C\u002Fstrong>\u003C\u002Fh2>\u003Cp style=\"text-align:center\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F19\u002F62bd3ed9-13f2-44e8-a96f-86fcc10841e0.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-align:left\">\u003Cspan style=\"font-size:16px\">（1）利用Spring Initializr创建一个Spring Boot项目。在项目配置期间，挑选合适的Spring Boot版本，一般推荐使用稳定版本。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left\">\u003Cspan style=\"font-size:16px\">要确保添加Web依赖，因为在Web服务中我们通常会使用分布式锁来保护共享资源。此外，添加Redis依赖，这会让我们在项目中便捷地使用Redis相关功能。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-align:left\">\u003Cspan style=\"font-size:16px\">（2）检查项目结构与配置文件\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left\">\u003Cspan style=\"font-size:16px\">在生成的项目结构里，pom.xml（针对Maven项目）或者build.gradle（针对Gradle项目）属于项目构建文件，其作用是管理项目的依赖关系。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left\">\u003Cspan style=\"font-size:16px\">src\u002Fmain\u002Fjava目录是用于编写Java代码的地方，src\u002Fmain\u002Fresources目录则用于存放配置文件、静态资源等。\u003C\u002Fspan>\u003C\u002Fp>\u003Ch2 style=\"text-align:left\">\u003Cstrong>2、配置 Redis 连接\u003C\u002Fstrong>\u003C\u002Fh2>\u003Cp style=\"text-align:left\">\u003Cspan style=\"font-size:16px\">（1）在application.properties或者application.yml中进行配置。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:left\">\u003Cspan style=\"font-size:16px\">若使用application.properties文件，则添加如下配置：\u003C\u002Fspan>\u003C\u002Fp>\u003Cpre>\u003Ccode>properties\nspring.redis.host=localhostspring.redis.port=6379\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-align:justify\">\u003Cspan style=\"color:rgba(0, 0, 0, 0.9);font-size:16px\">（2）这里假定Redis服务在本地运行，其主机名是localhost，端口为6379。若Redis服务受密码保护，那么还需添加spring.redis.password配置项。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">若采用application.yml文件，配置如下：\u003C\u002Fspan>\u003C\u002Fp>\u003Cpre>\u003Ccode>yaml\nspring:\n  redis:\n    host: localhost\n    port: 6379\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">这种配置方式更为直观，具有清晰的层次结构。同样地，若存在密码，也能够在password（密码）字段添加密码信息。\u003C\u002Fspan>\u003C\u002Fp>\u003Ch1 style=\"text-align:justify\">\u003Cstrong>二、实现 Redis 分布式锁的基本步骤\u003C\u002Fstrong>\u003C\u002Fh1>\u003Cp style=\"text-align:center\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F19\u002F474bdb16-0a64-4aed-a1c3-0b87406c9734.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Ch2 style=\"text-align:justify\">\u003Cstrong>1、注入 RedisTemplate\u003C\u002Fstrong>\u003C\u002Fh2>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">在需要运用分布式锁的类里注入RedisTemplate。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">在Spring Boot框架下，RedisTemplate属于操作Redis的核心类。在服务类或者相关业务逻辑类当中，借助@Autowired注解来注入RedisTemplate。\u003C\u002Fspan>\u003C\u002Fp>\u003Cpre>\u003Ccode>java\nimport org.springframework.data.redis.core.RedisTemplate;import org.springframework.stereotype.Service;@Servicepublic class MyService {\n    private final RedisTemplate&lt;String, Object&gt; redisTemplate;\n    @Autowired\n    public MyService(RedisTemplate&lt;String, Object&gt; redisTemplate) {\n        this.redisTemplate = redisTemplate;\n    }\n    \u002F\u002F 以下是使用分布式锁的业务逻辑}\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">在这里，把RedisTemplate注入到MyService类里，以便于在这个类之后的业务逻辑当中，运用Redis操作达成分布式锁。\u003C\u002Fspan>\u003C\u002Fp>\u003Ch2 style=\"text-align:justify\">\u003Cstrong>2、获取分布式锁\u003C\u002Fstrong>\u003C\u002Fh2>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">利用Redis的SETNX命令达成锁获取\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">在MyService类里，编写一个用于获取分布式锁的方法。能够借助RedisTemplate的opsForValue方法来操作Redis中的字符串类型数据，该方法对应SETNX（SET if Not eXists）命令，此命令的作用是当键不存在时设置键值。\u003C\u002Fspan>\u003C\u002Fp>\u003Cpre>\u003Ccode>java\npublic boolean tryLock(String lockKey, long expireTime) {\n    Boolean result = redisTemplate.opsForValue().setIfAbsent(lockKey, \"locked\");\n    if (result!= null &amp;&amp; result) {\n        \u002F\u002F 设置锁的过期时间，防止死锁\n        redisTemplate.expire(lockKey, expireTime, TimeUnit.SECONDS);\n        return true;\n    }\n    return false;}\n\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">此方法接收两个参数，其中lockKey为用于标识锁的唯一键，expireTime则是锁的过期时间（单位为秒）。首先尝试获取锁，若键不存在（也就是说当前没有其他节点持有该锁），便将键值设为locked，并且返回true以表明获取锁成功。接着设置锁的过期时间，如此一来，即便持有锁的节点发生故障，锁也会在一段时间后自动释放，从而避免了死锁状况。若获取锁失败（键已经存在），则返回false。\u003C\u002Fspan>\u003C\u002Fp>\u003Ch2 style=\"text-align:justify\">\u003Cstrong>3、释放分布式锁\u003C\u002Fstrong>\u003C\u002Fh2>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">利用Redis的DEL命令达成锁的释放\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">编写一个用于释放分布式锁的方法，同样借助RedisTemplate进行操作。\u003C\u002Fspan>\u003C\u002Fp>\u003Cpre>\u003Ccode>java\npublic void unlock(String lockKey) {\n    redisTemplate.delete(lockKey);}\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">这个方法十分简单，利用redisTemplate.delete方法删除相应的锁键，进而释放锁。但在实际应用时，必须注意确保只有持有锁的节点才能够释放锁，防止误将其他节点持有的锁释放。\u003C\u002Fspan>\u003C\u002Fp>\u003Ch1 style=\"text-align:justify\">\u003Cstrong>三、注意事项\u003C\u002Fstrong>\u003C\u002Fh1>\u003Cp>\u003Cspan style=\"font-size:16px\">\u003Cstrong>1、锁的过期时间：\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan style=\"font-size:16px\">要确保设定合理的锁过期时间，防止由于某些原因（例如服务器宕机）致使锁无法释放。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp>\u003Cspan style=\"font-size:16px\">\u003Cstrong>2、重试机制：\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan style=\"font-size:16px\">运用Spring Retry或者其他重试机制来处理锁获取失败的状况。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp>\u003Cspan style=\"font-size:16px\">\u003Cstrong>3、锁的唯一性：\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan style=\"font-size:16px\">要保证锁键具有唯一性，以免不同业务逻辑发生冲突。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp>\u003Cspan style=\"font-size:16px\">\u003Cstrong>4、性能考量：\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan style=\"font-size:16px\">分布式锁会带来一定的性能损耗，在高并发场景下尤其需要谨慎使用。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-align:center\">\u003Cimg src=\"https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F19\u002Fd80606d6-4721-4175-9f7e-f6fad721c45e.png\" alt=\"\" loading=\"lazy\" \u002F>\u003C\u002Fp>\u003Cp style=\"text-indent:2em;text-align:justify\">\u003Cspan style=\"font-size:16px\">通过以上步骤，我们可以在 Spring Boot 项目中有效地使用 Redis 实现分布式锁，保护共享资源，确保分布式系统的稳定运行和数据一致性。不过，在实际应用中，还需要根据具体的业务场景和系统架构进行更多的优化和调整。\u003C\u002Fspan>\u003C\u002Fp>\u003Cp style=\"text-align:justify\">————————————————\u003C\u002Fp>\u003Cp style=\"text-align:left;line-height:2\">\u003Cspan style=\"color:rgb(0, 0, 0);background-color:rgb(255, 255, 255);font-size:16px\">关注\u003C\u002Fspan>\u003Cspan style=\"color:rgb(66, 144, 247);background-color:rgb(255, 255, 255);font-size:16px\">\u003Cstrong>“美畅物联”\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan style=\"color:rgb(0, 0, 0);background-color:rgb(255, 255, 255);font-size:16px\">，了解更多视频汇聚及AIoT底座解决方案。\u003C\u002Fspan>\u003C\u002Fp>","https:\u002F\u002Fqu-link.oss-cn-hangzhou.aliyuncs.com\u002F2024\u002F12\u002F19\u002Fff3eac70-0a72-4412-aacc-cc58df52c8f7.jpg","美畅，美畅物联，畅联，畅联云平台，视频监控云平台，云视频监控，视频云平台，视频开放平台，视频感知云，视频接入网关，AIoT综合接入网关，视频中台，物联网中台，无插件播放，H265播放，Ehome，ISUP， GB28181，GB35114，gat1400，JT808，JT1078","原创技术分享丨美畅物联","http:\u002F\u002Fwww.24hlink.cn\u002Fweb-index\u002FBO3OO22.html","2024-12-19 16:35:29","807"]