1. 底子使用
1.1 引入依赖
- <dependencies>
- <dependency>
- <groupId>org.redisson</groupId>
- <artifactId>redisson-spring-boot-starter</artifactId>
- </dependency>
- </dependencies>
复制代码 包含的依赖如下
1.2 配置文件
其实默认主机就是 127.0.0.1,默认端口是 6379,一致的话可以不用配置
- spring:
- data:
- redis:
- host: 127.0.0.1
- password: redis
复制代码 1.3 测试类
- import org.redisson.api.RBucket;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RBucket<String> bucket = redissonClient.getBucket("test");
- bucket.set("hello");
- }
- @GetMapping("/get")
- public String get() {
- RBucket<String> bucket = redissonClient.getBucket("test");
- return bucket.get();
- }
- }
复制代码 1.4 测试
访问 /test 接口,利用 Redis 管理工具可以看到数据已经添加了进来
在访问 /get 接口,乐成获取到数据
2. 设置序列化
上面可以看到在 Redis 管理工具中查看数据是一串字符,并不直观,可以自界说数据序列化
2.1 配置类
- import org.redisson.Redisson;
- import org.redisson.api.RedissonClient;
- import org.redisson.codec.JsonJacksonCodec;
- import org.redisson.config.Config;
- import org.redisson.config.SingleServerConfig;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- @Configuration
- public class RedissonConfig {
- @Bean
- public RedissonClient redissonClient() {
- Config config = new Config();
- // 单机模式
- SingleServerConfig singleServerConfig = config.useSingleServer();
- singleServerConfig.setAddress("redis://127.0.0.1:6379");
- singleServerConfig.setPassword("redis");
- // JSON序列化
- config.setCodec(new JsonJacksonCodec());
- return Redisson.create(config);
- }
- }
复制代码 这里已经配置了主机等相干信息,因此配置文件里的配置可以去除,或者这里直接取配置文件的值,具体根据情况选择,其他的序列化类如下
编码类名称说明org.redisson.codec.JsonJacksonCodecJackson JSON 编码org.redisson.codec.AvroJacksonCodecAvro 一种二进制的 JSON 编码org.redisson.codec.SmileJacksonCodecSmile一种 二进制的 JSON 编码org.redisson.codec.CborJacksonCodecCBOR 一种二进制的 JSON 编码org.redisson.codec.MsgPackJacksonCodecMsgPack 一种 二进制的 JSON 编码org.redisson.codec.IonJacksonCodecAmazon Ion 亚马逊的 Ion 编码,格式与 JSON 类似org.redisson.codec.KryoCodecKryo 二进制对象序列化编码org.redisson.codec.SerializationCodecJDK 序列化编码org.redisson.codec.FstCodecFST 10 倍于 JDK 序列化性能而且 100% 兼容的编码org.redisson.codec.LZ4CodecLZ4 压缩型序列化对象编码org.redisson.codec.SnappyCodecSnappy 另一个压缩型序列化对象编码org.redisson.client.codec.JsonJacksonMapCodec基于 Jackson 的映射类使用的编码,可用于避免序列化类的信息,以及用于办理使用byte[] 碰到的问题org.redisson.client.codec.StringCodec纯字符串编码(无转换)org.redisson.client.codec.LongCodec纯整长型数字编码(无转换)org.redisson.client.codec.ByteArrayCodec字节数组编码org.redisson.codec.CompositeCodec用来组合多种不同编码在一起 2.2 测试
访问 /test 接口,再查看数据可以看到已经序列化成 JSON 格式
3. 底子数据结构使用
3.1 String
其实上面的示例用的就是字符串操作,通过 RBucket 对象来操作字符串数据结构
创建一个实体类
- import lombok.Builder;
- import lombok.Data;
- import java.io.Serial;
- import java.io.Serializable;
- @Data
- @Builder
- public class Article implements Serializable {
- @Serial
- private static final long serialVersionUID = -8862397425409851538L;
-
- private String title;
- private String content;
- }
复制代码 存储对象,简单示比方下:
- import org.redisson.api.RBucket;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RBucket<Object> bucket = redissonClient.getBucket("test");
- bucket.set(Article.builder().title("demo").content("test redisson").build());
- }
- }
复制代码 数据如下:
3.2 Hash
通过 RMap 对象来操作哈希数据结构,简单示比方下:
- import org.redisson.api.RMap;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RMap<String, Article> rMap = redissonClient.getMap("test");
- rMap.put("k1", Article.builder().title("demo").content("test redisson").build());
- }
- }
复制代码 数据如下:
3.3 List
3.3.1 无序
通过 RList 对象来操作列表数据结构,简单示比方下:
- import org.redisson.api.RList;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RList<Article> rList = redissonClient.getList("test");
- rList.add(Article.builder().title("demo").content("test redisson").build());
- rList.add(Article.builder().title("demo").content("test redisson").build());
- }
- }
复制代码 数据如下:
3.3.2 有序
通过 RSortedSet 对象来操作有序集合数据结构
改造一下实体类,实现 Comparable 接口
- import lombok.Data;
- import java.io.Serial;
- import java.io.Serializable;
- @Data
- public class Article implements Serializable, Comparable<Article> {
- @Serial
- private static final long serialVersionUID = -8862397425409851538L;
- private Long id;
- private String title;
- private String content;
- @Override
- public int compareTo(Article article) {
- return this.getId().compareTo(article.getId());
- }
- }
复制代码 简单示比方下:
- import org.redisson.api.RSortedSet;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RSortedSet<Article> rSortedSet = redissonClient.getSortedSet("test");
- Article article1 = new Article();
- article1.setId(22L);
- article1.setTitle("demo");
- article1.setContent("test redisson");
- rSortedSet.add(article1);
- Article article2 = new Article();
- article2.setId(11L);
- article2.setTitle("demo");
- article2.setContent("test redisson");
- rSortedSet.add(article2);
- }
- }
复制代码 数据如下,可以看到数据根据 id 排序
3.4 Set
通过 RSet 对象来操作集合数据结构,简单示比方下:
- import org.redisson.api.RSet;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RSet<Article> rSet = redissonClient.getSet("test");
- rSet.add(Article.builder().title("demo").content("test redisson").build());
- rSet.add(Article.builder().title("demo").content("test redisson").build());
- }
- }
复制代码 数据如下,可以看到重复数据被去除了
3.5 Zset
通过 RScoredSortedSet 来操作带分数的有序集合数据结构,简单示比方下:
- import org.redisson.api.*;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RScoredSortedSet<String> rScoredSortedSet = redissonClient.getScoredSortedSet("test");
- rScoredSortedSet.add(600.1, "test1");
- rScoredSortedSet.add(500.3, "test2");
- rScoredSortedSet.add(900.3, "test3");
- rScoredSortedSet.add(200.9, "test1");
- }
- }
复制代码 数据如下,可以看到根据分数来排序,并且重复数据被排除了
4. 布隆过滤器
可以用于检索一个元素是否在一个集合中
- import org.redisson.api.RBloomFilter;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- import java.time.Duration;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RBloomFilter<String> rBloomFilter = redissonClient.getBloomFilter("test");
- // 初始化预期插入的数据量为10000和期望误差率为0.01
- rBloomFilter.tryInit(10000, 0.01);
- // 插入部分数据
- rBloomFilter.add("100");
- rBloomFilter.add("200");
- rBloomFilter.add("300");
- // 设置过期时间
- rBloomFilter.expire(Duration.ofSeconds(30));
- // 判断是否存在
- System.out.println(rBloomFilter.contains("300")); // true
- System.out.println(rBloomFilter.contains("200")); // true
- System.out.println(rBloomFilter.contains("999")); // false
- }
- }
复制代码 5. 分布式自增 ID
参考代码如下:
- import org.redisson.api.RAtomicLong;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RAtomicLong rAtomicLong = redissonClient.getAtomicLong("test");
- System.out.println(rAtomicLong.incrementAndGet());
- }
- }
复制代码 6. 分布式锁
6.1 未加锁情况
模仿一个库存扣减操作
- import org.redisson.api.RBucket;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RBucket<Integer> bucket = redissonClient.getBucket("num");
- Integer num = bucket.get();
- if (num > 0) {
- System.out.println("扣减库存, 当前库存: " + --num);
- bucket.set(num);
- } else {
- System.out.println("库存不足");
- }
- }
- }
复制代码 使用 Jemter 模仿并发场景
点击运行后可以看到明显出现了并发问题
6.2 加锁情况
修改下库存扣减代码
- import org.redisson.api.RBucket;
- import org.redisson.api.RLock;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RLock rLock = redissonClient.getLock("test");
- try {
- rLock.lock();
- RBucket<Integer> bucket = redissonClient.getBucket("num");
- Integer num = bucket.get();
- if (num > 0) {
- System.out.println("扣减库存, 当前库存: " + --num);
- bucket.set(num);
- } else {
- System.out.println("库存不足");
- }
- } finally {
- rLock.unlock();
- }
- }
- }
复制代码 再次模仿并发请求,可以看到问题已包办理
6.3 加锁操作耗时长
当加锁操作耗时较长时,假如多个请求进来,其他的请求会不停堵塞,可以使用 tryLock 来尝试获取锁,获取不到先返回相应
- import org.redisson.api.RBucket;
- import org.redisson.api.RLock;
- import org.redisson.api.RedissonClient;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RestController;
- @RestController
- public class DemoController {
- private final RedissonClient redissonClient;
- @Autowired
- public DemoController(RedissonClient redissonClient) {
- this.redissonClient = redissonClient;
- }
- @GetMapping("/test")
- public void test() {
- RLock rLock = redissonClient.getLock("test");
- try {
- if (rLock.tryLock()) {
- RBucket<Integer> bucket = redissonClient.getBucket("num");
- Integer num = bucket.get();
- Thread.sleep(5000);
- if (num > 0) {
- System.out.println("扣减库存, 当前库存: " + --num);
- bucket.set(num);
- } else {
- System.out.println("库存不足");
- }
- } else {
- System.out.println("请稍后再试");
- }
- } catch (InterruptedException e) {
- System.out.println(e.getMessage());
- Thread.currentThread().interrupt();
- } finally {
- // 是否是锁定状态且是当前执行线程的锁
- if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
- rLock.unlock();
- }
- }
- }
- }
复制代码 模仿并发请求,这里将时间设置长一点,可以看到获取到锁的请求则去举行库存扣减,获取不到先返回相应
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |