热门关键字:
jquery > jquery教程 > java > Redisson基本用法

Redisson基本用法

364
作者:管理员
发布时间:2020/4/10 15:54:31
评论数:0
转载请自觉注明原文:http://www.jq-school.com/Show.aspx?id=1267

Redisson基本用法

1.  Redisson

Redisson是Redis官方推荐的Java版的Redis客户端。它提供的功能非常多,也非常强大,此处我们只用它的分布式锁功能。

https://github.com/redisson/redisson

1.1.  基本用法

1 <dependency> 2 <groupId>org.redisson</groupId> 3 <artifactId>redisson</artifactId> 4 <version>3.11.1</version> 5 </dependency>

1.2.  Distributed locks and synchronizers

RedissonClient中提供了好多种锁,还有其它很多实用的方法

Redisson基本用法

Redisson基本用法

1.2.1.  Lock

默认,非公平锁

最简洁的一种方法

Redisson基本用法

指定超时时间 

Redisson基本用法

异步

Redisson基本用法

1.2.2  Fair Lock 

Redisson基本用法

Redisson基本用法

1.2.3  MultiLock

Redisson基本用法

1.2.4  RedLock

Redisson基本用法

1.3.  示例

pom.xml

 1 <?xml version="1.0" encoding="UTF-8"?>  2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  4 <modelVersion>4.0.0</modelVersion>  5 <parent>  6 <groupId>org.springframework.boot</groupId>  7 <artifactId>spring-boot-starter-parent</artifactId>  8 <version>2.1.6.RELEASE</version>  9 <relativePath/> <!-- lookup parent from repository --> 10 </parent> 11 <groupId>com.cjs.example</groupId> 12 <artifactId>cjs-redisson-example</artifactId> 13 <version>0.0.1-SNAPSHOT</version> 14 <name>cjs-redisson-example</name> 15 16 <properties> 17 <java.version>1.8</java.version> 18 </properties> 19 20 <dependencies> 21 <dependency> 22 <groupId>org.springframework.boot</groupId> 23 <artifactId>spring-boot-starter-data-jpa</artifactId> 24 </dependency> 25 <dependency> 26 <groupId>org.springframework.boot</groupId> 27 <artifactId>spring-boot-starter-data-redis</artifactId> 28 </dependency> 29 <dependency> 30 <groupId>org.springframework.boot</groupId> 31 <artifactId>spring-boot-starter-web</artifactId> 32 </dependency> 33 34 <!-- https://github.com/redisson/redisson#quick-start --> 35 <dependency> 36 <groupId>org.redisson</groupId> 37 <artifactId>redisson</artifactId> 38 <version>3.11.1</version> 39 </dependency> 40 41 42 <dependency> 43 <groupId>org.apache.commons</groupId> 44 <artifactId>commons-lang3</artifactId> 45 <version>3.9</version> 46 </dependency> 47 <dependency> 48 <groupId>com.alibaba</groupId> 49 <artifactId>fastjson</artifactId> 50 <version>1.2.58</version> 51 </dependency> 52 <dependency> 53 <groupId>org.apache.commons</groupId> 54 <artifactId>commons-pool2</artifactId> 55 <version>2.6.2</version> 56 </dependency> 57 58 <dependency> 59 <groupId>mysql</groupId> 60 <artifactId>mysql-connector-java</artifactId> 61 <scope>runtime</scope> 62 </dependency> 63 <dependency> 64 <groupId>org.projectlombok</groupId> 65 <artifactId>lombok</artifactId> 66 <optional>true</optional> 67 </dependency> 68 </dependencies> 69 70 <build> 71 <plugins> 72 <plugin> 73 <groupId>org.springframework.boot</groupId> 74 <artifactId>spring-boot-maven-plugin</artifactId> 75 </plugin> 76 </plugins> 77 </build> 78 79 </project> 

application.yml

 1 server:  2 port: 8080  3 spring:  4 application:  5 name: cjs-redisson-example  6 redis:  7 cluster:  8 nodes: 10.0.29.30:6379, 10.0.29.95:6379, 10.0.29.205:6379  9 lettuce: 10 pool: 11 min-idle: 0 12 max-idle: 8 13 max-active: 20 14 datasource: 15 url: jdbc:mysql://127.0.0.1:3306/test 16 username: root 17 password: 123456 18 driver-class-name: com.mysql.cj.jdbc.Driver 19 type: com.zaxxer.hikari.HikariDataSource 

RedissonConfig.java

 1 package com.cjs.example.lock.config;  2  3 import org.redisson.Redisson;  4 import org.redisson.api.RedissonClient;  5 import org.redisson.config.Config;  6 import org.springframework.context.annotation.Bean;  7 import org.springframework.context.annotation.Configuration;  8  9 /** 10  * @author ChengJianSheng 11  * @date 2019-07-26 12  */ 13 @Configuration 14 public class RedissonConfig { 15 16 @Bean 17 public RedissonClient redissonClient() { 18 Config config = new Config(); 19 config.useClusterServers() 20 .setScanInterval(2000) 21 .addNodeAddress("redis://10.0.29.30:6379", "redis://10.0.29.95:6379") 22 .addNodeAddress("redis://10.0.29.205:6379"); 23 24 RedissonClient redisson = Redisson.create(config); 25 26 return redisson; 27 } 28 29 } 

CourseServiceImpl.java 

 1 package com.cjs.example.lock.service.impl;  2  3 import com.alibaba.fastjson.JSON;  4 import com.cjs.example.lock.constant.RedisKeyPrefixConstant;  5 import com.cjs.example.lock.model.CourseModel;  6 import com.cjs.example.lock.model.CourseRecordModel;  7 import com.cjs.example.lock.repository.CourseRecordRepository;  8 import com.cjs.example.lock.repository.CourseRepository;  9 import com.cjs.example.lock.service.CourseService;  10 import lombok.extern.slf4j.Slf4j;  11 import org.apache.commons.lang3.StringUtils;  12 import org.redisson.api.RLock;  13 import org.redisson.api.RedissonClient;  14 import org.springframework.beans.factory.annotation.Autowired;  15 import org.springframework.data.redis.core.HashOperations;  16 import org.springframework.data.redis.core.StringRedisTemplate;  17 import org.springframework.stereotype.Service;  18  19 import java.util.concurrent.TimeUnit;  20  21 /**  22  * @author ChengJianSheng  23  * @date 2019-07-26  24  */  25 @Slf4j  26 @Service  27 public class CourseServiceImpl implements CourseService {  28  29 @Autowired  30 private CourseRepository courseRepository;  31 @Autowired  32 private CourseRecordRepository courseRecordRepository;  33 @Autowired  34 private StringRedisTemplate stringRedisTemplate;  35 @Autowired  36 private RedissonClient redissonClient;  37  38 @Override  39 public CourseModel getById(Integer courseId) {  40  41 CourseModel courseModel = null;  42  43 HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash();  44  45 String value = hashOperations.get(RedisKeyPrefixConstant.COURSE, String.valueOf(courseId));  46  47 if (StringUtils.isBlank(value)) {  48 String lockKey = RedisKeyPrefixConstant.LOCK_COURSE + courseId;  49 RLock lock = redissonClient.getLock(lockKey);  50 try {  51 boolean res = lock.tryLock(10, TimeUnit.SECONDS);  52 if (res) {  53 value = hashOperations.get(RedisKeyPrefixConstant.COURSE, String.valueOf(courseId));  54 if (StringUtils.isBlank(value)) {  55 log.info("从数据库中读取");  56 courseModel = courseRepository.findById(courseId).orElse(null);  57 hashOperations.put(RedisKeyPrefixConstant.COURSE, String.valueOf(courseId), JSON.toJSONString(courseModel));  58 }  59 }  60 } catch (InterruptedException e) {  61 e.printStackTrace();  62 } finally {  63 lock.unlock();  64 }  65 } else {  66 log.info("从缓存中读取");  67 courseModel = JSON.parseObject(value, CourseModel.class);  68 }  69  70 return courseModel;  71 }  72  73 @Override  74 public void upload(Integer userId, Integer courseId, Integer studyProcess) {  75  76 HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash();  77  78 String cacheKey = RedisKeyPrefixConstant.COURSE_PROGRESS + ":" + userId;  79 String cacheValue = hashOperations.get(cacheKey, String.valueOf(courseId));  80 if (StringUtils.isNotBlank(cacheValue) && studyProcess <= Integer.valueOf(cacheValue)) {  81 return;  82 }  83  84 String lockKey = "upload:" + userId + ":" + courseId;  85  86 RLock lock = redissonClient.getLock(lockKey);  87  88 try {  89 lock.lock(10, TimeUnit.SECONDS);  90  91 cacheValue = hashOperations.get(cacheKey, String.valueOf(courseId));  92 if (StringUtils.isBlank(cacheValue) || studyProcess > Integer.valueOf(cacheValue)) {  93 CourseRecordModel model = new CourseRecordModel();  94 model.setUserId(userId);  95 model.setCourseId(courseId);  96 model.setStudyProcess(studyProcess);  97 courseRecordRepository.save(model);  98 hashOperations.put(cacheKey, String.valueOf(courseId), String.valueOf(studyProcess));  99 } 100 101 } catch (Exception ex) { 102 log.error("获取所超时!", ex); 103 } finally { 104 lock.unlock(); 105 } 106 107 } 108 } 

StockServiceImpl.java

 1 package com.cjs.example.lock.service.impl;  2  3 import com.cjs.example.lock.constant.RedisKeyPrefixConstant;  4 import com.cjs.example.lock.service.StockService;  5 import org.apache.commons.lang3.StringUtils;  6 import org.springframework.beans.factory.annotation.Autowired;  7 import org.springframework.data.redis.core.HashOperations;  8 import org.springframework.data.redis.core.StringRedisTemplate;  9 import org.springframework.stereotype.Service; 10 11 /** 12  * @author ChengJianSheng 13  * @date 2019-07-26 14  */ 15 @Service 16 public class StockServiceImpl implements StockService { 17 18 @Autowired 19 private StringRedisTemplate stringRedisTemplate; 20 21 @Override 22 public int getByProduct(Integer productId) { 23 HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash(); 24 String value = hashOperations.get(RedisKeyPrefixConstant.STOCK, String.valueOf(productId)); 25 if (StringUtils.isBlank(value)) { 26 return 0; 27 } 28 return Integer.valueOf(value); 29 } 30 31 @Override 32 public boolean decrease(Integer productId) { 33 int stock = getByProduct(productId); 34 if (stock <= 0) { 35 return false; 36 } 37 HashOperations<String, String, String> hashOperations = stringRedisTemplate.opsForHash(); 38 hashOperations.put(RedisKeyPrefixConstant.STOCK, String.valueOf(productId), String.valueOf(stock - 1)); 39 return true; 40 } 41 } 

OrderServiceImpl.java

 1 package com.cjs.example.lock.service.impl;  2  3 import com.cjs.example.lock.model.OrderModel;  4 import com.cjs.example.lock.repository.OrderRepository;  5 import com.cjs.example.lock.service.OrderService;  6 import com.cjs.example.lock.service.StockService;  7 import lombok.extern.slf4j.Slf4j;  8 import org.redisson.api.RLock;  9 import org.redisson.api.RedissonClient; 10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.stereotype.Service; 12 13 import java.util.Date; 14 import java.util.UUID; 15 import java.util.concurrent.TimeUnit; 16 17 /** 18  * @author ChengJianSheng 19  * @date 2019-07-30 20  */ 21 @Slf4j 22 @Service 23 public class OrderServiceImpl implements OrderService { 24 25 @Autowired 26 private StockService stockService; 27 @Autowired 28 private OrderRepository orderRepository; 29 @Autowired 30 private RedissonClient redissonClient; 31 32 /** 33  * 乐观锁 34  */ 35 @Override 36 public String save(Integer userId, Integer productId) { 37 int stock = stockService.getByProduct(productId); 38 log.info("剩余库存:{}", stock); 39 if (stock <= 0) { 40 return null; 41 } 42 43 //  如果不加锁,必然超卖 44 45 RLock lock = redissonClient.getLock("stock:" + productId); 46 47 try { 48 lock.lock(10, TimeUnit.SECONDS); 49 50 String orderNo = UUID.randomUUID().toString().replace("-", "").toUpperCase(); 51 52 if (stockService.decrease(productId)) { 53 54 OrderModel orderModel = new OrderModel(); 55 orderModel.setUserId(userId); 56 orderModel.setProductId(productId); 57 orderModel.setOrderNo(orderNo); 58 Date now = new Date(); 59 orderModel.setCreateTime(now); 60 orderModel.setUpdateTime(now); 61 orderRepository.save(orderModel); 62 63 return orderNo; 64 } 65 66 } catch (Exception ex) { 67 log.error("下单失败", ex); 68 } finally { 69 lock.unlock(); 70 } 71 72 return null; 73 } 74 75 } 

OrderModel.java

 1 package com.cjs.example.lock.model;  2  3 import lombok.Data;  4  5 import javax.persistence.*;  6 import java.io.Serializable;  7 import java.util.Date;  8  9 /** 10  * @author ChengJianSheng 11  * @date 2019-07-30 12  */ 13 @Data 14 @Entity 15 @Table(name = "t_order") 16 public class OrderModel implements Serializable { 17 18 @Id 19 @GeneratedValue(strategy = GenerationType.IDENTITY) 20 private Integer id; 21 22 @Column(name = "order_no") 23 private String orderNo; 24 25 @Column(name = "product_id") 26 private Integer productId; 27 28 @Column(name = "user_id") 29 private Integer userId; 30 31 @Column(name = "create_time") 32 private Date createTime; 33 34 @Column(name = "update_time") 35 private Date updateTime; 36 } 

数据库脚本.sql

 1 SET NAMES utf8mb4;  2 SET FOREIGN_KEY_CHECKS = 0;  3  4 -- ----------------------------  5 -- Table structure for t_course  6 -- ----------------------------  7 DROP TABLE IF EXISTS `t_course`;  8 CREATE TABLE `t_course` (  9 `id` int(11) NOT NULL AUTO_INCREMENT, 10 `course_name` varchar(64) NOT NULL, 11 `course_type` tinyint(4) NOT NULL DEFAULT '1', 12 `start_time` datetime NOT NULL, 13 PRIMARY KEY (`id`) 14 ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; 15 16 -- ---------------------------- 17 -- Table structure for t_order 18 -- ---------------------------- 19 DROP TABLE IF EXISTS `t_order`; 20 CREATE TABLE `t_order` ( 21 `id` int(11) NOT NULL AUTO_INCREMENT, 22 `order_no` varchar(256) CHARACTER SET latin1 NOT NULL, 23 `user_id` int(11) NOT NULL, 24 `product_id` int(11) NOT NULL, 25 `create_time` datetime NOT NULL, 26 `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP, 27 PRIMARY KEY (`id`) 28 ) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; 29 30 -- ---------------------------- 31 -- Table structure for t_user_course_record 32 -- ---------------------------- 33 DROP TABLE IF EXISTS `t_user_course_record`; 34 CREATE TABLE `t_user_course_record` ( 35 `id` int(11) NOT NULL AUTO_INCREMENT, 36 `user_id` int(11) NOT NULL, 37 `course_id` int(11) NOT NULL, 38 `study_process` int(11) NOT NULL, 39 PRIMARY KEY (`id`) 40 ) ENGINE=InnoDB AUTO_INCREMENT=103 DEFAULT CHARSET=utf8mb4; 41 42 SET FOREIGN_KEY_CHECKS = 1; 

1.4  工程结构

https://github.com/chengjiansheng/cjs-redisson-example 

Redisson基本用法

1.5  Redis集群创建

Redisson基本用法

Redisson基本用法

Redisson基本用法

Redisson基本用法

Redisson基本用法

Redisson基本用法

Redisson基本用法

1.6  测试

测试/course/upload

Redisson基本用法

测试/order/create

Redisson基本用法

Redisson基本用法

Redisson基本用法

2.  Spring Integration

用法与Redisson类似

1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-integration</artifactId> 4 </dependency> 5 <dependency> 6 <groupId>org.springframework.integration</groupId> 7 <artifactId>spring-integration-redis</artifactId> 8 </dependency>
 1 package com.kaishustory.base.conf;  2  3 import org.springframework.context.annotation.Bean;  4 import org.springframework.context.annotation.Configuration;  5 import org.springframework.data.redis.connection.RedisConnectionFactory;  6 import org.springframework.integration.redis.util.RedisLockRegistry;  7  8 /**  9  * @author ChengJianSheng 10  * @date 2019-07-30 11  */ 12 @Configuration 13 public class RedisLockConfig { 14 15 @Bean 16 public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) { 17 return new RedisLockRegistry(redisConnectionFactory, "asdf") 18 } 19 20 } 
 1 @Autowired  2 private RedisLockRegistry redisLockRegistry;  3  4 public void save(Integer userId) {  5  6 String lockKey = "order:" + userId;  7  8 Lock lock = redisLockRegistry.obtain(lockKey);  9 try { 10 lock.lock(); 11 12 //todo 13 14 } finally { 15 lock.unlock(); 16 } 17 18 } 

3.  其它

https://github.com/redisson/redisson/wiki/8.-Distributed-locks-and-synchronizers 

https://www.cnblogs.com/cjsblog/p/9831423.html 





如果您觉得本文的内容对您的学习有所帮助:支付鼓励



关键字:Redisson基本用法
友荐云推荐