Springboot集成Redisson
redissson可以提供分布式锁,延时队列,布隆过滤器等Redis高级功能,结合lettuce使用可以极大使用redis的各种特性,本文介绍如何在springboot框架下集成redisson
lettuce集成请参考:Sringboot 集成redis(基于lettuce)
https://blog.csdn.net/shuoyueqishilove/article/details/112417390
引入坐标:
<!-- redisson-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>${redisson.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
在此基础之上,需要在resource目录下新增redisson配置文件,以下分别展示单机,集群和哨兵模式的配置文件
单机模式
新增redissonSingle.yml文件
---
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
# address: "redis://127.0.0.1:6379" #windows
address: "redis://192.168.26.128:6379" #linux
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 32
connectionPoolSize: 64
database: 0
dnsMonitoringInterval: 5000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
"transportMode": NIO
集群模式
新增redissonCluster.yml文件
---
clusterServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
nodeAddresses:
- "redis://127.0.0.1:7004"
- "redis://127.0.0.1:7001"
- "redis://127.0.0.1:7000"
scanInterval: 1000
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
"transportMode": NIO
哨兵模式
新增redissonSentinel.yml文件
---
sentinelServersConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
loadBalancer: !<org.redisson.connection.balancer.RoundRobinLoadBalancer> {}
slaveSubscriptionConnectionMinimumIdleSize: 1
slaveSubscriptionConnectionPoolSize: 50
slaveConnectionMinimumIdleSize: 32
slaveConnectionPoolSize: 64
masterConnectionMinimumIdleSize: 32
masterConnectionPoolSize: 64
readMode: "SLAVE"
sentinelAddresses:
- "redis://127.0.0.1:26379"
- "redis://127.0.0.1:26389"
masterName: "mymaster"
database: 0
threads: 0
nettyThreads: 0
codec: !<org.redisson.codec.JsonJacksonCodec> {}
"transportMode": NIO
Redisson单机配置
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import java.io.IOException;
@Configuration
public class RedissonConfig {
/**
* redisson客户端
* @return
* @throws IOException
*/
@Bean(destroyMethod = "shutdown")
public RedissonClient redissonClient() throws IOException {
Config config = Config.fromYAML(new ClassPathResource("redissonSingle.yml").getInputStream());
return Redisson.create(config);
}
}
测试redisson
package com.xxx.xlt.controller;
import com.xxx.xlt.utils.redis.RedisUtil;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RLock;
import org.redisson.api.RQueue;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/redisson")
public class RedissonController {
private static Logger logger = LoggerFactory.getLogger(RedissonController.class);
private static final String PRODUCT = "MoonCake";
private static final String AA= "aa";
private static Integer stock = 100;
@Autowired
private RedissonClient redissonClient;
@GetMapping("/lockAdd")
public void lockAdd() throws Exception {
//对数据进行加锁
RLock lock = redissonClient.getLock(PRODUCT);
if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
if (stock > 0) {
stock -= 1;
RedisUtil.set(AA,stock,50);
Integer product = (Integer)RedisUtil.get(AA);
logger.info("Get from redis, AA="+product);
logger.info("扣减成功,库存stock:" + stock);
Thread.sleep(5000);
} else {
//没库存
logger.info("扣减失败,库存不足");
}
//解锁
lock.unlock();
}
}
@GetMapping("/queue/push")
public void pushQueue() throws Exception {
RLock writeQueueLock = redissonClient.getLock("writeQueueLock");
if (writeQueueLock.tryLock(500,TimeUnit.MILLISECONDS)) {
RQueue<Object> xltQueue = redissonClient.getQueue("xltQueue");
xltQueue.add("queue body1");
xltQueue.add("queue body2");
xltQueue.add("queue body3");
writeQueueLock.unlock();
}
}
@GetMapping("queue/poll")
public void pollQueue() throws Exception {
RLock readQueueLock = redissonClient.getLock("readQueueLock");
if (readQueueLock.tryLock(1000,TimeUnit.MILLISECONDS)) {
RQueue<Object> xltQueue = redissonClient.getQueue("xltQueue");
while (xltQueue.size()>0) {
String poll = (String)xltQueue.poll();
logger.info("poll msg from rabbit, msg="+poll);
}
readQueueLock.unlock();
}
}
@GetMapping("bloom/filter")
public void bloomFilter() throws Exception {
RLock bloomFilterLock = redissonClient.getLock("bloomFilterLock");
if (bloomFilterLock.tryLock(200,100*1000,TimeUnit.MILLISECONDS)) {
RBloomFilter<Object> xltRecords = redissonClient.getBloomFilter("xltRecords");
xltRecords.tryInit(100,0.001);
int TOTAL=100;
int cnt = 0;
for (int i=0;i<TOTAL;i++) {
xltRecords.add("Article_"+i);
if (!xltRecords.contains("Article_" + (i-1))) {
logger.info("NOT Contains Article_"+i*10);
cnt++;
}
}
logger.info("total="+TOTAL+",error cnt="+cnt);
bloomFilterLock.unlock();
}
}
}
其他配置请参考官方文档:
https://github.com/redisson/redisson/wiki/2.-%E9%85%8D%E7%BD%AE%E6%96%B9%E6%B3%95