Пример #1
0
        public T Get(string key, string region)
        {
            key = CusKeyHelper.GetKey(_options.RedisOcelotKeyPrefix, region, key);
            if (region == nameof(DiffClientRateLimitCounter) && _options.ClusterEnvironment)
            {//限流且开启了集群支持,默认从redis取
                return(RedisHelper.Get <T>(key));
            }
            var result = _cache.Get <T>(key);

            if (result == null && _options.ClusterEnvironment)
            {
                result = RedisHelper.Get <T>(key);
                if (result != null)
                {
                    if (typeof(T) == typeof(CachedResponse))
                    {//查看redis过期时间
                        var second = RedisHelper.Ttl(key);
                        if (second > 0)
                        {
                            _cache.Set(key, result, TimeSpan.FromSeconds(second));
                        }
                    }
                    else
                    {
                        _cache.Set(key, result, TimeSpan.FromSeconds(_options.CacheTime));
                    }
                }
            }
            return(result);
        }
Пример #2
0
 public void Add(string key, T value, TimeSpan ttl, string region)
 {
     key = CusKeyHelper.GetKey(_options.RedisOcelotKeyPrefix, region, key);
     if (_options.ClusterEnvironment)
     {
         var msg = value.ToJson();
         if (typeof(T) == typeof(CachedResponse))
         {                                  //带过期时间的缓存
             _cache.Set(key, value, ttl);   //添加本地缓存
             RedisHelper.Set(key, msg);     //加入redis缓存
             RedisHelper.Publish(key, msg); //发布
         }
         else if (typeof(T) == typeof(DiffClientRateLimitCounter?))
         {//限流缓存,直接使用redis
             RedisHelper.Set(key, value, (int)ttl.TotalSeconds);
         }
         else
         {                                  //正常缓存,发布
             _cache.Set(key, value, ttl);   //添加本地缓存
             RedisHelper.Set(key, msg);     //加入redis缓存
             RedisHelper.Publish(key, msg); //发布
         }
     }
     else
     {
         _cache.Set(key, value, ttl); //添加本地缓存
     }
 }
        /// <summary>
        /// 校验完整的限流规则
        /// </summary>
        /// <param name="rateLimitOptions">限流配置</param>
        /// <returns></returns>
        private bool CheckRateLimitResult(List <DiffClientRateLimitOptions> rateLimitOptions)
        {
            bool result = true;

            if (rateLimitOptions != null && rateLimitOptions.Count > 0)
            {//校验策略
                foreach (var op in rateLimitOptions)
                {
                    var counter = new DiffClientRateLimitCounter(DateTime.UtcNow, 1);
                    //分别对每个策略校验
                    var enablePrefix    = _options.RedisOcelotKeyPrefix + "RateLimitRule";
                    var key             = CusKeyHelper.ComputeCounterKey(enablePrefix, op.ClientId, op.Period, op.RateLimitPath);
                    var periodTimestamp = CusKeyHelper.ConvertToSecond(op.Period);
                    lock (_processLocker)
                    {
                        var rateLimitCounter = _clientRateLimitCounter.Get(key, enablePrefix);
                        if (rateLimitCounter.HasValue)
                        {//提取当前的计数情况
                         // 请求次数增长
                            var totalRequests = rateLimitCounter.Value.TotalRequests + 1;
                            // 深拷贝
                            counter = new DiffClientRateLimitCounter(rateLimitCounter.Value.Timestamp, totalRequests);
                        }
                        else
                        {//写入限流策略
                            _clientRateLimitCounter.Add(key, counter, TimeSpan.FromSeconds(periodTimestamp), enablePrefix);
                        }
                    }
                    if (counter.TotalRequests > op.Limit)
                    {//更新请求记录,并标记为失败
                        result = false;
                    }
                    if (counter.TotalRequests > 1 && counter.TotalRequests <= op.Limit)
                    {//更新缓存配置信息
                        //获取限流剩余时间
                        var cur = (int)(counter.Timestamp.AddSeconds(periodTimestamp) - DateTime.UtcNow).TotalSeconds;
                        _clientRateLimitCounter.Add(key, counter, TimeSpan.FromSeconds(cur), enablePrefix);
                    }
                }
            }
            return(result);
        }
        /// <summary>
        /// 校验当前的请求地址客户端是否有权限访问
        /// </summary>
        /// <param name="clientid">客户端ID</param>
        /// <param name="path">请求地址</param>
        /// <returns></returns>
        public async Task <bool> CheckClientAuthenticationAsync(string clientid, string path)
        {
            var enablePrefix = _options.RedisOcelotKeyPrefix + "ClientAuthentication";
            var key          = CusKeyHelper.ComputeCounterKey(enablePrefix, clientid, "", path);
            var cacheResult  = _ocelotCache.Get(key, enablePrefix);

            if (cacheResult != null)
            {//提取缓存数据
                return(cacheResult.Role);
            }
            else
            {//重新获取认证信息
                var result = await _clientAuthenticationRepository.ClientAuthenticationAsync(clientid, path);

                //添加到缓存里
                _ocelotCache.Add(key, new ClientRoleModel()
                {
                    CacheTime = DateTime.Now, Role = result
                }, TimeSpan.FromMinutes(_options.CacheTime), enablePrefix);
                return(result);
            }
        }