用户回复频率控制Redis

Redis 项目常见场景

需求:

用户回复频率控制

  • 项目的社区功能里,不可避免的总是会遇到垃圾内容,一觉醒来你会发现首页突然会被某些恶意的帖子和广告刷屏了,如果不采取适当的机制来控制就会导致用户体验受到严重的影响
  • 控制广告垃圾贴的策略很多,高级一点的可以通过AI,最简单的方式是通过关键词扫描,还有比较常用的一种方式是频率控制,限制单个用户内容的生产速度,不同等级的用户会有不同的频率控制参数
  • 使用Redis来实现频率控制(青铜1小时3贴 白银1小时5贴 黄金1小时8贴)

方案一:

第一步:记录某个IP访问API频率

  • IP+当前小时 为key在Redis中记录某个IP的调用次数,缓存过期时间为1小时

第二步:限制用户调用API

  • 我们限制 [3] 的值超过阈值,则在Redis中写入 [小黑屋+ip] 为key的一个键值对,再设置过期时间( 到某个时间戳 EXPIREAT < timestamp> 命令用于将键key 的过期时间设置为timestamp所指定的秒数时间戳),不到缓存过期时间就不允许API再被这个IP调用。

  • 在API再次调用的时候,判断Redis中是否存在 [小黑屋+ip] 的这个键值对,如果存在,则返回:此ip访问频率受到限制。


伪代码:

public boolean islimited(String ip) {
    // 获取小黑屋的ip
    String limitip = "小黑屋"+ip;

    //判断ip是否关进了小黑屋
    if(redis.get1(limitip))
        return true;

    //用来记录Ip 一小时内访问次数的KEY
    long hour =  System.currentTimeMillis() / 1000 / (60 * 60);
    String ipCountKey = "ipCount"+ip+":"+hour;

    // 判断 ipCountKey是否存在
    int count = redis.get2(ipCountKey);
    count++;
    if(count > 3) {//阈值3
        redis.set(limitip, 3/*缓存一段时间*/);
        return false;
    }else {
        redis.set(ipCountKey, count);
        return true;
    }
}
//伪代码
class Redis{
	public boolean get1(String limitip) {
        return false;
	}
	
	public int get2(String limitip) {
		return 1;
	}
	
	public void set(String str,int c) {}
}

方案二:

  • 使用Redis中list类型,当用户发帖时,优先查看 用户信息(ip|用户户名) 是否存在。
  • 如果存在则再判断当前时间与第一次发帖时间的时间差,并且时间差1小时内,则再判断是否大于会员限制的数量**【例如3】** 大于则发帖成功,否则发帖失败。
  • 如果时间差不在一个小时内,则清空 list列表中第一个数据,计算第二个位置的数据与当前时间戳的时间差,如再次不满足条件则继续重复该操作。
  • 如果不存在,则记录 用户信息(ip|用户户名)+时间戳 为 key ,类型为 list 的对列中存入第一个数据。

伪代码:

private static void postmsg(String ip, String msg) {
    Redis redis = new Redis();
    List<String> list = new ArrayList<String>();

    // 创建用户信息
    String userinfo = "userinfo"+ip;

    //判断用户信息是否存在
    if(redis.get1(userinfo)) {
        //获取第一个数据+时间戳
        String msgAndTimestamp = list.get(0);
        //获取第一个数据的时间戳
        long timestamp = Long.valueOf(msgAndTimestamp.split("::::")[2]);
        //获取当前时间戳
        long nowtimestamp = System.currentTimeMillis();
        //判断两次时间戳是否小于1小时
        if(nowtimestamp - timestamp < "一小时") {
            list.add(msg+nowtimestamp);

        }else {
            list.remove(0);
            postmsg(ip,msg);
            return ;
        }
    }else {//不存在	
        list.add(msg);
        redis.set(userinfo, list);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值