使用Redis 哈希(Hash)统计pv uv

版权声明:本文为博主原创文章,转载需标明出处哦 ^-^。 https://blog.csdn.net/qq_33101675/article/details/89002517

需求:要统计每天有多个用户访问这个渠道的H5页面,计算PV UV

废话少说,直接上代码:

(1)这个是渠道H5的index方法,利用Redis hash里的下面三个方法

HEXISTS key field 
查看哈希表 key 中,指定的字段是否存在。

HINCRBY key field increment 
为哈希表 key 中的指定字段的整数值加上增量 increment 。

HSET key field value 
将哈希表 key 中的字段 field 的值设为 value 。

/**
     * demo:要统计每天有多个用户访问这个渠道的H5页面
     * 假设这个是访问H5首页的方法
     * 页面访问一次,就计算一次 pv uv 数据
     * @return
     */
    public String index(HttpServletRequest request,Long channelId){
        /*获取用户真实ip*/
        String ip = Utils.getRealIp(request);

        /*缓存key*/
        String key = "CHANNEL_DATA_CACHE_KEY_" + channelId;

        /*判断该缓存是否有该ip*/
        boolean hexists = redisClient.hexists(key, ip);

        if (hexists) {
            /*有的话,说明之前该ip访问过,次数加1*/
            redisClient.hincrby(key, ip, 1);
        } else {
            /*没有,说明第一次访问,给该ip计数1次*/
            HashMap<String, String> map = new HashMap<>(2);
            map.put(ip, "1");
            redisClient.hmset(key, map);
        }
        return "ok";
    }

(2)统计缓存里的 pv uv,利用Redis hash里的下面三个方法

HLEN key 
获取哈希表中字段的数量(UV)

HVALS key 
获取哈希表中所有值(PV)

/**
     * 统计pv uv,可做定时任务,每晚0点更新到DB里
     * @return
     */
    public String dataStatistics(Long channelId){
        /*缓存key*/
        String key = "CHANNEL_DATA_CACHE_KEY_" + channelId;

        /*uv*/
        Long uvToday = redisClient.hlen(key);

        /*pv*/
        List<String> hvals = redisClient.hvals(key);
        Long pvToday = 0L;
        for (String str : hvals) {
            pvToday += Long.valueOf(str);
        }
        return "ok";
    }

获取用户真实IP :

public static String getRealIp(HttpServletRequest request) {
        String ip = null;
        //X-Forwarded-For:Squid 服务代理
        String ipAddresses = request.getHeader("X-Forwarded-For");
        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //Proxy-Client-IP:apache 服务代理
            ipAddresses = request.getHeader("Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //WL-Proxy-Client-IP:weblogic 服务代理
            ipAddresses = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //HTTP_CLIENT_IP:有些代理服务器
            ipAddresses = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            //X-Real-IP:nginx服务代理
            ipAddresses = request.getHeader("X-Real-IP");
        }

        //有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
        if (ipAddresses != null && ipAddresses.length() != 0) {
            ip = ipAddresses.split(",")[0];
        }

        //还是不能获取到,最后再通过request.getRemoteAddr();获取
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }

RedisClient的全部方法奉上,供参考:

package com.aplus.config.redis;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author 王弘博
 */
@Component
public class RedisClient {

    private Logger logger = LoggerFactory.getLogger(RedisClient.class);

    @Resource
    private JedisPool jedisPool;

    public Long del(String key) {
        Long value = null;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            if (jedis.exists(key)) {
                value = jedis.del(key);
                this.logger.debug("del {} = {}", key, value);
            }
        } catch (Exception e) {
            this.logger.error("del {} = {}", new Object[]{key, value, e});
        } finally {
            this.release(jedis);
        }
        return value;
    }

    public String get(String key) {
        String value = null;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            if (jedis.exists(key)) {
                value = jedis.get(key);
                value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
                this.logger.debug("get {} = {}", key, value);
            }
        } catch (Exception e) {
            this.logger.error("get {} = {}", new Object[]{key, value, e});
        } finally {
            this.release(jedis);
        }
        return value;
    }

    public String set(String key, String value) {
        return this.set(key, value, 0);
    }

    public String set(String key, String value, int expire) {
        Jedis jedis = null;
        String result = null;
        try {
            jedis = this.getResource();
            result = jedis.set(key, value);
            if (expire != 0) {
                jedis.expire(key, expire);
            }
            logger.debug("set {} = {}", key, value);
        } catch (Exception e) {
            logger.error("set {} = {}", new Object[]{key, value, e});
        } finally {
            this.release(jedis);
        }
        return result;
    }

    public boolean exists(String key) {
        boolean result = false;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            result = jedis.exists(key);
        } catch (Exception e) {
            logger.error("exists {}", key, e);
        } finally {
            this.release(jedis);
        }
        return result;
    }

    /**
     * ttl
     *
     * @param key
     * @return
     */
    public Long ttl(String key) {
        Long result = 0L;
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            result = jedis.ttl(key);
        } catch (Exception e) {
            logger.error("exists {}", key, e);
        } finally {
            this.release(jedis);
        }
        return result;
    }

    public Long incr(String key) {
        return incrWithExpire(key, 0);
    }

    public Long incrWithExpire(String key, int seconds) {
        Jedis jedis = null;
        Long incr;
        try {
            if (StringUtils.isBlank(key)) {
                incr = null;
                return incr;
            }
            jedis = this.getResource();
            incr = jedis.incr(key);
            if (seconds > 0) {
                jedis.expire(key, seconds);
            }
        } catch (Exception e) {
            logger.error("incr {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
        return incr;
    }

    public Long incrBy(String key, Long integer) {
        Jedis jedis = null;
        Long incrBy;
        try {
            if (StringUtils.isBlank(key)) {
                incrBy = null;
                return incrBy;
            }
            if (integer == null) {
                integer = 0L;
            }
            jedis = this.getResource();
            incrBy = jedis.incrBy(key, integer);
        } catch (Exception e) {
            logger.error("incr {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
        return incrBy;
    }

    public Long incrByWithExpire(String key, Long integer, int seconds) {
        Jedis jedis = null;
        Long incrBy;
        try {
            if (StringUtils.isBlank(key)) {
                incrBy = null;
                return incrBy;
            }
            if (integer == null) {
                integer = 0L;
            }
            jedis = this.getResource();
            incrBy = jedis.incrBy(key, integer);

            if (seconds > 0) {
                jedis.expire(key, seconds);
            }
        } catch (Exception e) {
            logger.error("incr {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
        return incrBy;
    }

    public Long decrBy(String key, Long integer) {
        Jedis jedis = null;
        Long decrBy;
        try {
            if (StringUtils.isBlank(key)) {
                decrBy = null;
                return decrBy;
            }
            if (integer == null) {
                integer = 0L;
            }
            jedis = this.getResource();
            decrBy = jedis.decrBy(key, integer);
        } catch (Exception e) {
            logger.error("incr {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
        return decrBy;
    }

    public Long decr(String key) {
        Jedis jedis = null;
        Long decr;
        try {
            if (StringUtils.isBlank(key)) {
                decr = null;
                return decr;
            }
            jedis = this.getResource();
            decr = jedis.decr(key);
            return decr;
        } catch (Exception e) {
            logger.error("decr {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
    }

    /**
     * hgetAll
     *
     * @param key
     * @return
     */
    public Map<String, String> hgetAll(String key) {
        Map<String, String> map = new HashMap<>();
        Jedis jedis = null;
        try {
            if (StringUtils.isBlank(key)) {
                return map;
            }
            jedis = this.getResource();
            map = jedis.hgetAll(key);
            return map;
        } catch (Exception e) {
            logger.error("hgetAll {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
    }

    /**
     * hmset
     *
     * @param key
     * @return
     */
    public String hmset(String key, Map<String, String> map) {
        Jedis jedis = null;
        try {
            if (StringUtils.isBlank(key)) {
                return null;
            }
            jedis = this.getResource();
            return jedis.hmset(key, map);
        } catch (Exception e) {
            logger.error("hmset {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
    }

    /**
     * hexists
     *
     * @param key
     * @param field
     * @return
     */
    public boolean hexists(String key, String field) {
        Jedis jedis = null;
        try {
            if (StringUtils.isBlank(key)) {
                return false;
            }
            jedis = this.getResource();
            return jedis.hexists(key, field);
        } catch (Exception e) {
            logger.error("hexists {} ", key, e);
            return false;
        } finally {
            this.release(jedis);
        }
    }

    /**
     * hincrby
     *
     * @param key
     * @param field
     * @return
     */
    public Long hincrby(String key, String field, long increment) {
        Jedis jedis = null;
        try {
            if (StringUtils.isBlank(key)) {
                return null;
            }
            jedis = this.getResource();
            return jedis.hincrBy(key, field, increment);
        } catch (Exception e) {
            logger.error("hincrby {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
    }

    /**
     * hlen
     *
     * @param key
     * @return
     */
    public Long hlen(String key) {
        Jedis jedis = null;
        try {
            if (StringUtils.isBlank(key)) {
                return null;
            }
            jedis = this.getResource();
            return jedis.hlen(key);
        } catch (Exception e) {
            logger.error("hlen {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
    }

    /**
     * hvals
     *
     * @param key
     * @return
     */
    public List<String> hvals(String key) {
        Jedis jedis = null;
        List<String> result = new ArrayList<>();
        try {
            if (StringUtils.isBlank(key)) {
                return result;
            }
            jedis = this.getResource();
            result = jedis.hvals(key);
        } catch (Exception e) {
            logger.error("hvals {} ", key, e);
            return result;
        } finally {
            this.release(jedis);
        }
        return result;
    }

    /**
     * hdel
     *
     * @param key
     * @param fields
     * @return
     */
    public Long hdel(String key, String... fields) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            return jedis.hdel(key, fields);
        } catch (Exception e) {
            logger.error("hdel {} ", key, e);
            return null;
        } finally {
            this.release(jedis);
        }
    }


    /**
     * 获取分布式锁
     *
     * @param lockKey
     * @return
     */
    public boolean getLock(String lockKey) {
        return this.getLock(lockKey, "1", 5);
    }

    /**
     * 获取分布式锁
     *
     * @param lockKey
     * @param requestId
     * @param expireTime
     * @return
     */
    public boolean getLock(String lockKey, String requestId, int expireTime) {
        Jedis jedis = null;
        try {
            jedis = this.getResource();
            String result = jedis.set(lockKey, requestId, "NX", "EX", expireTime);
            if ("OK".equals(result)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            logger.error("getLock {} ", lockKey, e);
            return false;
        } finally {
            this.release(jedis);
        }
    }

    /**
     * 释放分布式锁
     *
     * @param lockKey
     * @return
     */
    public boolean unLock(String lockKey) {
        return this.unLock(lockKey, "1");
    }

    /**
     * 释放分布式锁
     *
     * @param lockKey
     * @param requestId
     * @return
     */
    public boolean unLock(String lockKey, String requestId) {
        Jedis jedis = null;
        try {
            String script = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then\n" +
                    "    return redis.call(\"del\",KEYS[1])\n" +
                    "else\n" +
                    "    return 0\n" +
                    "end";
            jedis = this.getResource();
            Object result = jedis.eval(script, Collections.singletonList(lockKey),
                    Collections.singletonList(requestId));
            if ("OK".equals(result)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            logger.error("unLock {} ", lockKey, e);
            return false;
        } finally {
            this.release(jedis);
        }
    }

    private Jedis getResource() throws Exception {
        try {
            return jedisPool.getResource();
        } catch (Exception e) {
            logger.error("getResource.", e);
            throw e;
        }
    }

    private void release(Jedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33101675/article/details/89002517