做网站博客怎么推广,wordpress打开错误,百度行业网站怎么做,网站目的在.NET中使用Redis来限制接口请求频率#xff08;每10秒只允许请求一次#xff09;
NuGet setup StackExchange.Redis
实现速率限制逻辑#xff1a; 在控制器或服务层中#xff0c;编写Redis速率限制计数器。 设置Redis键#xff1a; 为每个用户或每个IP地址设置一个唯一…在.NET中使用Redis来限制接口请求频率每10秒只允许请求一次
NuGet setup StackExchange.Redis
实现速率限制逻辑 在控制器或服务层中编写Redis速率限制计数器。 设置Redis键 为每个用户或每个IP地址设置一个唯一的键。这个键将用于存储最后一次请求的时间戳和/请求计数。 检查时间戳 当请求到达时从Redis中获取该键的值时间戳。如果键不存在或时间戳超过10秒则允许请求并更新键的值设置为当前时间戳。 处理超过速率的请求 如果时间戳在10秒内则拒绝或限制该请求返回限制状态码。 private static readonly LazyConnectionMultiplexer LazyConnection new LazyConnectionMultiplexer(() {// 配置Redis连接字符串 localhost,abortConnectfalse return ConnectionMultiplexer.Connect(localhost:6379);});private static ConnectionMultiplexer Connection LazyConnection.Value;private static IDatabase Db Connection.GetDatabase();public async TaskActionResult MyAction(){IPAddress clientIpAddress HttpContext.Connection.RemoteIpAddress;string ipAddress clientIpAddress.ToString();string redisKey $rate-limit:{ipAddress}; // 构建Redis键名 // 获取当前时间戳可以是Unix时间戳或任何你选择的格式 long currentTimestamp DateTimeOffset.UtcNow.ToUnixTimeSeconds();// 尝试从Redis获取时间戳 var redisValue await Db.StringGetAsync(redisKey);long lastTimestamp redisValue.HasValue ? (long)redisValue : 0;// 检查是否超过10秒 if (currentTimestamp - lastTimestamp 10){// 如果超过10秒则允许请求并更新Redis键 await Db.StringSetAsync(redisKey, currentTimestamp, TimeSpan.FromSeconds(10)); // 设置键的过期时间为10秒 return Content(Request allowed.);}else{// 如果未超过10秒则拒绝请求 HttpResponseMessage response new HttpResponseMessage(HttpStatusCode.TooManyRequests){ReasonPhrase Too Many Requests,Content new StringContent(Rate limit exceeded. Please try again later.)};// 处理请求return Content(Please try again later. );// throw new HttpResponseException(response); // 或者返回自定义的ActionResult }}扩展为参数
MyAction(string p)
//...
string redisKey $rate-limit:{p};请求 /MyAction?p2 /MyAction?p3
滑动窗口算法
滑动窗口算法Sliding Window Algorithm是一种用于解决字符串/数组 问题的算法它通过维护一个窗口即一个连续的子串或子数组并在字符串或数组上滑动这个窗口来寻找满足特定条件的子串或子数组。以下是滑动窗口算法的主要内容和特点
维护窗口通过两个指针左指针和右指针来定义窗口的边界。 移动窗口通过移动右指针来扩展窗口同时根据问题的要求调整左指针来缩小窗口。 更新信息在窗口滑动的过程中根据需要更新一些数据结构如哈希表来保存所需的信息。
实现方法 步骤1.初始化定义左指针和右指针并初始化它们的位置。 步骤2.扩展窗口向右移动右指针扩展窗口同时更新所需的信息如字符频率的哈希表。 步骤3.检查条件当窗口满足特定条件时开始收缩窗口。 步骤4.收缩窗口向右移动左指针缩小窗口同时更新所需的信息。 步骤5.更新最优解在收缩窗口的过程中不断更新最优解如最长子串、最短子串等。 重复步骤重复步骤2到步骤5直到右指针到达字符串或数组的末尾。
在Redis中维护一个窗口内的请求时间戳列表而不是仅仅存储最后一次请求的时间戳。移除超过窗口大小的时间戳。检查剩余的时间戳数是否超过了最大请求数 MaxRequests。如果超过则返回超过的响应否则记录当前时间戳并允许请求。 private const int MaxRequests 5; // 最大请求数private const int WindowSizeInSeconds 10; // 窗口大小秒//...// 获取Redis中存储的时间戳列表var redisValue await Db.ListRangeAsync(redisKey);var timestamps redisValue.Select(value (long)value).ToList();// 移除窗口之外的时间戳timestamps timestamps.Where(timestamp currentTimestamp - timestamp WindowSizeInSeconds).ToList();if (timestamps.Count MaxRequests){// 如果请求数超过限制则拒绝请求HttpResponseMessage response new HttpResponseMessage(HttpStatusCode.TooManyRequests){ReasonPhrase Too Many Requests,Content new StringContent(Rate limit exceeded. Please try again later.)};return Content(Please try again later.);}else{// 如果请求数未超过限制则允许请求并记录当前时间戳timestamps.Add(currentTimestamp);await Db.ListRightPushAsync(redisKey, timestamps.Select(timestamp (RedisValue)timestamp).ToArray());await Db.KeyExpireAsync(redisKey, TimeSpan.FromSeconds(WindowSizeInSeconds)); // 设置键的过期时间为窗口大小return Content(Request allowed.);}End