赞
踩
一, 添加所需依赖
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>2.6.5</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.commons</groupId>
- <artifactId>commons-pool2</artifactId>
- </dependency>
二, redis配置参数
- # redis
- spring.redis.database=0
- spring.redis.host=r-uf63gkx4qs0ygz3rag.redis.rds.aliyuncs.com
- spring.redis.port=6379
- spring.redis.password=ywjAYKDz28RFCJg9iRW4
- # 连接超时时间
- spring.redis.timeout=5000
- # 连接池最大连接数(使用负值表示没有限制)
- spring.redis.lettuce.pool.max-active=5000
- # 连接池中的最小空闲连接
- spring.redis.lettuce.pool.min-idle=1
- # 连接池中的最大空闲连接
- spring.redis.lettuce.pool.max-idle=100
- # 连接池最大阻塞等待时间(使用负值表示没有限制)
- spring.redis.lettuce.pool.max-wait=1000
- #在关闭客户端连接之前等待任务处理完成的最长时间,在这之后,无论任务是否执行完成,都会被执行器关闭,默认100ms
- spring.redis.lettuce.shutdown-timeout=1000
- #是否缓存空值
- spring.cache.redis.cache-null-values=false
三, redis连接池设置
- package com.shuinfo.ods_poc.config;
-
- import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.cache.annotation.EnableCaching;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisPassword;
- import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
- import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
- import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
- import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
- import org.springframework.data.redis.core.ReactiveRedisTemplate;
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.RedisSerializationContext;
- import org.springframework.data.redis.serializer.RedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
- import java.time.Duration;
-
- @Configuration
- @EnableCaching
- public class RedisConfig {
- @Value("${spring.redis.database}")
- private int database;
-
- @Value("${spring.redis.host}")
- private String host;
-
- @Value("${spring.redis.password}")
- private String password;
-
- @Value("${spring.redis.port}")
- private int port;
-
- @Value("${spring.redis.timeout}")
- private long timeout;
-
- @Value("${spring.redis.lettuce.shutdown-timeout}")
- private long shutDownTimeout;
-
- @Value("${spring.redis.lettuce.pool.max-idle}")
- private int maxIdle;
-
- @Value("${spring.redis.lettuce.pool.min-idle}")
- private int minIdle;
-
- @Value("${spring.redis.lettuce.pool.max-active}")
- private int maxActive;
-
- @Value("${spring.redis.lettuce.pool.max-wait}")
- private long maxWait;
-
- Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
-
- @Bean
- public LettuceConnectionFactory lettuceConnectionFactory() {
- GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
- genericObjectPoolConfig.setMaxIdle(maxIdle);
- genericObjectPoolConfig.setMinIdle(minIdle);
- genericObjectPoolConfig.setMaxTotal(maxActive);
- genericObjectPoolConfig.setMaxWait(Duration.ofMillis(maxWait));
- //每隔多少毫秒,空闲线程驱逐器关闭多余的空闲连接,且保持最少空闲连接可用,这个值最好设置大一点,否者影响性能
- genericObjectPoolConfig.setTimeBetweenEvictionRuns(Duration.ofMillis(1000));
- RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
- redisStandaloneConfiguration.setDatabase(database);
- redisStandaloneConfiguration.setHostName(host);
- redisStandaloneConfiguration.setPort(port);
- redisStandaloneConfiguration.setPassword(RedisPassword.of(password));
- LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder()
- .commandTimeout(Duration.ofMillis(timeout))
- .shutdownTimeout(Duration.ofMillis(shutDownTimeout))
- .poolConfig(genericObjectPoolConfig)
- .build();
-
- LettuceConnectionFactory factory = new LettuceConnectionFactory(redisStandaloneConfiguration, clientConfig);
- // factory.setShareNativeConnection(true);
- // factory.setValidateConnection(false);
- return factory;
- }
-
- @Bean
- public RedisSerializationContext redisSerializationContext() {
- RedisSerializationContext.RedisSerializationContextBuilder builder = RedisSerializationContext.newSerializationContext();
- builder.key(StringRedisSerializer.UTF_8);
- builder.value(RedisSerializer.json());
- builder.hashKey(StringRedisSerializer.UTF_8);
- builder.hashValue(StringRedisSerializer.UTF_8);
- return builder.build();
- }
-
- @Bean
- public ReactiveRedisTemplate<String, Object> reactiveRedisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
- RedisSerializationContext serializationContext = redisSerializationContext();
- return new ReactiveRedisTemplate(lettuceConnectionFactory,serializationContext);
- }
-
- }
四, 封装工具类
- package com.shuinfo.ods_poc.utils;
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.ReactiveRedisTemplate;
- import org.springframework.stereotype.Component;
- import reactor.core.publisher.Flux;
- import reactor.core.publisher.Mono;
-
- import java.time.Duration;
-
- @Component
- @Slf4j
- public class RedisUtils {
- private static final Duration EXPIRED_DAY = Duration.ofDays(7);
- private static final Duration EXPIRED_HOURS = Duration.ofHours(30);
- private static final Duration EXPIRED_MINUTES = Duration.ofMinutes(1);
- @Autowired
- private ReactiveRedisTemplate reactiveRedisTemplate;
-
- public <T> void put(String key,T value){
- reactiveRedisTemplate.opsForValue()
- .set(key,value,EXPIRED_HOURS).subscribe((b->{}));
- }
-
- public <T> Mono<T> get(String key){
- return reactiveRedisTemplate.opsForValue()
- .get(key);
- }
-
- public <T> void putList(String key, T value){
- reactiveRedisTemplate.opsForSet().add(key,value).subscribe();
- }
-
- public <T> Flux<T> getList(String key){
- return reactiveRedisTemplate.opsForSet().members(key);
- }
-
- public void remove(String key){
- reactiveRedisTemplate.opsForSet().delete(key).subscribe();
- }
- public <T> void putZSet(String key, T value,String score){
- reactiveRedisTemplate.opsForZSet().add(key,value,Double.valueOf(score))
- .doOnError(e->{
- log.error(e.toString());
- }).subscribe();
- }
-
- public <T> Flux<T> getZSet(String key,Integer page,Integer size){
- if(page == null || size == null){
- return reactiveRedisTemplate.opsForZSet().rangeByScore(key,
- org.springframework.data.domain.Range.unbounded());
- }
- return reactiveRedisTemplate.opsForZSet().rangeByScore(key,
- org.springframework.data.domain.Range.unbounded(),
- org.springframework.data.redis.connection
- .RedisZSetCommands.Limit.limit()
- .offset((page - 1) * size).count(size)
- );
- }
-
- }
五, 使用
- //存缓存
- redisUtils.putList(RedisConstant.FIND_ORDER_BY_UID_AND_OTYPE
- + req.getMemberCode()+req.getBusinessTypeCode(),req);
- redisUtils.putList(RedisConstant.FIND_ORDER_BY_SHOP_POS_INFO
- + req.getShopCode()+req.getOrderTime()+req.getPosRefId()
- + req.getReceiptNumber(),req);
六, 分布式锁(RedisTemplate)
- package com.shuinfo.ods_poc.utils;
-
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.data.redis.connection.RedisStringCommands;
- import org.springframework.data.redis.connection.ReturnType;
- import org.springframework.data.redis.core.RedisCallback;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.core.types.Expiration;
- import org.springframework.stereotype.Component;
- import javax.annotation.Resource;
- import java.nio.charset.Charset;
- import java.util.concurrent.TimeUnit;
-
- @Component
- @Slf4j
- public class RedisLockUtils {
- @Resource
- private RedisTemplate redisTemplate;
-
- private static final Long DEFAULT_EXPIRE_TIME = 1L;
- private static final TimeUnit DEFAULT_UNIT = TimeUnit.SECONDS;
- private static final String UNLOCK_LUA;
- private static final String CHARCODE = "UTF-8";
-
- /**
- * 释放锁脚本,原子操作
- */
- static {
- StringBuilder sb = new StringBuilder();
- sb.append("if redis.call(\"get\",KEYS[1]) == ARGV[1] ");
- sb.append("then ");
- sb.append(" return redis.call(\"del\",KEYS[1]) ");
- sb.append("else ");
- sb.append(" return 0 ");
- sb.append("end ");
- UNLOCK_LUA = sb.toString();
- }
-
- /**
- * 获取分布式锁,原子操作
- * @param lockKey
- * @param requestId 唯一ID, 可以使用UUID.randomUUID().toString();
- * @param expire
- * @param timeUnit
- * @return
- */
- public boolean tryLock(String lockKey, String requestId, long expire, TimeUnit timeUnit) {
- try{
- RedisCallback<Boolean> callback = (connection) ->
- connection.set(lockKey.getBytes(Charset.forName(CHARCODE)),
- requestId.getBytes(Charset.forName(CHARCODE)),
- Expiration.seconds(timeUnit.toSeconds(expire)),
- RedisStringCommands.SetOption.SET_IF_ABSENT);
- return (Boolean)redisTemplate.execute(callback);
- } catch (Exception e) {
- log.error("redis lock error.", e);
- }
- return false;
- }
- public boolean tryLock(String lockKey, String requestId) {
- return tryLock( lockKey, requestId,DEFAULT_EXPIRE_TIME,DEFAULT_UNIT);
- }
-
- /**
- * 释放锁
- * @param lockKey
- * @param requestId 唯一ID
- * @return
- */
- public boolean releaseLock(String lockKey, String requestId) {
- RedisCallback<Boolean> callback = (connection) ->
- connection.eval(UNLOCK_LUA.getBytes(), ReturnType.BOOLEAN ,
- 1, lockKey.getBytes(Charset.forName(CHARCODE)),
- requestId.getBytes(Charset.forName(CHARCODE)));
- return (Boolean)redisTemplate.execute(callback);
- }
-
- /**
- * 获取Redis锁的value值
- * @param lockKey
- * @return
- */
- public String get(String lockKey) {
- try {
- RedisCallback<String> callback = (connection) ->
- new String(connection.get(lockKey.getBytes()), Charset.forName(CHARCODE));
- return (String)redisTemplate.execute(callback);
- } catch (Exception e) {
- log.error("get redis occurred an exception", e);
- }
- return null;
- }
-
- }
可参照阿里文档:
通过客户端程序连接Redis_云数据库 Redis 版(Redis)-阿里云帮助中心
注: redis的参数还需要关注redis服务端的参数,有些默认的参数可能实际并不适合
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。