zoukankan      html  css  js  c++  java
  • asp.net 通过redis 缓存限制接口访问频率

    1、通过nuget 管理器安装ServiceStack.Redis

    2、在web.config 加入redis配置

    <appSettings>
        <!--redis配置-->
        <add key="WriteServerList" value="127.0.0.1:6379"/>
        <add key="ReadServerList" value="127.0.0.1:6379"/>
        <add key="MaxWritePoolSize" value="60"/>
        <add key="MaxReadPoolSize" value="60"/>
        <add key="AutoStart" value="true"/>
        <add key="LocalCacheTime" value="1800"/>
        <add key="RecordeLog" value="false"/>

    3、新建 RedisManager.cs

    using ServiceStack.Redis;
    using ServiceStack.Redis.Generic;
    using System;
    using System.Configuration;
    using System.Linq;
    
    namespace Music.Musical.WebUtility
    {
    public    class RedisManager
        {
            public static string WriteServerList = ConfigurationManager.AppSettings["WriteServerList"];
            public static string ReadServerList = ConfigurationManager.AppSettings["ReadServerList"];
            public static int MaxWritePoolSize = Convert.ToInt32(ConfigurationManager.AppSettings["MaxWritePoolSize"]);
            public static int MaxReadPoolSize = Convert.ToInt32(ConfigurationManager.AppSettings["MaxReadPoolSize"]);
            public static int LocalCacheTime = Convert.ToInt32(ConfigurationManager.AppSettings["LocalCacheTime"]);
            public static bool AutoStart = ConfigurationManager.AppSettings["AutoStart"].Equals("true") ? true : false;
    
            private static PooledRedisClientManager prcm;
            /// <summary>
            /// 限制IP访问网站的频率,1分钟内限制的请求次数,
            /// </summary>
            /// <param name="rate">次数</param>
            /// <param name="page">用于生成不同key</param>
            /// <param name="minutes">分钟</param>
            /// <returns></returns>
            public static bool IsValidAccess(int rate, string page, int minutes, System.Web.HttpContext httpContext)
            {
                string key = page + getIp(httpContext);
                using (var redisClient = RedisManager.GetClient())
                {
                    int getRate = redisClient.Get<int>(key);
                    if (!redisClient.ContainsKey(key))
                    {
                        redisClient.Set<int>(key, 1,DateTime.Now.AddMinutes(minutes));
                    }
                    else if (getRate > rate)
                    {
                        return false;
                    }
                    else
                        redisClient.Increment(key,1);
                  
                }
                return true;
            }
    
            private static string getIp(System.Web.HttpContext httpContext) 
            {
                string userIP;
                System.Web.HttpRequest Request = httpContext.Request; // ForumContext.Current.Context.Request; 
                                                                   // 如果使用代理,获取真实IP 
                userIP = Request.UserHostAddress;
    
                if (string.IsNullOrEmpty(userIP))
                {
                    if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != "")
                        userIP = Request.ServerVariables["REMOTE_ADDR"];
                    else
                        userIP = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                }
                return userIP;
            }
            /// <summary>
            /// 创建链接池管理对象
            /// </summary>
            private static void CreateManager()
            {
                string[] writeServerList = SplitString(WriteServerList, ",");
                string[] readServerList = SplitString(ReadServerList, ",");
    
                prcm = new PooledRedisClientManager(readServerList, writeServerList,
                                 new RedisClientManagerConfig
                                 {
                                     MaxWritePoolSize = MaxWritePoolSize,
                                     MaxReadPoolSize = MaxReadPoolSize,
                                     AutoStart = AutoStart,
                                 });
            }
    
            private static string[] SplitString(string strSource, string split)
            {
                return strSource.Split(split.ToArray());
            }
    
            /// <summary>
            /// 客户端缓存操作对象
            /// </summary>
            public static IRedisClient GetClient()
            {
                if (prcm == null)
                    CreateManager();
    
                return prcm.GetClient();
            }
            /// <summary>
            /// 缓存默认24小时过期
            /// </summary>
            public static TimeSpan expiresIn = TimeSpan.FromHours(24);
            /// <summary>
            /// 设置一个键值对,默认24小时过期
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="value"></param>
            /// <param name="redisClient"></param>
            /// <returns></returns>
            public static bool Set<T>(string key, T value, IRedisClient redisClient)
            {
    
                return redisClient.Set<T>(key, value, expiresIn);
            }
    
            /// <summary>
            /// 将某类数据插入到list中
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key">一般是BiaoDiGuid</param>
            /// <param name="item"></param>
            /// <param name="redisClient"></param>
            public static void Add2List<T>(string key, T item, IRedisClient redisClient)
            {
                var redis = redisClient.As<T>();
                var list = redis.Lists[GetListKey(key)];
                list.Add(item);
            }
    
            /// <summary>
            /// 获取一个list
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="key"></param>
            /// <param name="redisClient"></param>
            /// <returns></returns>
            public static IRedisList<T> GetList<T>(string key, IRedisClient redisClient)
            {
                var redis = redisClient.As<T>();
                return redis.Lists[GetListKey(key)];
            }
    
            public static string GetListKey(string key, string prefix = null)
            {
                if (string.IsNullOrEmpty(prefix))
                {
                    return "urn:" + key;
                }
                else
                {
                    return "urn:" + prefix + ":" + key;
                }
            }
        }
    }

    3、使用

     public void ProcessRequest(HttpContext context)
            {
                context.Response.ContentType = "text/json";
                string act = context.Request.QueryString["act"];
    
                bool isValid = RedisManager.IsValidAccess(6, act, 2, context);
    
                if (!isValid) 
                {
                    context.Response.Write("{"code":404,"msg":"您的访问太频繁了!"}");
                    context.Response.End();
                }

    相关参考:

    windows redis配置并开机启动

    asp.net性能优化之使用Redis缓存(入门)

    相关问题:

    问题描述:Redis跑了一段时间之后,出现了以下异常。

    Redis Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use.

    解决方法:

    初步分析是连接池的最大连接数量限制,超过了最大数量,则直接报错

     public static T getKey<T>(string key)
            {
               IRedisClient redisClient;
                try
                {
                    redisClient = RedisManager.GetClient();
                 
                }
                catch (Exception e) 
                {
                    prcm.Dispose();
               
                    redisClient = RedisManager.GetClient();
    
                }
                return redisClient.Get<T>(key);
            }
    

      

  • 相关阅读:
    Tinyhttpd 代码学习
    Windows noinstall zip 安装MySQL。
    Java 优先队列
    Java Comparable 和 Comparator
    Centos6.6下安装Python3.5
    对象的实现
    对象接口
    适配器模式
    java基础学习(一)
    【MongoDB】如何注册windows服务
  • 原文地址:https://www.cnblogs.com/fogwang/p/14684963.html
Copyright © 2011-2022 走看看