项目-24-网站数据统计

本文介绍网站数据统计中的关键指标,包括独立访客(UV)和日活跃用户(DAU)。UV通过IP去重,使用HyperLoglog进行高效统计;DAU依赖用户ID,采用Bitmap确保准确性,并通过RedisKeyUtil、DateService、DataInterceptor等组件实现数据拦截、处理和展示。此外,数据页面只对管理员开放。

网站数据统计

1.UV(Unique Visitor)

  • 独立访客,需通过用户IP去重统计数据。不需要登录
  • 每次访问都要进行统计。
  • HyperLoglog:性能好,且存储空间小。

2.DAU(Daily Active User)

  • 日活跃用户,需通过用户ID去重统计数据。需要登录
  • 访问过一次,则认为其为活跃。
  • Bitmap:性能好、且可以统计精确的结果。
  • 通过用户ID作为Bitmap的索引,1表示今天为活跃,0表示今天不活跃

1.RedisKeyUtil

//单日UV:某一天的数据
public static String getUVKey(String date){
   
   
    return PREFIX_UV + SPLIT + date;
}

//区间UV:某几天的数据 [startDate, endDate]
public static String getUVKey(String startDate, String endDate){
   
   
    return PREFIX_UV + SPLIT + startDate + SPLIT + endDate;
}

//单日DAU:某一天的数据
public static String getDAUKey(String date){
   
   
    return PREFIX_DAU + SPLIT + date;
}

//区间DAU:某几天的数据 [startDate, endDate]
public static String getDAUKey(String startDate, String endDate){
   
   
    return PREFIX_DAU + SPLIT + startDate + SPLIT + endDate;
}

2.DateService

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

// 统计UV和DAU的业务逻辑
@Service
public class DateService {
   
   
	// 进行Redis有关的操作
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private HostHolder hostHolder;

    // 统一时间格式:年月日
    private SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");

    /**
     * 根据访问网站的ip统计当前的UV
     * @param ip ip地址
     */
    public void recordUV(int ip){
   
   
        //1. 创建Redis的key,当前的时间
        String redisKey = RedisKeyUtil.getUVKey(df.format(new Date()));
        //2. 将ip地址存入Redis的HyperLogLog
        redisTemplate.opsForHyperLogLog().add(redisKey, ip);
    }

    /**
     * 统计一段时间网站的UV
     * @param start 起始时间
     * @param end 结束时间
     */
    public long calculateUV(Date start, Date end){
   
   
        //1. 判断参数是否为空
        if (start == null || end == null){
   
   
            throw new IllegalArgumentException("参数不能为空");
        }

        //2. 确定在区间中每一天的key,将每一天key存在list中
        List<String> keyList = new ArrayList<>();
        // Calendar.getInstance() 获取指定时间点(定时)
        Calendar calendar = Calendar.getInstance();
        // 采用Date类型的一个参数dt表示要设置的给定日期
        calendar.setTime(start);
        // 遍历每一天
        while (!calendar.getTime().after(end)){
   
   
            // 将每一天key存在list中
            String key = RedisKeyUtil.getUVKey(df.format(calendar.getTime()));
            keyList.add(key);
            // 增加一天
            calendar.add(calendar.DATE, 1);
        }
        // 3. 合并数据
        // 创建合并的key
        String redisKey = RedisKeyUtil.getUVKey(df.format(start), df.format(end));
        // 将list中每一天的key合并成redisKey
        redisTemplate.opsForHyperLogLog().union(redisKey, keyList.toArray());
        // 4. 返回统计结果
        return redisTemplate.opsForHyperLogLog().size(redisKey);
    }

    /**
     * 根据userId将其计入DAU
     * @param userId
     */
    public void recordDAU(int userId){
   
   
        String redisKey = RedisKeyUtil.getDAUKey(df.format(new Date())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值