点击箭头处
“JAVA日知录”
,关注并星标哟!!
本文作者:水坎92
原文链接:http://www.javadaily.cn/articles/2020/03/14/1584178764395.html
概述
在Redis中默认有16个库,一些业务场景需要对Redis分库,每个库按业务需求存储不同数据。比如下面:
public enum RedisDBEnum { Default(0,"默认"), Banner(1,"Banner热数据"), Captcha_Token(2, "图片验证码/短信验证码/token"), ShoppingCart(3, "购物车"), Order(4,"订单"), Goods(5,"商品"), User(6, "用户"), District(7,"中国省份城市数据库"); //TODO and so on private Integer index; private String desc; private RedisDBEnum(Integer index, String desc) { this.index = index; this.desc = desc; } public Integer getIndex() { return index; } public String getDesc() { return desc; }}
使用原生的 spring-boot-starter-data-redis
默认只能构建出单例的 RedisTemplate 和 LettuceConnectionFactory,并且只能操作指定的一个Redis 库。所以,我们需要 改造LettuceConnectionFactory 让其能构建多个 RedisTemplate 。
实现过程
在 pom.xml 中引入相关依赖
<!-- 配置管理,里面有依赖FastJson --><dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId></dependency><dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId></dependency><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId></dependency>
修改bootstrap配置文集
src/main/resources/bootstrap.properties
#配置中心spring.cloud.nacos.config.server-addr=192.168.1.4:8848spring.cloud.nacos.config.namespace=c51764ea-936b-42a9-a169-8b78ca9ea93espring.cloud.nacos.config.ext-config[0].data-id=redis_config.propertiesspring.cloud.nacos.config.ext-config[0].group=DEFAULT_GROUPspring.cloud.nacos.config.ext-config[0].refresh=false
在Nacos的DEV命名空间新增redis_config.properties 配置文件
redis.host=192.168.1.4redis.port=6379redis.password=redis.timeout=10000redis.lettuce.pool.max-idle=4redis.lettuce.pool.min-idle=0redis.lettuce.pool.max-active=8redis.lettuce.pool.max-wait=10000redis.lettuce.shutdown-timeout=4000
编写配置类RedisConfig.java
import java.time.Duration;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import lombok.Data;@Data@Component@ConfigurationProperties(prefix = "redis")public class RedisConfig { private String host; private Integer port; private String password; private Duration timeout; private final Lettuce lettuce = new Lettuce(); @Data public static class Pool { private int maxIdle = 8; private int minIdle = 0; private int maxActive = 8; private Duration maxWait = Duration.ofMillis(-1); private Duration timeBetweenEvictionRuns; } @Data public static class Lettuce { private Duration shutdownTimeout = Duration.ofMillis(100); private Pool pool; }}
构建多个RedisTemplate
import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class ProjectRedisTemplate { @Autowired private RedisConfig redisConfig; private LettuceConnectionFactory createLettuceConnectionFactory(int dbIndex) { // Redis配置 RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration(redisConfig.getHost(), redisConfig.getPort()); redisConfiguration.setDatabase(dbIndex); redisConfiguration.setPassword(redisConfig.getPassword()); // 连接池配置 GenericObjectPoolConfig<Object> genericObjectPoolConfig = new GenericObjectPoolConfig<Object>(); RedisConfig.Pool pool = redisConfig.getLettuce().getPool(); genericObjectPoolConfig.setMaxIdle(pool.getMaxIdle()); genericObjectPoolConfig.setMinIdle(pool.getMinIdle()); genericObjectPoolConfig.setMaxTotal(pool.getMaxActive()); genericObjectPoolConfig.setMaxWaitMillis(pool.getMaxWait().toMillis()); // Redis客户端配置 LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration .builder().commandTimeout(redisConfig.getTimeout()); builder.shutdownTimeout(redisConfig.getLettuce().getShutdownTimeout()); builder.poolConfig(genericObjectPoolConfig); // 根据配置和客户端配置创建连接 LettuceClientConfiguration lettuceClientConfiguration = builder.build(); LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(redisConfiguration, lettuceClientConfiguration); lettuceConnectionFactory.afterPropertiesSet(); return lettuceConnectionFactory; } /** * Banner 数据存储 * * @return */ @Bean public RedisTemplate<String, Object> bannerRedisTemplate() { LettuceConnectionFactory lettuceConnectionFactory = createLettuceConnectionFactory(RedisDBEnum.Banner.getIndex()); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); redisTemplate.setValueSerializer(fastJsonRedisSerializer); redisTemplate.setHashValueSerializer(fastJsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 验证码/token 数据存储 * * @return */ @Bean public RedisTemplate<String, Object> captchaTokenRedisTemplate() { LettuceConnectionFactory lettuceConnectionFactory = createLettuceConnectionFactory(RedisDBEnum.Captcha_Token.getIndex()); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); redisTemplate.setValueSerializer(fastJsonRedisSerializer); redisTemplate.setHashValueSerializer(fastJsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; } /** * 默认 * * @return */ @Bean public RedisTemplate<String, Object> redisTemplate() { LettuceConnectionFactory lettuceConnectionFactory = createLettuceConnectionFactory(RedisDBEnum.Default.getIndex()); RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>(); redisTemplate.setConnectionFactory(lettuceConnectionFactory); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(stringRedisSerializer); redisTemplate.setHashKeySerializer(stringRedisSerializer); FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class); redisTemplate.setValueSerializer(fastJsonRedisSerializer); redisTemplate.setHashValueSerializer(fastJsonRedisSerializer); redisTemplate.afterPropertiesSet(); return redisTemplate; }}
业务测试
@Slf4j@RestControllerpublic class DemoController { @Autowired @Qualifier("bannerRedisTemplate") private RedisTemplate<String, Object> bannerRedisTemplate; @Autowired @Qualifier("captchaTokenRedisTemplate") private RedisTemplate<String, Object> captchaTokenRedisTemplate; @GetMapping("/store") public String store() { captchaTokenRedisTemplate.opsForValue().set("captchaPureNumber", RandomStringUtils.randomNumeric(6), 30, TimeUnit.MINUTES); captchaTokenRedisTemplate.opsForValue().set("token", RandomStringUtils.randomAlphabetic(21), 30, TimeUnit.MINUTES); List<Money> moneyList = Arrays.asList(new Money(1L, "人民币", 100), new Money(2L, "越南盾", 100000)); bannerRedisTemplate.opsForList().rightPushAll("homePageLeftBanner", moneyList); SetOperations<String, Object> moneySet = bannerRedisTemplate.opsForSet(); moneySet.add("homePageRightBanner", new Money(11L, "日元", 10000)); moneySet.add("homePageRightBanner", new Money(22L, "加元", 20000)); moneySet.add("homePageRightBanner", new Money(33L, "泰铢", 30000)); return "somewhere"; } @GetMapping("/view") public String view(Model model) { model.addAttribute("captchaPureNumber", captchaTokenRedisTemplate.opsForValue().get("captchaPureNumber")); model.addAttribute("token", captchaTokenRedisTemplate.opsForValue().get("token")); Set<Object> homePageRightBanner = bannerRedisTemplate.opsForSet().members("homePageRightBanner"); model.addAttribute("homePageRightBanner", homePageRightBanner); List<Object> homePageLeftBanner = (List<Object>) bannerRedisTemplate.opsForList().range("homePageLeftBanner", 0,-1); model.addAttribute("homePageLeftBanner", homePageLeftBanner); return "<pre>" + JSON.toJSONString(model, SerializerFeature.PrettyFormat,SerializerFeature.WriteMapNullValue) + "</pre>"; }}@Builder@Dataclass Money { private Long id; private String currency; private Integer value;}
访问 Controller中的 store
方法,不同业务的RedisTemplate操作不同Redis库。访问 Controller view 方法,查看不同Redis库数据。
好了,各位朋友们,本期的内容到此就全部结束啦,能看到这里的同学都是优秀的同学,下一个升职加薪的就是你了!
如果觉得这篇文章对你有所帮助的话请扫描下面二维码加个关注。" 转发 " 加 " 在看 ",养成好习惯!咱们下期再见!
热文推荐
☞ 数据库优化之SQL优化
☞ 数据库优化之实例优化
☞ Docker基础与实战,看这一篇就够了!
☞ Docker-Compose基础与实战,看这一篇就够了!
☞ OAuth2.0最简向导(多图预警)
☞ 构建三维一体立体化监控体系
JAVA日知录
长按左边二维码关注我们,精彩文章第一时间推送
戳我留言
朕已阅
本文分享自微信公众号 - JAVA日知录(javadaily)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。