Spring Cloud分布式微服务系统中利用redssion实现分布式锁
在非分布式系统中要实现锁的机制很简单,利用java.util.concurrent.locks包下的Lock和关键字synchronized都可以实现。但是在分布式系统中,如何实现各个单独的微服务需要共享某个资源的时候进行有效的锁的保护机制呢?这边使用Redisson来实现。
一、Redisson简介
Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。更多,https://github.com/redisson/redisson/wiki/1.-%E6%A6%82%E8%BF%B0
二、springboot+redission 演示
1、pom.xml
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>1.5.8.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>1.5.8.RELEASE</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>1.5.8.RELEASE</version></dependency><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.3.2</version></dependency></dependencies>
2、application.properties
server.port=8070# redisson redisson.address=192.168.3.3:6379 redisson.password=test123
3、DistributedLocker
import java.util.concurrent.TimeUnit;/*** 定义Lock的接口类* @author ko**/ public interface DistributedLocker {void lock(String lockKey);void unlock(String lockKey);void lock(String lockKey, int timeout);void lock(String lockKey, TimeUnit unit ,int timeout); }
4、RedissonDistributedLocker
import org.redisson.api.RLock; import org.redisson.api.RedissonClient;import com.redlock.locker.DistributedLocker;import java.util.concurrent.TimeUnit;/*** Lock接口实现类* @author ko**/ public class RedissonDistributedLocker implements DistributedLocker {private RedissonClient redissonClient;@Overridepublic void lock(String lockKey) {RLock lock = redissonClient.getLock(lockKey);lock.lock();}@Overridepublic void unlock(String lockKey) {RLock lock = redissonClient.getLock(lockKey);lock.unlock();}@Overridepublic void lock(String lockKey, int leaseTime) {RLock lock = redissonClient.getLock(lockKey);lock.lock(leaseTime, TimeUnit.SECONDS);}@Overridepublic void lock(String lockKey, TimeUnit unit ,int timeout) {RLock lock = redissonClient.getLock(lockKey);lock.lock(timeout, unit);}public void setRedissonClient(RedissonClient redissonClient) {this.redissonClient = redissonClient;} }
5、RedissonProperties
import org.springframework.boot.context.properties.ConfigurationProperties;/*** redisson属性装配类* @author ko**/ @ConfigurationProperties(prefix = "redisson") public class RedissonProperties {private int timeout = 3000;private String address;private String password;private int connectionPoolSize = 64;private int connectionMinimumIdleSize=10;private int slaveConnectionPoolSize = 250;private int masterConnectionPoolSize = 250;private String[] sentinelAddresses;private String masterName;public int getTimeout() {return timeout;}public void setTimeout(int timeout) {this.timeout = timeout;}public int getSlaveConnectionPoolSize() {return slaveConnectionPoolSize;}public void setSlaveConnectionPoolSize(int slaveConnectionPoolSize) {this.slaveConnectionPoolSize = slaveConnectionPoolSize;}public int getMasterConnectionPoolSize() {return masterConnectionPoolSize;}public void setMasterConnectionPoolSize(int masterConnectionPoolSize) {this.masterConnectionPoolSize = masterConnectionPoolSize;}public String[] getSentinelAddresses() {return sentinelAddresses;}public void setSentinelAddresses(String sentinelAddresses) {this.sentinelAddresses = sentinelAddresses.split(",");}public String getMasterName() {return masterName;}public void setMasterName(String masterName) {this.masterName = masterName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public int getConnectionPoolSize() {return connectionPoolSize;}public void setConnectionPoolSize(int connectionPoolSize) {this.connectionPoolSize = connectionPoolSize;}public int getConnectionMinimumIdleSize() {return connectionMinimumIdleSize;}public void setConnectionMinimumIdleSize(int connectionMinimumIdleSize) {this.connectionMinimumIdleSize = connectionMinimumIdleSize;} }
6、RedissLockUtil
import java.util.concurrent.TimeUnit;import com.redlock.locker.DistributedLocker;/*** redis分布式锁工具类* @author ko**/ public class RedissLockUtil {private static DistributedLocker redissLock;public static void setLocker(DistributedLocker locker) {redissLock = locker;}public static void lock(String lockKey) {redissLock.lock(lockKey);}public static void unlock(String lockKey) {redissLock.unlock(lockKey);}/*** 带超时的锁* @param lockKey* @param timeout 超时时间 单位:秒*/public static void lock(String lockKey, int timeout) {redissLock.lock(lockKey, timeout);}/*** 带超时的锁* @param lockKey* @param unit 时间单位* @param timeout 超时时间*/public static void lock(String lockKey, TimeUnit unit ,int timeout) {redissLock.lock(lockKey, unit, timeout);} }
7、RedissonAutoConfiguration
import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.redisson.config.SentinelServersConfig; import org.redisson.config.SingleServerConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import com.redlock.bean.RedissonProperties; import com.redlock.locker.DistributedLocker; import com.redlock.locker.impl.RedissonDistributedLocker; import com.redlock.util.RedissLockUtil;/*** Redisson+springboot 自动配置类* @author ko**/ @Configuration @ConditionalOnClass(Config.class) @EnableConfigurationProperties(RedissonProperties.class) public class RedissonAutoConfiguration {@Autowiredprivate RedissonProperties redssionProperties;/*** 哨兵模式自动装配* @return*/@Bean@ConditionalOnProperty(name="redisson.master-name")RedissonClient redissonSentinel() {Config config = new Config();SentinelServersConfig serverConfig = config.useSentinelServers().addSentinelAddress(redssionProperties.getSentinelAddresses()).setMasterName(redssionProperties.getMasterName()).setTimeout(redssionProperties.getTimeout()).setMasterConnectionPoolSize(redssionProperties.getMasterConnectionPoolSize()).setSlaveConnectionPoolSize(redssionProperties.getSlaveConnectionPoolSize());if(redssionProperties.getPassword() != null && !"".equals(redssionProperties.getPassword())) {serverConfig.setPassword(redssionProperties.getPassword());}return Redisson.create(config);}/*** 单机模式自动装配* @return*/@Bean@ConditionalOnProperty(name="redisson.address")RedissonClient redissonSingle() {Config config = new Config();SingleServerConfig serverConfig = config.useSingleServer().setAddress(redssionProperties.getAddress()).setTimeout(redssionProperties.getTimeout()).setConnectionPoolSize(redssionProperties.getConnectionPoolSize()).setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());if(redssionProperties.getPassword() != null && !"".equals(redssionProperties.getPassword())) {serverConfig.setPassword(redssionProperties.getPassword());}return Redisson.create(config);}/*** 装配locker类,并将实例注入到RedissLockUtil中* @return*/@BeanDistributedLocker distributedLocker(RedissonClient redissonClient) {RedissonDistributedLocker locker = new RedissonDistributedLocker();locker.setRedissonClient(redissonClient);RedissLockUtil.setLocker(locker);return locker;}}
8、暴露接口 TestController
import java.text.SimpleDateFormat; import java.util.Date; import java.util.concurrent.TimeUnit;import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;import com.redlock.util.RedissLockUtil;/*** 测试类* @author ko**/ @RestController public class TestController {// private static final Logger LOG = Logger.getLogger(BootApplication.class.getName()); // LOG.log(Level.INFO, "All procn");private final String _lock = "_lock";static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");public static String getCurrentDate(){return sdf.format(new Date());}@RequestMapping(value = "/testlock",method=RequestMethod.GET)public String testlock(String name) {new Thread(new Runnable() {@Overridepublic void run() {RedissLockUtil.lock(_lock, TimeUnit.MINUTES, 10);System.out.println(getCurrentDate()+" "+name+" begin...");for (int i = 0; i < 20; i++) {try {Thread.sleep(1000);System.out.println(getCurrentDate()+" "+name+" "+i);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(getCurrentDate()+" "+name+" end...");RedissLockUtil.unlock(_lock);}}).start();return "testlock";}}
9、微服务启动类 BootApplication
@SpringBootApplication public class BootApplication {public static void main(String[] args) {SpringApplication.run(BootApplication.class, args);} }
三、启动演示
复制项目,第二个服务的端口改为8071,启动两个服务,先在浏览器里输入http://localhost:8070/testlock?name=zhang,3s后再输入http://localhost:8071/testlock?name=wang,3s后再输入http://localhost:8070/testlock?name=zhang1,3s后再输入http://localhost:8071/testlock?name=wang1,如果没有锁机制,打印的数据应该是交叉的,反之,同一时刻只会打印一次的请求,不会出现交叉打印数据的情况。
官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95
Spring Cloud分布式微服务系统中利用redssion实现分布式锁相关推荐
- (十六)java springcloud版b2b2c社交电商spring cloud分布式微服务-使用spring cloud Bus刷新配置...
b2b2c电子商务社交平台源码请加企鹅求求:一零三八七七四六二六.我们使用spring cloud分布式微服务云架构做了b2b2c的电子商务系统,除了架构本身自带的系统服务外,我们将b2b2c的业务服 ...
- java spring cloud版b2b2c社交电商spring cloud分布式微服务:分布式配置中心
JAVASpring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码请加企鹅求求:一零三八七七四六二六.Spring Cloud Config是Spring Cloud团队创建的一个 ...
- java版b2b2c社交电商spring cloud分布式微服务-服务提供与调用
java版b2b2c社交电商spring cloud分布式微服务源码请加企鹅求求:一零三八七七四六二六.上一篇文章我们介绍了eureka服务注册中心的搭建,这篇文章介绍一下如何使用eureka服务注册 ...
- java springcloud版b2b2c社交电商spring cloud分布式微服务(十三)断路器聚合监控(Hystrix Turbine)...
Spring cloud b2b2c电子商务社交平台源码请加企鹅求求:一零三八七七四六二六.讲述了如何利用Hystrix Dashboard去监控断路器的Hystrix command.当我们有很多个 ...
- (十二)java版b2b2c社交电商spring cloud分布式微服务:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪...
Spring Cloud Sleuth Spring cloud b2b2c电子商务社交平台源码请加企鹅求求:一零三八七七四六二六.一般的,一个分布式服务跟踪系统,主要有三部分:数据收集.数据存储和数 ...
- java springcloud版b2b2c社交电商spring cloud分布式微服务-docker-feign(四)
简介 Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码请加企鹅求求:一零三八七七四六二六.上一节,我们讨论了怎么通过,restTemlate调用cloud的生产者,实现起 ...
- java版b2b2c社交电商spring cloud分布式微服务:服务消费(Ribbon)
Spring Cloud Ribbon 电子商务社交平台源码请加企鹅求求:一零三八七七四六二六Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具.它 ...
- (十)java版b2b2c社交电商spring cloud分布式微服务- SSO单点登录之OAuth2.0登录认证(1)...
之前写了很多关于spring cloud的文章,今天我们对OAuth2.0的整合方式做一下笔记,首先我从网上找了一些关于OAuth2.0的一些基础知识点,帮助大家回顾一下知识点:Spring Clou ...
- java版b2b2c社交电商spring cloud分布式微服务(十)高可用的服务注册中心
电子商务社交平台源码请加企鹅求求:一零三八七七四六二六.文章 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka) 介绍了服务注册与发现,其中服务注册中心Eure ...
最新文章
- 虚拟局域网vlan实验报告_网络交换机如何规划,VLAN原理介绍
- NDK学习笔记-多线程与生产消费模式
- (HttpURLConnection)强制转化
- 【计算机网络复习 数据链路层】3.4.1 流量控制与可靠传输机制
- Problem C: 默认参数:求圆面积
- 高性能网站建设之减少Http连接数
- Helm 3 完整教程(十三):Helm 函数讲解(7)列表函数
- springmvc并发调用controller方法时对局部变量的影响
- Atitit.故障排除系列-----apache 不能启动的排除
- wsus微软补丁升级服务器不能下发,WSUS配置微软升级服务器操作.doc
- 网页版进销存2.0-部署手册(windows版)
- html 显示ai 矢量图,PS图层文件转变为AI矢量图
- 数据可视化(全彩)(十二五国家重点图书出版规划项目)
- xbox360能玩java我的世界吗_xbox360我的世界完整版god
- html 超链接标签 a 的基本用法
- linux桌面图标恢复,恢复Linux桌面下方面板上显示最小化的图标的方法
- Django讲课笔记02:Django环境搭建
- 聚焦:XuperOS成长计划FAQ
- 张小飞的Java之路——第九章
- 数据结构初阶——链式二叉树
热门文章
- java xml stax_如何使用Java StAX Iterator API用Java编写XML文件
- android浮动按钮_Android扩展浮动操作按钮
- 开课吧:C++入门必知必会的基础知识汇总
- 《深入理解Spark:核心思想与源码分析》——1.3节阅读环境准备
- Oracle SUn
- 仅此一文让你明白ASP.NET MVC原理
- 快慢指针算法及其应用
- STL模板之vector与sort的使用
- Salesforce LWC学习(二) helloWorld程序在VSCode中的实现
- java中JSON转含泛型对象