ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Redis限流

2021-09-24 15:05:33  阅读:197  来源: 互联网

标签:Redis rng Summaries 限流 new logger public


 

 

 

在电商开发过程中,我们很多地方需要做限流,有的是从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次时,会返回“请求过于频繁”

 

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

 

标签:Redis,rng,Summaries,限流,new,logger,public
来源: https://www.cnblogs.com/wangoublog/p/15330415.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有