• Redis限流


    在电商开发过程中,我们很多地方需要做限流,有的是从Nginx上面做限流,有的是从代码层面限流等,这里我们就是从代码层面用Redis计数器做限流,这里我们用C#语言来编写,且用特性(过滤器,拦截器)的形式拦截限流,CSRedis来作为redis的客户端包。

    1-新建一个.NET CORE的WebApi项目

    其中默认的Webapi如

       [ApiController]
        [Route("[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            private static readonly string[] Summaries = new[]
            {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
     
            private readonly ILogger<WeatherForecastController> _logger;
     
            public WeatherForecastController(ILogger<WeatherForecastController> logger)
            {
                _logger = logger;
            }
    
            [HttpGet]
            public IEnumerable<WeatherForecast> Get()
            {
    
                var rng = new Random();
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
    
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                })
                .ToArray();
            }
        }

    2-引入CSRedisCore包

    使用方法可以访问地址https://github.com/ctstone/csredis

      

    3-安装启动Redis

    4-新建一个特性(过滤器,拦截器),名字叫RateLimitingAttirbute

    public class RateLimitingAttirbute : ActionFilterAttribute
        {
            private readonly int _count;
            public RateLimitingAttirbute(int count)
            {
                _count = count;//请求次数闲置
            }
     
            public override async void OnActionExecuting(ActionExecutingContext context)
            {
                var userID = 0;//当我们在每个用户维度做限流,比如要限制每个用户的每个接口请求多少次,我们需要从请求头中解析用户信息,如token,获取用户的Id
                var redisKey = "RedisConsts.RateLimiter";//Redis的Key
                var csredis = new CSRedisClient("localhost");//链接Redis地址,这里默认本地地址
                RedisHelper.Initialization(csredis);
    
               //限流的redis的key是“RedisConsts.RateLimiter”+接口地址
     var RateLimiterKey = string.Format(redisKey, $"{userID}{context.HttpContext.Request.Path.Value.Replace("/", ":")}");//获取接口地址
                if (RedisHelper.Exists(RateLimiterKey))
                {
                    string redisResult =await RedisHelper.GetAsync(RateLimiterKey);
                    if (int.Parse(redisResult) >= _count)//当一分钟内的请求次数大于设置的次数,则拦截
                    {
    
                        context.Result = new JsonResult( "请求过于频繁!");
                    }
                    else
                        await RedisHelper.IncrByAsync(RateLimiterKey, 1);
                }
                else
                {
    
                    //1分钟内限制count次请求
                    await RedisHelper.SetAsync(RateLimiterKey, 1, new TimeSpan(0, 0, 60));
    
                }
    
            }
    
        }

    5-在WebApi中设置该特性

    我们既可以放在某个Controller维度,也可以放在方法(Action)维度,下面的案例是放在Controller维度,下面的参数3表示一分钟内接口只能请求3次。

    [ApiController]
        [Route("[controller]")]
        [RateLimitingAttirbute(3)]
        public class WeatherForecastController : ControllerBase
        {
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
     
            private readonly ILogger<WeatherForecastController> _logger;
    
            public WeatherForecastController(ILogger<WeatherForecastController> logger)
            {
                _logger = logger;
            }
    
            [HttpGet]
            public IEnumerable<WeatherForecast> Get()
            {
                var rng = new Random();
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                })
                .ToArray();
            }
        }

    6-运行项目,请求接口

    http://localhost:53439/weatherforecast,开始是可以返回正常结果,是一个集合的值,连续请求多次,当超过3次时,会返回“请求过于频繁”

    更多分享请关注我的公众号

  • 相关阅读:
    iscroll中使用input框的话是导致无法选中input框
    JS中setInterval()和clearInterval()的使用以及注意事项
    连接oracle出现的问题以及解决办法
    Oracle数据库数据显示乱码问题解决方法。
    Android4.4以上Uri转换成绝对路径的工具类
    安卓,调用相机并适配6.0后
    问题-解决
    ORACLE相关
    PL/SQL表结构/数据的导出
    springMVC笔记
  • 原文地址:https://www.cnblogs.com/wangoublog/p/15330415.html
Copyright © 2020-2023  润新知