【项目调优】项目从EhCache缓存变为redis之后,加载菜单变得极其缓慢

问题重现

1、原本用的缓存机制EhCache

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。

2、换成redis之后有问题

项目没有加上redis之前,加载菜单没有任何问题,但是加上redis进行缓存之后,加载菜单变得极其缓慢

问题所在

1、前端的页面为JSP页面

jsp页面有什么特点呢,他不是一个静态的界面。
在这里插入图片描述
这种类似的对象模式的获取后台值,其实都是相当于实时的拼接这个jsp界面,所以这个界面虽然看起来好像是在加载,但是其实,一直都是在走后台

2、JSP页面里面的【对象.属性】,也有可能是【对象.方法】

for循环所有的菜单,然后在每一个菜单上调用page.visiblePortletEntities,判断这个菜单是否是可以展示的
在这里插入图片描述

page.visiblePortletEntities方法在哪里呢

在这里插入图片描述

在哪里请求的EhCache/redis(请求了400多次啊!)

有人就会问了,为什么从EhCache(java内存)里面拿的时候快啊,因为是内部的啊!!!!是redis的几千倍几万倍!!!!!
这就是为什么换了redis方式之后变卡了!!!!【其实redis已经很快了,毫秒级别,但是架不住次数多啊,400多个菜单就要循环400多次,一加起来就可能是40s甚至更多】
在这里插入图片描述

问题怎么解决

既然问题已经找到了,那就解决掉这个方法就好了!!!
1、不每一次去调用方法去判别
2、在对象page,里面设置一个属性userOrNot,判断当前这个菜单是否展示
3、在加载页面之前,先给每个page的userOrNot属性塞值true【展示】,false【不展示】

代码实现

逻辑:一级菜单,二级菜单,三级菜单
只要三级菜单有权限,那么二级和一级菜单都需要展示
所以递归:setUserOrNot 方法的结果为true,就说明上级也需要 pg.setUserOrNot(true) 从而实现所有有权限的菜单进行展示

public boolean setUserOrNot(List<Page> pages,List<String> a ){
		boolean trueOrFalse = false;
		for(Page pg :pages){
			Collection<String> portletEntities = pg.getPortletEntities();
			Iterator<String> iterable = portletEntities.iterator();
			while(iterable.hasNext()) {
				String entitieString = iterable.next();
				String[] entitys = entitieString.split("\\.");
				if(entitys!=null&&entitys.length>1){
					String entityCode = entitys[1];
					String entityCodes[] = entityCode.split("!");
					if(entityCodes!=null){
						if(a.contains(entityCodes[0])){
							pg.setUserOrNot(true);
							trueOrFalse = true;
					        break;
						}
					}
				}
			}
			List<Page> childPages = pg.getPages();
			if(childPages!=null&&childPages.size()>0){
				if(setUserOrNot(childPages,a)){
					pg.setUserOrNot(true);
					trueOrFalse = true;
				}
			}
		}
		return trueOrFalse;
	}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ehcache缓存改为redis缓存,需要进行以下步骤: 1.引入redis的依赖包,例如jedis或者lettuce。 2.在Spring配置文件中,将原来的EhCache缓存管理器替换为Redis缓存管理器。例如: ```xml <!-- 引入Redis依赖 --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.5.3</version> </dependency> <!-- 配置Redis缓存管理器 --> <bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager"> <constructor-arg name="redisOperations" ref="redisTemplate"/> <constructor-arg name="cacheNames" value="cacheName1,cacheName2,..."/> </bean> <!-- 配置RedisTemplate --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="jedisConnectionFactory"/> <property name="keySerializer" ref="stringRedisSerializer"/> <property name="valueSerializer" ref="stringRedisSerializer"/> </bean> <!-- 配置JedisConnectionFactory --> <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <property name="hostName" value="localhost"/> <property name="port" value="6379"/> <property name="password" value="password"/> <property name="database" value="0"/> </bean> <!-- 配置StringRedisSerializer --> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer"/> ``` 其中,cacheNames为需要缓存的名称,可以根据实际情况进行配置。 3.在需要使用缓存的地方,使用@Cacheable注解进行缓存操作。例如: ```java @Cacheable(value = "cacheName1", key = "#id") public User getUserById(String id) { // 从数据库中获取用户信息 return userDao.getUserById(id); } ``` 其中,value为缓存名称,key为缓存的键值,可以根据实际情况进行配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值