Browse Source

redisson用spring的配置,方便redisson升级

FrozenWatermelon 2 years ago
parent
commit
a906a9c369

+ 0 - 7
pom.xml

@@ -36,7 +36,6 @@
         <aliyun-dysmsapi.version>1.1.0</aliyun-dysmsapi.version>
         <mybatis-plus.version>3.1.0</mybatis-plus.version>
         <redisson.version>3.12.5</redisson.version>
-        <kryo.version>4.0.2</kryo.version>
         <transmittable-thread-local.version>2.12.1</transmittable-thread-local.version>
         <log4j.version>2.17.2</log4j.version>
         <knife4j.version>3.0.3</knife4j.version>
@@ -119,12 +118,6 @@
                 <artifactId>redisson-spring-boot-starter</artifactId>
                 <version>${redisson.version}</version>
             </dependency>
-            <!-- 用于序列化和反序列化-->
-            <dependency>
-                <groupId>com.esotericsoftware</groupId>
-                <artifactId>kryo</artifactId>
-                <version>${kryo.version}</version>
-            </dependency>
             <dependency>
                 <groupId>org.apache.logging.log4j</groupId>
                 <artifactId>log4j-to-slf4j</artifactId>

+ 4 - 3
yami-shop-admin/src/main/resources/application-dev.yml

@@ -18,12 +18,13 @@ spring:
     redis:
       cache-null-values: true
   redis:
-    redisson:
-      config: classpath:redisson/redisson.yml
+    host: 127.0.0.1
+    port: 6379
+    database: 0
 logging:
   config: classpath:logback/logback-dev.xml
 xxl-job:
   accessToken: default_token
   logPath: /data/applogs/xxl-job/jobhandler
   admin:
-    addresses: http://localhost:8080/xxl-job-admin
+    addresses: http://localhost:8080/xxl-job-admin

+ 6 - 5
yami-shop-admin/src/main/resources/application-docker.yml

@@ -14,12 +14,13 @@ spring:
       auto-commit: true
       connection-test-query: SELECT 1
   redis:
-    redisson:
-      config: classpath:redisson/redisson-docker.yml
+    host: ${REDIS_HOST}
+    port: ${REDIS_PORT}
+    database: ${REDIS_DATABASE:0}
 logging:
   config: classpath:logback/logback-prod.xml
 xxl-job:
-  accessToken: default_token
-  logPath: /data/applogs/xxl-job/jobhandler
+  accessToken: ${XXL_JOB_ACCESS_TOKEN:default_token}
+  logPath: ${XXL_JOB_LOG_PATH:/data/applogs/xxl-job/jobhandler}
   admin:
-    addresses: http://localhost:8080/xxl-job-admin
+    addresses: ${XXL_JOB_ADDRESS:http://mall4j-job:8080/xxl-job-admin}

+ 3 - 2
yami-shop-admin/src/main/resources/application-prod.yml

@@ -14,8 +14,9 @@ spring:
       auto-commit: true
       connection-test-query: SELECT 1
   redis:
-    redisson:
-      config: classpath:redisson/redisson.yml
+    host: 127.0.0.1
+    port: 6379
+    database: ${REDIS_DATABASE:0}
 logging:
   config: classpath:logback/logback-prod.xml
 xxl-job:

+ 0 - 28
yami-shop-admin/src/main/resources/redisson/redisson-docker.yml

@@ -1,28 +0,0 @@
-# 单节点设置
-singleServerConfig:
-  address: redis://${REDIS_HOST}:${REDIS_PORT}
-  database: ${REDIS_DATABASE}
-  password: ${REDIS_PASSWORD}
-  idleConnectionTimeout: 10000
-  connectTimeout: 10000
-  timeout: 3000
-  retryAttempts: 3
-  retryInterval: 1500
-  clientName: null
-  # 发布和订阅连接的最小空闲连接数 默认1
-  subscriptionConnectionMinimumIdleSize: 1
-  # 发布和订阅连接池大小 默认50
-  subscriptionConnectionPoolSize: 1
-  # 单个连接最大订阅数量 默认5
-  subscriptionsPerConnection: 1
-  # 最小空闲连接数 默认32,现在暂时不需要那么多的线程
-  connectionMinimumIdleSize: 2
-  # connectionPoolSize 默认64,现在暂时不需要那么多的线程
-  connectionPoolSize: 4
-# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。
-threads: 0
-# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
-nettyThreads: 0
-codec:
-  class: org.redisson.codec.KryoCodec
-transportMode: NIO

+ 0 - 28
yami-shop-admin/src/main/resources/redisson/redisson.yml

@@ -1,28 +0,0 @@
-# 单节点设置
-singleServerConfig:
-  address: redis://127.0.0.1:6379
-  database: 0
-  password: null
-  idleConnectionTimeout: 10000
-  connectTimeout: 10000
-  timeout: 3000
-  retryAttempts: 3
-  retryInterval: 1500
-  clientName: null
-  # 发布和订阅连接的最小空闲连接数 默认1
-  subscriptionConnectionMinimumIdleSize: 1
-  # 发布和订阅连接池大小 默认50
-  subscriptionConnectionPoolSize: 1
-  # 单个连接最大订阅数量 默认5
-  subscriptionsPerConnection: 1
-  # 最小空闲连接数 默认32,现在暂时不需要那么多的线程
-  connectionMinimumIdleSize: 2
-  # connectionPoolSize 默认64,现在暂时不需要那么多的线程
-  connectionPoolSize: 4
-# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。
-threads: 0
-# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
-nettyThreads: 0
-codec:
-  class: org.redisson.codec.KryoCodec
-transportMode: NIO

+ 3 - 2
yami-shop-api/src/main/resources/application-dev.yml

@@ -13,8 +13,9 @@ spring:
       idle-timeout: 10000
       connection-test-query: select 1
   redis:
-    redisson:
-      config: classpath:redisson/redisson.yml
+    host: 127.0.0.1
+    port: 6379
+    database: 0
 logging:
   config: classpath:logback/logback-dev.xml
 

+ 3 - 2
yami-shop-api/src/main/resources/application-docker.yml

@@ -13,7 +13,8 @@ spring:
       maximum-pool-size: 20
       connection-test-query: select 1
   redis:
-    redisson:
-      config: classpath:redisson/redisson-docker.yml
+    host: ${REDIS_HOST}
+    port: ${REDIS_PORT}
+    database: ${REDIS_DATABASE:0}
 logging:
   config: classpath:logback/logback-prod.xml

+ 3 - 4
yami-shop-api/src/main/resources/application-prod.yml

@@ -1,7 +1,5 @@
 server:
   port: 8112
-  undertow:
-    worker-threads: 200
 
 spring:
   datasource:
@@ -15,7 +13,8 @@ spring:
       maximum-pool-size: 20
       connection-test-query: select 1
   redis:
-    redisson:
-      config: classpath:redisson/redisson.yml
+    host: 127.0.0.1
+    port: 6379
+    database: ${REDIS_DATABASE:0}
 logging:
   config: classpath:logback/logback-prod.xml

+ 0 - 28
yami-shop-api/src/main/resources/redisson/redisson-docker.yml

@@ -1,28 +0,0 @@
-# 单节点设置
-singleServerConfig:
-  address: redis://${REDIS_HOST}:${REDIS_PORT}
-  database: ${REDIS_DATABASE}
-  password: ${REDIS_PASSWORD}
-  idleConnectionTimeout: 10000
-  connectTimeout: 10000
-  timeout: 3000
-  retryAttempts: 3
-  retryInterval: 1500
-  clientName: null
-  # 发布和订阅连接的最小空闲连接数 默认1
-  subscriptionConnectionMinimumIdleSize: 1
-  # 发布和订阅连接池大小 默认50
-  subscriptionConnectionPoolSize: 1
-  # 单个连接最大订阅数量 默认5
-  subscriptionsPerConnection: 1
-  # 最小空闲连接数 默认32,现在暂时不需要那么多的线程
-  connectionMinimumIdleSize: 4
-  # connectionPoolSize 默认64,现在暂时不需要那么多的线程
-  connectionPoolSize: 4
-# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。
-threads: 0
-# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
-nettyThreads: 0
-codec:
-  class: org.redisson.codec.KryoCodec
-transportMode: NIO

+ 0 - 28
yami-shop-api/src/main/resources/redisson/redisson.yml

@@ -1,28 +0,0 @@
-# 单节点设置
-singleServerConfig:
-  address: redis://127.0.0.1:6379
-  database: 0
-  password: null
-  idleConnectionTimeout: 10000
-  connectTimeout: 10000
-  timeout: 3000
-  retryAttempts: 3
-  retryInterval: 1500
-  clientName: null
-  # 发布和订阅连接的最小空闲连接数 默认1
-  subscriptionConnectionMinimumIdleSize: 1
-  # 发布和订阅连接池大小 默认50
-  subscriptionConnectionPoolSize: 1
-  # 单个连接最大订阅数量 默认5
-  subscriptionsPerConnection: 1
-  # 最小空闲连接数 默认32,现在暂时不需要那么多的线程
-  connectionMinimumIdleSize: 2
-  # connectionPoolSize 默认64,现在暂时不需要那么多的线程
-  connectionPoolSize: 4
-# 这个线程池数量被所有RTopic对象监听器,RRemoteService调用者和RExecutorService任务共同共享。
-threads: 0
-# 这个线程池数量是在一个Redisson实例内,被其创建的所有分布式数据类型和服务,以及底层客户端所一同共享的线程池里保存的线程数量。
-nettyThreads: 0
-codec:
-  class: org.redisson.codec.KryoCodec
-transportMode: NIO

+ 0 - 4
yami-shop-common/pom.xml

@@ -73,10 +73,6 @@
             <groupId>com.vdurmont</groupId>
             <artifactId>emoji-java</artifactId>
         </dependency>
-        <dependency>
-            <groupId>com.esotericsoftware</groupId>
-            <artifactId>kryo</artifactId>
-        </dependency>
         <dependency>
             <groupId>com.github.binarywang</groupId>
             <artifactId>weixin-java-pay</artifactId>

+ 52 - 17
yami-shop-common/src/main/java/com/yami/shop/common/config/RedisCacheConfig.java

@@ -10,7 +10,14 @@
 
 package com.yami.shop.common.config;
 
-import com.yami.shop.common.serializer.redis.KryoRedisSerializer;
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.MapperFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.json.JsonMapper;
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
 import org.springframework.cache.CacheManager;
 import org.springframework.cache.annotation.EnableCaching;
 import org.springframework.context.annotation.Bean;
@@ -21,7 +28,9 @@ import org.springframework.data.redis.cache.RedisCacheWriter;
 import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
 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;
@@ -37,53 +46,79 @@ import java.util.Map;
 public class RedisCacheConfig  {
 
     @Bean
-    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
+    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, RedisSerializer<Object> redisSerializer) {
 
-    	RedisCacheManager redisCacheManager = new RedisCacheManager(
+        RedisCacheManager redisCacheManager = new RedisCacheManager(
                 RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                 // 默认策略,未配置的 key 会使用这个
-                this.getRedisCacheConfigurationWithTtl(3600),
+                this.getRedisCacheConfigurationWithTtl(3600,redisSerializer),
                 // 指定 key 策略
-                this.getRedisCacheConfigurationMap()
-            );
-    	redisCacheManager.setTransactionAware(true);
+                this.getRedisCacheConfigurationMap(redisSerializer)
+        );
+        redisCacheManager.setTransactionAware(true);
         return redisCacheManager;
     }
 
-    private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
+    private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap(RedisSerializer<Object>  redisSerializer) {
         Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(16);
-//        redisCacheConfigurationMap.put("UserInfoList", this.getRedisCacheConfigurationWithTtl(3000));
-//        redisCacheConfigurationMap.put("UserInfoListAnother", this.getRedisCacheConfigurationWithTtl(18000));
-
+        redisCacheConfigurationMap.put("product", this.getRedisCacheConfigurationWithTtl(1800, redisSerializer));
         return redisCacheConfigurationMap;
     }
 
-    private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
+    private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds,RedisSerializer<Object> redisSerializer) {
+
+
         RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
         redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
                 RedisSerializationContext
                         .SerializationPair
-                        .fromSerializer(new KryoRedisSerializer<>())
+                        .fromSerializer(redisSerializer)
         ).entryTtl(Duration.ofSeconds(seconds));
 
         return redisCacheConfiguration;
     }
 
     @Bean
-    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
-        KryoRedisSerializer kryoRedisSerializer = new KryoRedisSerializer();
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory,RedisSerializer<Object> redisSerializer) {
+
         RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
         redisTemplate.setConnectionFactory(redisConnectionFactory);
         redisTemplate.setKeySerializer(new StringRedisSerializer());
         redisTemplate.setHashKeySerializer(new StringRedisSerializer());
-        redisTemplate.setValueSerializer(kryoRedisSerializer);
-        redisTemplate.setHashValueSerializer(kryoRedisSerializer);
+        redisTemplate.setValueSerializer(redisSerializer);
+        redisTemplate.setHashValueSerializer(redisSerializer);
         redisTemplate.setEnableTransactionSupport(false);
 
         redisTemplate.afterPropertiesSet();
         return redisTemplate;
     }
 
+    /**
+     * 自定义redis序列化的机制,重新定义一个ObjectMapper.防止和MVC的冲突
+     * https://juejin.im/post/5e869d426fb9a03c6148c97e
+     */
+    @Bean
+    public RedisSerializer<Object> redisSerializer() {
+        ObjectMapper objectMapper = JsonMapper.builder().disable(MapperFeature.USE_ANNOTATIONS).build();
+        // 反序列化时候遇到不匹配的属性并不抛出异常
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        // 序列化时候遇到空对象不抛出异常
+        objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+        // 反序列化的时候如果是无效子类型,不抛出异常
+        objectMapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
+        // 不使用默认的dateTime进行序列化,
+        objectMapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS, false);
+        // 使用JSR310提供的序列化类,里面包含了大量的JDK8时间序列化类
+        objectMapper.registerModule(new JavaTimeModule());
+        // 启用反序列化所需的类型信息,在属性中添加@class
+        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL,
+                JsonTypeInfo.As.PROPERTY);
+        // 配置null值的序列化器
+        GenericJackson2JsonRedisSerializer.registerNullValueSerializer(objectMapper, null);
+        return new GenericJackson2JsonRedisSerializer(objectMapper);
+    }
+
+
     @Bean
     public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory){
         StringRedisTemplate redisTemplate = new StringRedisTemplate(redisConnectionFactory);

+ 0 - 74
yami-shop-common/src/main/java/com/yami/shop/common/serializer/redis/KryoRedisSerializer.java

@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
- *
- * https://www.mall4j.com/
- *
- * 未经允许,不可做商业用途!
- *
- * 版权所有,侵权必究!
- */
-package com.yami.shop.common.serializer.redis;
-
-import com.esotericsoftware.kryo.Kryo;
-import com.esotericsoftware.kryo.io.Input;
-import com.esotericsoftware.kryo.io.Output;
-import lombok.extern.slf4j.Slf4j;
-import org.redisson.codec.KryoCodec;
-import org.springframework.data.redis.serializer.RedisSerializer;
-import org.springframework.data.redis.serializer.SerializationException;
-
-import java.io.ByteArrayOutputStream;
-import java.util.Collections;
-
-/**
- * 使用Kryo 进行reids的序列化
- * @author LGH
- */
-@Slf4j
-public class KryoRedisSerializer<T> implements RedisSerializer<T> {
-
-    private final KryoCodec kryoPool;
-
-    public KryoRedisSerializer() {
-        kryoPool = new KryoCodec(Collections.emptyList(), null);
-    }
-
-    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-
-
-    @Override
-    public byte[] serialize(T t) throws SerializationException {
-        if (t == null) {
-            return EMPTY_BYTE_ARRAY;
-        }
-
-        Kryo kryo = kryoPool.get();
-
-        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
-             Output output = new Output(baos)) {
-            kryo.writeClassAndObject(output, t);
-            output.flush();
-            return baos.toByteArray();
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-        }
-
-        return EMPTY_BYTE_ARRAY;
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public T deserialize(byte[] bytes) throws SerializationException {
-        if (bytes == null || bytes.length <= 0) {
-            return null;
-        }
-        Kryo kryo = kryoPool.get();
-
-        try (Input input = new Input(bytes)) {
-            return (T) kryo.readClassAndObject(input);
-        } catch (Exception e) {
-            log.error(e.getMessage(), e);
-        }
-        return null;
-    }
-}

+ 4 - 3
yami-shop-security/yami-shop-security-common/src/main/java/com/yami/shop/security/common/manager/TokenStore.java

@@ -18,7 +18,6 @@ import cn.hutool.crypto.symmetric.AES;
 import com.yami.shop.common.constants.OauthCacheNames;
 import com.yami.shop.common.enums.YamiHttpStatus;
 import com.yami.shop.common.exception.YamiShopBindException;
-import com.yami.shop.common.serializer.redis.KryoRedisSerializer;
 import com.yami.shop.common.util.PrincipalUtil;
 import com.yami.shop.security.common.bo.TokenInfoBO;
 import com.yami.shop.security.common.bo.UserInfoInTokenBO;
@@ -30,6 +29,7 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.data.redis.core.RedisCallback;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
 import org.springframework.data.redis.serializer.RedisSerializer;
 import org.springframework.stereotype.Component;
 
@@ -62,12 +62,13 @@ public class TokenStore {
     private final StringRedisTemplate stringRedisTemplate;
 
     public TokenStore(RedisTemplate<String, Object> redisTemplate,
-                      StringRedisTemplate stringRedisTemplate) {
+                      StringRedisTemplate stringRedisTemplate, GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer) {
         this.redisTemplate = redisTemplate;
-        this.redisSerializer = new KryoRedisSerializer<>();
+        this.redisSerializer = genericJackson2JsonRedisSerializer;
         this.stringRedisTemplate = stringRedisTemplate;
     }
 
+
     /**
      * 将用户的部分信息存储在token中,并返回token信息
      * @param userInfoInToken 用户在token中的信息