C# 关于API 限制调用次数方法

一般短信接口,或者付费的接口,需要做一定时间内调用次数的限制。

本文主要根据客户端 ip 做区分调用次数,只考虑可能会有一级代理级别。

首先,我们根据以下两行代码获取客户端ip

 string IpAddress = "";//获取真实IP
            if ((HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null
            && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != String.Empty))
            {
                IpAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            }
            else
            {
                IpAddress= HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            }


然后根据得到的ip去调用以下函数进行校验

 /// <summary>
        /// 限制API接口调用次数
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool CheckCount(string key)
        {
            TimeSpan Const_RedisKeyExpiryHours = new TimeSpan(1, 0, 0, 0);//缓存周期
            string con = "jituan:Robotapi:count";//一般前缀
            using (var redisClient = waterRedisClient.GetWaterClientManager())//对象池获取一个Redis客户端
            {


                if (!string.IsNullOrEmpty((string)redisClient.Redis.GetDatabase().StringGet(con + key+"black")))
                {
                    return false; //黑名单检查
                }
                var tempkey = con + DateTime.Now.Hour + "_"+ key ;
                var reslut =redisClient.Redis.GetDatabase().StringGet(tempkey);
                if (reslut.IsNull)
                {
                    redisClient.Redis.GetDatabase().StringSet(tempkey, 1, Const_RedisKeyExpiryHours);
                    return true;
                }
                else
                {
                    var count = Convert.ToInt32(reslut);
                    if (count<20)//20以内不干预,无需检查
                    {
                        
                        redisClient.Redis.GetDatabase().StringIncrement(tempkey);
                        return true;
                    }
                    else
                    {
                      
                        double survivalTime = redisClient.Redis.GetDatabase().KeyTimeToLive(tempkey).Value.TotalSeconds;//剩余存活时间
                        double dieTime = 24 * 60 * 60 - survivalTime;//过去时间秒数
                        double limitCount = 0.8;//每秒限制的次数
                        double LimitMax = dieTime * limitCount;
                        if (LimitMax< count)
                        {
                            redisClient.Redis.GetDatabase().StringSet(con + "_black"+ key  ,1, Const_RedisKeyExpiryHours);
                            return false;
                        }
                        redisClient.Redis.GetDatabase().StringIncrement(tempkey);
                        return true;
                    }
                }
            }
        }


猜你喜欢

转载自blog.csdn.net/qq_15555767/article/details/79209466