简介
Redisson 是一个在 Redis 的基础上实现的 Java 驻留内存数据网格(In-Memory Data Grid)。它提供了许多分布式 Java 对象和服务,包括分布式锁、分布式集合、分布式执行服务、分布式调度任务等。
使用
依赖
相关依赖,注意版本
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.redisson/redisson -->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.21.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
配置
spring.redis.host=192.168.0.120
spring.redis.port=6379
spring.redis.password=123456
spring.redis.timeout=3000
spring.redis.lettuce.pool.max-wait=-1
spring.redis.lettuce.pool.max-active=300
spring.redis.lettuce.pool.max-idle=100
spring.redis.lettuce.pool.min-idle=20
RedisConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}
RBloomFilterConfiguration
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 布隆过滤器配置
*/
@Configuration
public class RBloomFilterConfiguration {
@Bean
public RedissonClient redissonClient(){
Config config = new Config();
config.useSingleServer().setAddress("redis://192.168.0.120:6379");
config.useSingleServer().setPassword("123456");
RedissonClient redisson = Redisson.create(config);
return redisson;
}
/**
* 防⽌检查⽤户是否重复时查询数据库的布隆过滤器
*/
@Bean
public RBloomFilter<String> userRegisterCachePenetrationBloomFilter(RedissonClient redissonClient) {
RBloomFilter<String> cachePenetrationBloomFilter = redissonClient.
getBloomFilter("userRegisterCachePenetrationBloomFilter");
cachePenetrationBloomFilter.tryInit(100000000L, 0.001);
return cachePenetrationBloomFilter;
}
}
业务逻辑
public interface IRedissonService {
//测试布隆过滤器
void testBloomFilter();
//分布式锁
void testLock();
//写锁
void testWriteLock();
//读锁
void testReadLock();
}
@Service
@Transactional
public class RedissonServiceImpl implements IRedissonService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private RedissonClient redissonClient;
@Autowired
private RBloomFilter<String> userRegisterCachePenetrationBloomFilter;
public void testBloomFilter() {
// 新增数据到布隆过滤器中
userRegisterCachePenetrationBloomFilter.add("IRedissonService");
// 判断元素是否存在布隆过滤器
boolean hasUsername = userRegisterCachePenetrationBloomFilter.contains("IRedissonService");
System.out.println("testBloomFilter:" + hasUsername);
}
//TODO 注意 key 内容中不要包含一些关键词 比如 java,lock等等,否则会报错
@Override
public void testLock() {
RLock testLock = redissonClient.getLock("testL");
testLock.lock();//加锁
try {
//业务......
redisTemplate.opsForValue().set("testLK", "testLValue", 5, TimeUnit.SECONDS);
System.out.println("加锁成功");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
Object testLockValue = redisTemplate.opsForValue().get("testLK");
System.out.println("解锁成功" + testLockValue);
testLock.unlock();//解锁
}
}
@Override
public void testWriteLock() {
RReadWriteLock testWriteLock = redissonClient.getReadWriteLock("testWL");
try {
testWriteLock.writeLock().lock();
//业务......
redisTemplate.opsForValue().set("testWLK", "testWLV", 10, TimeUnit.SECONDS);
Thread.sleep(3000);
System.out.println("testWriteLock 加锁成功");
} catch (Exception ex) {
ex.printStackTrace();
} finally {
Object testWriteLockValue = redisTemplate.opsForValue().get("testWLK");
System.out.println("testWriteLock 解锁成功" + testWriteLockValue);
testWriteLock.writeLock().unlock();
}
}
@Override
public void testReadLock() {
RReadWriteLock testReadLock = redissonClient.getReadWriteLock("testRL");
try {
testReadLock.readLock().lock(2000, TimeUnit.MILLISECONDS);
//业务......
Object testWriteLockValue = redisTemplate.opsForValue().get("testWLK");
System.out.println("testReadLock 加锁成功" + testWriteLockValue);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
System.out.println("testReadLock 解锁成功");
testReadLock.readLock().unlock();
}
}
}
单元测试
import com.xysd.commodity.application.impl.MyAspectServiceImpl;
import com.xysd.commodity.domain.PaymentProcess;
import com.xysd.common.domain.Holiday;
import com.xysd.test.application.IDataCacheService;
import com.xysd.test.application.IDomeService;
import com.xysd.test.application.IRedissonService;
import com.xysd.test.infrastructure.DomeRepositoryHibernate;
import com.xysd.utils.calendar.CalendarUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.UUID;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = CDAApplication.class)
public class CDAApplicationTest {
@Autowired
private IRedissonService redissonService;
@Test
public void testBloomFilter() {
redissonService.testBloomFilter();
}
@Test
public void testLock() throws Exception {
redissonService.testLock();
redissonService.testWriteLock();
Thread.sleep(5000);
redissonService.testReadLock();
}
}