有一个表单需要做幂等性处理,所以每次用户进入到表单页面时,会调用后端接口并生成一个token值返回给前端,那么后端需要怎么存这个token,只考虑JVM内存,不考虑redis来存。
如果存到jvm中,比如定义一个hashMap来存所有用户的token的话,需要怎么存。使用用户ID作为key,token作为值来存储吗?
会不会存在并发问题
有一个表单需要做幂等性处理,所以每次用户进入到表单页面时,会调用后端接口并生成一个token值返回给前端,那么后端需要怎么存这个token,只考虑JVM内存,不考虑redis来存。
如果存到jvm中,比如定义一个hashMap来存所有用户的token的话,需要怎么存。使用用户ID作为key,token作为值来存储吗?
会不会存在并发问题
为了避免一个用户在不同客户端同时操作,token应该在登录阶段就生成。如果你说的这个token与用户登录验证需要的token不是一个,用hashMap存在内存应该是没问题的,如果用户量大或者这个表单提交接口的使用率会很高,那就用LinkedHashMap,效率会高一些。
防止表单重复提交,如果客户端也是本公司开发,可以在第一次提交之后禁用提交按钮,并给token加锁,锁定时间内不可再次提交。
15 回答8.2k 阅读
8 回答6k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
1 回答2.2k 阅读✓ 已解决
单机这么搞行,分布式你只能借助 Redis 之类的啊。
HashMap 肯定是线程不安全的,要么你读写的时候加锁、要么换线程安全的 ConcurrentHashMap。
把用户 ID + 表单 Token 当 K,当前时间戳当 V。
要么你后台单独开启一个线程,定时遍历这个 Map,把时间戳是很久以前的给删掉;要么就在每次插入前取一次、看看能不能过期。
不建议在表单提交的请求执行完之后就立刻把 Key 删掉。为什么你可以琢磨一下。
之所以要加上过期时间戳,一是为了避免 Map 体积无限膨胀占用内存;二是减少随着 Key 越来越多导致的哈希碰撞。
P.S. 所以还是 Redis 好,只存 Key 就行,Key 过期由 Redis 替你管理了。