IAtom问题

@JFinal  最近做了一个门禁扫码系统, 就像地铁站刷二维码一样,后台用的JFinal,

后台有记录每次进入的信息, 但发现机器很灵敏,造成进入日志记录有重复,间隔一秒,现想用new IAtom()方式检查一下10秒此人当天不能有重复记录,也就是说10秒内此人此时间段只记录一条出入日志,因工厂800多人, 想问用这种方式有没有问题,会不会由于同时创建线程太多造成服务器瘫痪?


评论区

JFinal

2018-12-26 10:28

不要用这种方式, 用一下 ehcache , 配置一个过期时间,大致过程如下:
1:用于这个功能的 ehcache 的 name 假定为 "doorLog",过期时间设置为 1 分钟

2:当用户扫码时,先去看 ehcache 的 doorLog 是否存在,如果存在则不做日志

3:如果 doorLog 不存在,则以用户 id 为 key 做一个日志,大致为:
if (CacheKit.get("doorLog", userId) == null) {
CacheKit.put("doorLog", userId, true);
log.logInfo(...) // 这里是做日志的代码
}

这里的关键就是 ehcache 中的 “doorLog" 的过期时间的配置,当过期时间一致,缓存中就没有数据了,那么前面的 if 语句就会为 true

JFinal

2018-12-26 10:57

基于上面的原理,其实还有很多方案,例如,在 mysql 中做一个临时表,例如叫 door_log 表,里面弄两个字段: door_log(long userId, datetime createAt),临时表只做辅助,可以在每天早上使用 Db.update("truncate table door_log") 进行数据清除

用户每次刷卡进入的时候,向这张表里面写数据,然后判断一下该 userId 的最大 createAt 与当前时间的间隔是否大于 10 秒即可,如果大于 10 秒才真正做日志:

Instant ins = LocalDateTime.now().minus(10L, ChronoUnit.SECONDS).atZone(ZoneId.systemDefault()).toInstant();
if (Db.queryLong("select userId where createAt > ?", Date.from(ins)) == null) {
做日志的代码
}

你也可以上上述逻辑用内存来做,在内存里面存放一个 List,里面放下 (userId, createAt) 这两个字段,道理是一样的

fox

2018-12-26 13:46

@JFinal 我说的这个日志表指的是我在后台自已设计的一个出入表,用于考勤记录出入记录,你这个log.logInfo(...) 是指的什么,没看明白. ehcache 没用过

JFinal

2018-12-26 14:42

@fox log.logInfo(...) 是针对你在贴子中提到的下面的这句话:
"后台有记录每次进入的信息, 但发现机器很灵敏,造成进入日志记录有重复"

上面这句话里头有 "日志" 字眼,所以我当成是你要做日志,你只理解成一个抽象动作就好,具体怎么使用看你自己的需求

fox

2018-12-26 15:10

@JFinal, ok,thks, 我回头学习一下ehcache ,看看怎么用到我的项目中去,还没用过ehcache .

JFinal

2018-12-26 15:52

@fox 这里的本质是通过某种手段记下用户的动作,然后在做日志时根据前面手段中的记录来具体操作

fox

2018-12-26 16:03

@JFinal 明白,业务逻辑是清楚的,因为涉及到考勤出入数据量大,所以在业逻辑查询时在考虑用何种方法能提高查询SQL性能(当然后台已优化索引). 我试试你说的ehcache

fox

2018-12-26 16:10

@JFinal JFinal3.3用什么版本的ehcache Jar包? 需要几个Jar文件?

JFinal

2018-12-26 16:24

@fox club 中有,照抄就好

fox

2018-12-26 17:37

热门反馈

扫码入社