1. 程式人生 > >C# 關於API 限制呼叫次數方法

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;
                    }
                }
            }
        }