Coder Social home page Coder Social logo

gitblog's People

Contributors

frostming avatar gnimg avatar kemingy avatar paradisewitch avatar raywangsy avatar yihong0618 avatar

Watchers

 avatar

gitblog's Issues

spring-session的removeAttribute方法踩坑

问题场景还原

背景:现在有一个服务使用了spring-session。服务有一个需求,需要在一个业务中将一个数据保存在用户session中的一个属性上,然后再在另一个业务将数据从redis中取出。类似以下模式:

  1. 当用户操作第一次时,attr1作为key,数据1作为value会被添加到session中
  2. 当用户操作第一次时,attr2作为key,数据2作为value会被添加到session中

……以此类推。以上是正常需求。

但是现在出现了一个问题:短时间内有一个用户操作次数过多,这个数据不断地在sessionMap中添加键值对,导致redis中这个人的对应的sessionMap越来越大,最后获取这个人的session时导致请求redis超时。

解决方案

这个问题其实算是设计问题,只要将原来将存在redis中的数据形式改为如下形式就可以:

key:sessionId+attrName1
value: 数据1

这样的话一条redis的数据也不会像sessionMap那样无限增加,造成请求超时。

尝试基于原有设计进行修改

虽然上面的解决方案可以直接解决根本问题,但是我还是想基于原来的设计修改一下。

由于这个数据存过后只会使用一次,那么我在使用完成后在sessionMap中删除这个属性就好了

伪代码如下:

// 唯一一次的获取session中这个属性的值
request.getSession().removeAttribute()

想法是好的,但是事与愿违。经过测试后发现,好家伙,removeAttribute方法确实把内存中的session中的属性删除了,但是更新到redis后,发现只是在sessionMap只把对应属性的value设置成了null:

image

我对这样的行为感到奇怪,于是找到了一个issue:spring-projects/spring-session/issues/1331

没办法,我尝试在获取一次session中这个属性的值之后就删除这个属性,代码like下面这样:

// 唯一一次的获取session中这个属性的值
request.getSession().removeAttribute()
redisCacheHashService.sessionHmDelete(request.getSession().getId(), attrName)

sessionHmDelete是一个封装了一个使用redisTemplate直接删除redis中sessionMap中key的函数,代码类似下面这样:

public void sessionHmDelete(string sessionId,String attrName){
	String redisKey = "spring:session:sessions:"+ sessionId;
	String mapKey = "sessionAttr:" + attrName;
	// get redisTemplate 
	RedisTemplate redisTemplate = redisTemplateService.getRedisTemplate(0);
	redisTemplate.setHashKeySerializer(new StringRedisSerializer());
	redisTemplate.sethashValueserializer(new JdkSerializationRedisSerializer());
	redisTemplate.afterPropertiesSet();
	redisTemplate.opsForHash().delete( redisKey, mapKey);
}

经过测试后发现通过这段代码后,redis依旧没有删除key,只是把value置为了null。

很奇怪,继续查看源码。

  1. removeAttribute方法源码,可以看到这里putAndFlush第二个参数传入的为 null

    image

  2. putAndFlush方法源码,其中delta是一个 map,临时记录改变的数据,方便等到更新时将所有变动更新到 redis 中。调用removeAttribute后,这个 map 就保存了一个键值对(key,null)

    image

  3. flushImmediateIfNecessary方法源码,更新时并不是马上一调用removeAttribute就会马上更新,默认时RedisFlushMode配置为ON_SAVE

    image

  4. 由于不是立马更新到 redis,这个saveDelta方法会在我们手动使用 redisTemplate 删除 redis 中 session 中的属性后执行,于是此时又会将 delta 变动信息 put 到 redis 中,最终会将空值 put 到这个属性上。

    修改配置方法:

    <bean class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
      <property name="redisFlushMode" value="IMMEDIATE"/>
    </bean>

但是spring-session的配置不是说改就能改的,需要权衡可能对现有业务的影响。所以改配置也不是明智之举。

那么至于RedisFlushModeON_SAVE的情况下,什么时候才会调用saveDelta方法呢?这个问题我就没有深入研究下去了,暂时没有测试出来,那天有时间了再研究吧。

2023 OKR

2023 OKR

奖励

60: switch
75: hhkb
120: apple watch

健身

  • okr1(10): 瘦10斤
  • okr2(20): 瘦20斤
  • okr3(30): 瘦40斤
  • okr4(35): 腹肌

英语

  • okr1(20): 单词1000个
  • okr2(20): 单词2000个
  • okr3(35): 熟练阅读,听懂口语,无障碍看生肉

日语

  • okr1(10): 完成基础
  • okr2(20): 学会唱日语歌曲(Rage your dream)
  • okr3(35): 无障碍看生肉

代码

  • okr1(20): 完成600道leetcode,之后每多完成100道题就+5,当前353
  • okr1(25): 完成maid_comic_home
  • okr2(30): 看技术书5本
  • okr3(30): 使用unity做游戏
  • okr4(40): 学习Rust,尝试使用Tauri写一个桌面程序
  • okr5(50): 尝试活跃参与著名开源项目

工作

  • okr1(20): 一份更有技术提升的工作
  • okr2(40): 薪水翻倍
  • ork3(50): WFH
  • okr4(40): 半个救火队员

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.