redis 实现 ip 限制

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介:   参考:http://843977358.iteye.com/blog/2317810           http://843977358.iteye.com/blog/2318143   本文 主要 是想更方便的实现ip限制,感觉楼主843977358 写的太过复杂,然后建议他用redis 或者memcached , 因为都有expired  方法,楼主没有使用,本人就写一个吧 。

 

参考:http://843977358.iteye.com/blog/2317810

          http://843977358.iteye.com/blog/2318143

 

本文 主要 是想更方便的实现ip限制,感觉楼主843977358 写的太过复杂,然后建议他用redis 或者memcached ,

因为都有expired  方法,楼主没有使用,本人就写一个吧 。。。

  



 

 

 

 

 

 

/*

 * Project: springmvchibernate
 * 
 * File Created at 2016年11月4日
 * 
 * Copyright 2016 CMCC Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ZYHY Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license.
 */
package com.curiousby.baoyou.cn.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.curiousby.baoyou.cn.redis.RedisConnectionContext;

/**
 * @com.curiousby.baoyou.cn.filters.IPFilter
 * @Type IPFilter.java
 * @Desc 
 * @author cmcc-B100036
 * @date 2016年11月4日 上午10:42:42
 * @version 
 */
@Component
public class IPFilter  implements Filter {

    protected static final Logger logger = LoggerFactory.getLogger(IPFilter.class);
 
    private RedisConnectionContext  redisConnectionContext;
    
    public final static int IPMAXCOUNTPERMINUTES = 5;
    public final static int IPLIMITSENCONDS = 300;
    public final static int IPCOUNTSENCONDS = 60;
    
    
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
      
        
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request; 
        WebApplicationContext wac=WebApplicationContextUtils.getWebApplicationContext(req.getSession().getServletContext());
        redisConnectionContext = (RedisConnectionContext) wac.getBean("redisConnectionContext");
        
        String ip = getIpAddr(req); 

        String ipLimit = redisConnectionContext.getValue(ip+"_limit");
        if (ipLimit !=null &&  !"".equals(ipLimit)) {
            req.getRequestDispatcher("/web/static/forward").forward(req, response);
            return;
        }else{
            String ipConut = redisConnectionContext.getValue(ip+"_count");
            if (ipConut !=null &&  !"".equals(ipConut)){
                int ipLCount = Integer.parseInt(ipConut);
                if(ipLCount >= IPMAXCOUNTPERMINUTES){
                    redisConnectionContext.setValue(ip+"_limit", ipLCount+"", IPLIMITSENCONDS);
                    redisConnectionContext.setValue(ip+"_count", "0", IPCOUNTSENCONDS); 
                    req.getRequestDispatcher("/web/static/forward").forward(req, response);
                    return;
                }else{
                    ipLCount += 1; 
                    redisConnectionContext.setValue(ip+"_count", ipLCount+"", IPCOUNTSENCONDS); 
                } 
            }else{
                redisConnectionContext.setValue(ip+"_count", "1", IPCOUNTSENCONDS);
            }
        } 
        chain.doFilter(req, response);
    }

    @Override
    public void destroy() {
         
        
    }
    
    
    public String getIpAddr(HttpServletRequest request) {   
        String ip = request.getHeader("x-forwarded-for");   
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {   
            ip = request.getHeader("Proxy-Client-IP");   
        }   
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {   
            ip = request.getHeader("WL-Proxy-Client-IP");   
        }   
        if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {   
            ip = request.getRemoteAddr();   
        }   
        return ip;   
    } 

}


/**
 * Revision history
 * -------------------------------------------------------------------------
 * 
 * Date Author Note
 * -------------------------------------------------------------------------
 * 2016年11月4日 cmcc-B100036 creat
 */

 

 

 

expire 方法

 

 public boolean setValue(final String paramKey, final String paramValue,final int seconds) {
        if (null == paramKey || null == paramValue) {
            return false;
        }
        boolean reltValue = false;
        ShardedJedis localShardedJedis = null;
        try {
            localShardedJedis = this.getRedisConnection();
            if (null != localShardedJedis) {
                localShardedJedis.set(paramKey, paramValue);  
                localShardedJedis.expire(paramKey, seconds);
            } else {
                log.error("setValue : key: " + paramKey + " null ShardedJedis error");
            }
        } catch (Exception e) {
            log.error("setValue Exception");
            e.printStackTrace();
        } finally {
            this.closeRedisConnection(localShardedJedis);
        }
        return reltValue;
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

捐助开发者

在兴趣的驱动下,写一个免费的东西,有欣喜,也还有汗水,希望你喜欢我的作品,同时也能支持一下。 当然,有钱捧个钱场(右上角的爱心标志,支持支付宝和PayPal捐助),没钱捧个人场,谢谢各位。



 
 
 谢谢您的赞助,我会做的更好!

 

 

 

 

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
监控 NoSQL Java
云服务器Redis集群部署及客户端通过公网IP连接问题
目录 1、配置文件 2、启动服务并创建集群 (1)启动6个Redis服务 (2)通过客户端命令创建集群 3、客户端连接 (1)客户端配置 (2)测试用例 (3)错误日志分析 4、问题解决 (1)查redis.conf配置文件 (2)修改配置文件 (3)重新启动Redis服务并创建集群 5、故障转移期间Lettuce客户端连接问题 (1)测试用例 (2)停掉其中一个master节点,模拟宕机 (3)解决办法 1)更换Redis客户端 2)Lettuce客户端配置Redis集群拓扑刷新
|
3月前
|
前端开发 NoSQL 数据库
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
|
3月前
|
NoSQL Redis
Redis 使用 hyperLogLog 实现请求ip去重的浏览量
Redis 使用 hyperLogLog 实现请求ip去重的浏览量
34 0
|
12月前
|
NoSQL Java Redis
redis.clients.jedis.exceptions.JedisDataException: ERR Syntax error, try CLIENT (LIST | KILL ip:port
redis.clients.jedis.exceptions.JedisDataException: ERR Syntax error, try CLIENT (LIST | KILL ip:port
|
12月前
|
NoSQL Redis 容器
Redis集群更换节点IP后如何恢复集群并保留完整集群数据
Redis集群更换节点IP后如何恢复集群并保留完整集群数据
159 0
|
12月前
|
NoSQL Redis 容器
Redis集群报错cluster_state:fail,如何解决并重新恢复集群(IP问题/ slot未完全分配问题)
Redis集群报错cluster_state:fail,如何解决并重新恢复集群(IP问题/ slot未完全分配问题)
199 0
|
NoSQL Redis
基于redis实现IP访问频次控制(超简单)
基于redis实现IP访问频次控制(超简单)
172 0
|
NoSQL Redis
Redis学习4:List数据类型、拓展操作、实现日志等
注意点:对存储空间的顺序进行分析!
Redis学习4:List数据类型、拓展操作、实现日志等
|
存储 NoSQL Redis
Redis学习3:hash类型操作、拓展操作、实现购物等
首先可以理解成一个redis里面有一个小的redis。同时要注意引入了一个field的名字。
Redis学习3:hash类型操作、拓展操作、实现购物等
下一篇
无影云桌面