场景。需要记录用户的操作行为,埋点(pv是页面浏览量,uv是独立访客)
思考。存放到数据库中,记录用户行为。但是用户操作频繁,会有数据库消耗。思考了一下不是很划算。所以想存放redis,记录当天用户访问页面的动作。对应redis存放key 为 项目名称:功能(pv):用户唯一识别号:具体页面(或者具体功能)。然后设置过期时间。这样来记录用户的访问数据。过期时间为当天到次日凌晨之间的时间间隔。也就是说当第二天之后访问数据清除,从新开始新的一天记录。
遇到问题。计算当天到第二天的凌晨的时间秒数。
解决:这里首先区分jdk8跟jdk7的对于时间的操作
具体代码如下
//java7方式
public void getTomorrowSeconds(){
Date date=new Date();
Calendar calendar=();
(date);
(Calendar.DAY_OF_MONTH,1);
(calendar.HOUR_OF_DAY,0);
(,0);
(,0);
(,0);
int seconds= (int) ((().getTime()-())/1000);
(seconds);
}
//java8方式
public int getTomorrowSeconds(Date currentTime){
//从一个 Instant和区域ID获得 LocalDateTime实例
LocalDateTime localDateTime=((), ());
//获取第第二天零点时刻的实例
LocalDateTime toromorrowTime=((), ())
.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
//ChronoUnit日期枚举类,between方法计算两个时间对象之间的时间量
long seconds = (localDateTime, toromorrowTime);
return (int)seconds;
}
小知识点
jdk7中 设置的区别
(, 0);【get 和 set 的字段数字,指示上午或下午的小时。】
跟 (calendar.HOUR_OF_DAY,0); 【get 和 set 的字段数字,指示一天中的小时。】
其中(, 0);会导致 过了中午12点,返回的结果就是当前时间到第二天中午12:00的秒数,如果当前时间不超过中午12点,则返回的结果是第二天凌晨的秒数,也就是我预期想要获得的秒数。
(calendar.HOUR_OF_DAY,0); 无论当前时间是否超过中午12:00 获取都是到第二天凌晨的秒数
拓展思考
如果要做更长久的统计。应该怎么设置redis的值 (其中redis的key跟value 存储数据上限为512M。基本你能放都可以存储)
设想如果要统计一个月的用户数据操作。可以采用这样的方式 对应key值需要修改。将定量的尽量放到前面,变量放到后面。比如 项目名称:功能:当前的时间年月日:项目模块:操作人。然后存储过期时间为设置至少二天。在凌晨进行数据的整合。保存到数据库中。当天的临时记录用redis缓存进行处理,跨时间段比较长的,这部分属于生成后,数据不会轻易改变,则保存到mysql数据库中。毕竟缓存无法代替数据库。
参考链接
/qq_34560242/article/details/79475190
/qq_40691113/article/details/103148860