Ver Fonte

优化redis缓存,流程定义缓存到redis

caixiaofeng há 6 meses atrás
pai
commit
a5be227340

+ 1 - 0
flow-common/flow-common-flowable-starter/src/main/java/com/flow/flowable/configure/FlowableConfigure.java

@@ -69,6 +69,7 @@ public class FlowableConfigure implements EngineConfigurationConfigurer<SpringPr
         }
         if (Objects.nonNull(this.deploymentCache)) {
             engineConfiguration.setProcessDefinitionCache(deploymentCache);
+            engineConfiguration.setProcessDefinitionCacheLimit(1000);
         }
     }
 }

+ 53 - 0
flow-common/flow-common-flowable-starter/src/main/java/com/flow/flowable/loader/FlowableLoaderClass.java

@@ -0,0 +1,53 @@
+package com.flow.flowable.loader;
+
+import org.flowable.common.engine.api.FlowableException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
+import org.springframework.core.Ordered;
+import org.springframework.core.PriorityOrdered;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+@Component
+public class FlowableLoaderClass implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
+    private static final Logger log = LoggerFactory.getLogger(FlowableLoaderClass.class);
+
+    @Override
+    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
+        List<String> serializableFlowableClassList = new ArrayList<>();
+        serializableFlowableClassList.add("org.flowable.bpmn.model.BpmnModel");
+        serializableFlowableClassList.add("org.flowable.bpmn.model.BaseElement");
+        serializableFlowableClassList.add("org.flowable.bpmn.model.GraphicInfo");
+        serializableFlowableClassList.add("org.flowable.common.engine.impl.event.FlowableEventSupport");
+        serializableFlowableClassList.add("org.flowable.bpmn.model.BpmnDiEdge");
+        serializableFlowableClassList.add("org.flowable.bpmn.model.ExtensionAttribute");
+        serializableFlowableClassList.add("org.flowable.common.engine.impl.persistence.entity.AbstractEntity");
+        serializableFlowableClassList.add("org.flowable.engine.impl.delegate.invocation.DefaultDelegateInterceptor");
+        serializableFlowableClassList.add("org.flowable.common.engine.api.delegate.FlowableFunctionDelegate");
+        serializableFlowableClassList.add("org.flowable.common.engine.impl.el.FlowableAstFunctionCreator");
+        FlowableSerializable flowableSerializable = new FlowableSerializable(serializableFlowableClassList);
+        try {
+            flowableSerializable.execute();
+        } catch (Exception e) {
+            log.error("Failed to make Flowable classes serializable", e);
+            throw new FlowableException("Failed to make Flowable classes serializable", e);
+        }
+    }
+
+    @Override
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
+
+    }
+
+    @Override
+    public int getOrder() {
+        return Ordered.LOWEST_PRECEDENCE;
+    }
+}

+ 52 - 0
flow-common/flow-common-flowable-starter/src/main/java/com/flow/flowable/loader/FlowableSerializable.java

@@ -0,0 +1,52 @@
+package com.flow.flowable.loader;
+
+import org.apache.ibatis.javassist.*;
+
+import java.util.List;
+
+public class FlowableSerializable {
+    List<String> serializableFlowableClassList;
+
+    public FlowableSerializable() {
+    }
+
+    public FlowableSerializable(List<String> serializableFlowableClassList) {
+        this.serializableFlowableClassList = serializableFlowableClassList;
+    }
+
+    public List<String> getSerializableFlowableClassList() {
+        return serializableFlowableClassList;
+    }
+
+    public void setSerializableFlowableClassList(List<String> serializableFlowableClassList) {
+        this.serializableFlowableClassList = serializableFlowableClassList;
+    }
+
+    public void execute() throws Exception {
+        ClassPool classPool = ClassPool.getDefault();
+        classPool.insertClassPath(new LoaderClassPath(FlowableSerializable.class.getClassLoader()));
+        for (String serializableFlowableClass : serializableFlowableClassList) {
+            CtClass ctClass = classPool.get(serializableFlowableClass);
+            if (ctClass.isFrozen()) {
+                ctClass.defrost();
+            }
+            ctClass.addInterface(classPool.get("java.io.Serializable"));
+            if (!ctClass.isInterface()) {
+                CtField field = CtField.make("private static final long serialVersionUID = 1L;", ctClass);
+                ctClass.addField(field);
+            }
+            ctClass.toClass();
+
+        }
+        classPool.importPackage("org.flowable.engine.impl.util.CommandContextUtil");
+        CtClass ctClass = classPool.get("org.flowable.common.engine.impl.el.JuelExpression");
+        ctClass.getField("expressionManager").setModifiers(Modifier.TRANSIENT);
+        CtMethod[] methods = ctClass.getMethods();
+        for (CtMethod method : methods) {
+            if (method.getName().equals("getValue") || method.getName().equals("setValue")) {
+                method.insertBefore("expressionManager = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager();");
+            }
+        }
+        ctClass.toClass();
+    }
+}

+ 20 - 2
flow-common/flow-common-redis-starter/src/main/java/com/flow/common/redis/configure/LettuceRedisConfigure.java

@@ -9,6 +9,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
 import org.springframework.data.redis.core.RedisOperations;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
 import org.springframework.data.redis.serializer.StringRedisSerializer;
 
 @Configuration
@@ -29,15 +30,32 @@ public class LettuceRedisConfigure {
         redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
         // HashValue采用jackson的json序列化方式
         redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
+        // 关闭事务
+        redisTemplate.setEnableTransactionSupport(false);
         //属性设置后
         redisTemplate.afterPropertiesSet();
         return redisTemplate;
     }
 
+    @Bean(name = "jdkRedisTemplate")
+    @ConditionalOnClass(RedisOperations.class)
+    public <T> RedisTemplate<String, T> jdkRedisTemplate(RedisConnectionFactory factory) {
+        RedisTemplate<String, T> redisTemplate = new RedisTemplate<>();
+        redisTemplate.setConnectionFactory(factory);
+        redisTemplate.setKeySerializer(new StringRedisSerializer());
+        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
+        JdkSerializationRedisSerializer jdkSerializationRedisSerializer = new JdkSerializationRedisSerializer();
+        redisTemplate.setValueSerializer(jdkSerializationRedisSerializer);
+        redisTemplate.setHashValueSerializer(jdkSerializationRedisSerializer);
+        redisTemplate.setEnableTransactionSupport(false);
+        redisTemplate.afterPropertiesSet();
+        return redisTemplate;
+    }
+
     @Bean
     @ConditionalOnBean(name = "redisTemplate")
-    public RedisService redisService() {
-        return new RedisService();
+    public RedisService<?> redisService() {
+        return new RedisService<>();
     }
 
 }

+ 27 - 28
flow-common/flow-common-redis-starter/src/main/java/com/flow/common/redis/service/RedisService.java

@@ -11,12 +11,11 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-@SuppressWarnings("all")
-public class RedisService {
-    private Logger log = LoggerFactory.getLogger(this.getClass());
+public class RedisService<T> {
+    private final Logger log = LoggerFactory.getLogger(this.getClass());
 
     @Autowired
-    private RedisTemplate<String, Object> redisTemplate;
+    private RedisTemplate<String, T> redisTemplate;
 
     /**
      * 发布消息
@@ -24,7 +23,7 @@ public class RedisService {
      * @param queueName
      * @param message
      */
-    public void sendMessage(String queueName, Object message) {
+    public void sendMessage(String queueName, T message) {
         redisTemplate.opsForList().leftPush(queueName, message);
     }
 
@@ -34,7 +33,7 @@ public class RedisService {
      * @param queueName
      * @return
      */
-    public Object receiveMessage(String queueName) {
+    public T receiveMessage(String queueName) {
         return redisTemplate.opsForList().rightPop(queueName);
     }
 
@@ -104,7 +103,7 @@ public class RedisService {
      * @param key 键
      * @return 值
      */
-    public Object get(String key) {
+    public T get(String key) {
         return key == null ? null : redisTemplate.opsForValue().get(key);
     }
 
@@ -115,9 +114,9 @@ public class RedisService {
      * @param value 值
      * @return true成功 false失败
      */
-    public Boolean set(String key, Object value) {
+    public Boolean set(String key, T value) {
         try {
-            redisTemplate.opsForValue().set(key, value);
+            redisTemplate.opsForValue().set(key, value, null);
             return true;
         } catch (Exception e) {
             log.error(e.getMessage(), e);
@@ -133,7 +132,7 @@ public class RedisService {
      * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
      * @return true成功 false 失败
      */
-    public Boolean set(String key, Object value, Long time) {
+    public Boolean set(String key, T value, Long time) {
         try {
             if (time > 0) {
                 redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
@@ -212,7 +211,7 @@ public class RedisService {
      * @param map 对应多个键值
      * @return true 成功 false 失败
      */
-    public Boolean hmset(String key, Map<String, Object> map) {
+    public Boolean hmset(String key, Map<String, T> map) {
         try {
             redisTemplate.opsForHash().putAll(key, map);
             return true;
@@ -230,7 +229,7 @@ public class RedisService {
      * @param time 时间(秒)
      * @return true成功 false失败
      */
-    public Boolean hmset(String key, Map<String, Object> map, Long time) {
+    public Boolean hmset(String key, Map<String, T> map, Long time) {
         try {
             redisTemplate.opsForHash().putAll(key, map);
             if (time > 0) {
@@ -252,7 +251,7 @@ public class RedisService {
      * @param value 值
      * @return true 成功 false失败
      */
-    public Boolean hset(String key, String item, Object value) {
+    public Boolean hset(String key, String item, T value) {
         try {
             redisTemplate.opsForHash().put(key, item, value);
             return true;
@@ -271,7 +270,7 @@ public class RedisService {
      * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
      * @return true 成功 false失败
      */
-    public Boolean hset(String key, String item, Object value, Long time) {
+    public Boolean hset(String key, String item, T value, Long time) {
         try {
             redisTemplate.opsForHash().put(key, item, value);
             if (time > 0) {
@@ -290,7 +289,7 @@ public class RedisService {
      * @param key  键 不能为 null
      * @param item 项 可以使多个不能为 null
      */
-    public void hdel(String key, Object... item) {
+    public void hdel(String key, T... item) {
         redisTemplate.opsForHash().delete(key, item);
     }
 
@@ -336,7 +335,7 @@ public class RedisService {
      * @param key 键
      * @return Set
      */
-    public Set<Object> sGet(String key) {
+    public Set<T> sGet(String key) {
         try {
             return redisTemplate.opsForSet().members(key);
         } catch (Exception e) {
@@ -352,7 +351,7 @@ public class RedisService {
      * @param value 值
      * @return true 存在 false不存在
      */
-    public Boolean sHasKey(String key, Object value) {
+    public Boolean sHasKey(String key, T value) {
         try {
             return redisTemplate.opsForSet().isMember(key, value);
         } catch (Exception e) {
@@ -368,7 +367,7 @@ public class RedisService {
      * @param values 值 可以是多个
      * @return 成功个数
      */
-    public Long sSet(String key, Object... values) {
+    public Long sSet(String key, T... values) {
         try {
             return redisTemplate.opsForSet().add(key, values);
         } catch (Exception e) {
@@ -386,7 +385,7 @@ public class RedisService {
      * @param values 值 可以是多个
      * @return 成功个数
      */
-    public Long sSetAndTime(String key, Long time, Object... values) {
+    public Long sSetAndTime(String key, Long time, T... values) {
         try {
             Long count = redisTemplate.opsForSet().add(key, values);
             if (time > 0) {
@@ -421,7 +420,7 @@ public class RedisService {
      * @param values 值 可以是多个
      * @return 移除的个数
      */
-    public Long setRemove(String key, Object... values) {
+    public Long setRemove(String key, T... values) {
         try {
             return redisTemplate.opsForSet().remove(key, values);
         } catch (Exception e) {
@@ -438,7 +437,7 @@ public class RedisService {
      * @param end   结束 0 到 -1代表所有值
      * @return List
      */
-    public List<Object> lGet(String key, Long start, Long end) {
+    public List<T> lGet(String key, Long start, Long end) {
         try {
             return redisTemplate.opsForList().range(key, start, end);
         } catch (Exception e) {
@@ -470,7 +469,7 @@ public class RedisService {
      *              index<0时,-1,表尾,-2倒数第二个元素,依次类推
      * @return Object
      */
-    public Object lGetIndex(String key, Long index) {
+    public T lGetIndex(String key, Long index) {
         try {
             return redisTemplate.opsForList().index(key, index);
         } catch (Exception e) {
@@ -486,7 +485,7 @@ public class RedisService {
      * @param value 值
      * @return Boolean
      */
-    public Boolean lSet(String key, Object value) {
+    public Boolean lSet(String key, T value) {
         try {
             redisTemplate.opsForList().rightPush(key, value);
             return true;
@@ -504,7 +503,7 @@ public class RedisService {
      * @param time  时间(秒)
      * @return Boolean
      */
-    public Boolean lSet(String key, Object value, Long time) {
+    public Boolean lSet(String key, T value, Long time) {
         try {
             redisTemplate.opsForList().rightPush(key, value);
             if (time > 0) {
@@ -524,7 +523,7 @@ public class RedisService {
      * @param value 值
      * @return Boolean
      */
-    public Boolean lSet(String key, List<Object> value) {
+    public Boolean lSet(String key, List<T> value) {
         try {
             redisTemplate.opsForList().rightPushAll(key, value);
             return true;
@@ -542,7 +541,7 @@ public class RedisService {
      * @param time  时间(秒)
      * @return Boolean
      */
-    public Boolean lSet(String key, List<Object> value, Long time) {
+    public Boolean lSet(String key, List<T> value, Long time) {
         try {
             redisTemplate.opsForList().rightPushAll(key, value);
             if (time > 0) {
@@ -563,7 +562,7 @@ public class RedisService {
      * @param value 值
      * @return Boolean
      */
-    public Boolean lUpdateIndex(String key, Long index, Object value) {
+    public Boolean lUpdateIndex(String key, Long index, T value) {
         try {
             redisTemplate.opsForList().set(key, index, value);
             return true;
@@ -581,7 +580,7 @@ public class RedisService {
      * @param value 值
      * @return 移除的个数
      */
-    public Long lRemove(String key, Long count, Object value) {
+    public Long lRemove(String key, Long count, T value) {
         try {
             return redisTemplate.opsForList().remove(key, count, value);
         } catch (Exception e) {

+ 30 - 14
flow-workflow/flow-workflow-biz/src/main/java/com/flow/config/CustomDeploymentCache.java

@@ -2,48 +2,64 @@ package com.flow.config;
 
 import org.flowable.common.engine.impl.persistence.deploy.DeploymentCache;
 import org.flowable.engine.impl.persistence.deploy.ProcessDefinitionCacheEntry;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
 import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.Collections;
+import java.util.Set;
 
 @Component
 public class CustomDeploymentCache implements DeploymentCache<ProcessDefinitionCacheEntry> {
-    protected Map<String, ProcessDefinitionCacheEntry> cache = new ConcurrentHashMap<>();
+    @Autowired
+    private RedisTemplate<String, ProcessDefinitionCacheEntry> jdkRedisTemplate;
+    private final String CachePrefix = "flow:";
 
     @Override
-    public ProcessDefinitionCacheEntry get(String s) {
-        return cache.get(s);
+    public ProcessDefinitionCacheEntry get(String id) {
+        return jdkRedisTemplate.opsForValue().get(this.CachePrefix + id);
     }
 
     @Override
-    public boolean contains(String s) {
-        return cache.containsKey(s);
+    public boolean contains(String id) {
+        Boolean has = jdkRedisTemplate.hasKey(this.CachePrefix + id);
+        return has != null && has;
     }
 
     @Override
-    public void add(String s, ProcessDefinitionCacheEntry processDefinitionCacheEntry) {
-        cache.put(s, processDefinitionCacheEntry);
+    public void add(String id, ProcessDefinitionCacheEntry processDefinitionCacheEntry) {
+        jdkRedisTemplate.opsForValue().set(this.CachePrefix + id, processDefinitionCacheEntry);
     }
 
     @Override
-    public void remove(String s) {
-        cache.remove(s);
+    public void remove(String id) {
+        jdkRedisTemplate.delete(this.CachePrefix + id);
     }
 
     @Override
     public void clear() {
-        cache.clear();
+        Set<String> keys = jdkRedisTemplate.keys(this.CachePrefix + "*");
+        if (keys != null) {
+            jdkRedisTemplate.delete(keys);
+        }
     }
 
     @Override
     public Collection<ProcessDefinitionCacheEntry> getAll() {
-        return cache.values();
+        Set<String> keys = jdkRedisTemplate.keys(this.CachePrefix + "*");
+        if (keys != null) {
+            return jdkRedisTemplate.opsForValue().multiGet(keys);
+        }
+        return Collections.emptyList();
     }
 
     @Override
     public int size() {
-        return cache.size();
+        Set<String> keys = jdkRedisTemplate.keys(this.CachePrefix + "*");
+        if (keys != null) {
+            return keys.size();
+        }
+        return 0;
     }
 }

+ 1 - 1
flow-workflow/flow-workflow-biz/src/main/java/com/flow/listener/GlobalActivityEventListener.java

@@ -57,7 +57,7 @@ public class GlobalActivityEventListener extends AbstractFlowableEngineEventList
     @Autowired
     private FlowInstanceService flowInstanceService;
     @Autowired
-    private RedisService redisService;
+    private RedisService<String> redisService;
 
     // 任务创建监听器
     @Override

+ 1 - 1
flow-workflow/flow-workflow-biz/src/main/java/com/flow/service/impl/FlowTaskServiceImpl.java

@@ -64,7 +64,7 @@ public class FlowTaskServiceImpl extends BaseServiceImpl<FlowTaskDao, FlowTask>
     @Autowired
     private RepositoryService repositoryService;
     @Autowired
-    private RedisService redisService;
+    private RedisService<String> redisService;
 
     @Override
     public PageResult<FlowTask> todo(FlowTaskQuery flowTaskQuery) {