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