我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Redis+AOP+自定义注解实现限流

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis+AOP+自定义注解实现限流

Redis安装

一提到Redis,相信大家都不会感到陌生吧。今天就让我们在阿里云上安装一下Redis,为以后使用它做个准备。

下载

1,下载页面

2,下载

解压

tar -xzvf redis-5.0.7.tar.gz

准备编译

1, 请在操作前确认gcc是否已安装,gcc -v

如未安装,可以执行这个命令安装:yum install gcc

2,请在操作前确认tcl是否已安装如未安装,可以执行这个命令安装:yum install tcl

编译

[root@localhost source]# cd redis-5.0.7/
[root@localhost redis-5.0.7]# make MALLOC=libc

make 后加 MALLOC的参数的原因:

避免提示找不到 jemalloc/jemalloc.h

测试编译

[root@localhost redis-5.0.7]# make test

如果看到以下字样:表示无错误:\o/ All tests passed without errors!

安装

[root@localhost redis-5.0.7]# mkdir /usr/local/soft/redis5 可分步创建
[root@localhost redis-5.0.7]# cd /usr/local/soft/redis5/
[root@localhost redis5]# mkdir bin
[root@localhost redis5]# mkdir conf
[root@localhost redis5]# cd bin/

find / -name redis-cli 查找文件位置

[root@localhost bin]# cp /root/redis-5.0.7/class="lazy" data-src/redis-cli ./
[root@localhost bin]# cp /root/redis-5.0.7/class="lazy" data-src/redis-server ./
[root@localhost bin]# cd …/conf/
[root@localhost conf]# cp /root/redis-5.0.7/redis.conf ./

配置

[root@localhost conf]# vi redis.conf

设置以下两个地方:

# daemonize no 
 daemonize yes  
# maxmemory <bytes>
maxmemory 128MB

说明:分别是以daemon方式独立运行 / 内存的最大使用限制

运行

[root@localhost conf]# /usr/local/soft/redis5/bin/redis-server /usr/local/soft/redis5/conf/redis.conf

检查端口是否在使用中

[root@localhost conf]# netstat -anp | grep 6379
​​​​​​​tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 16073/redis-server

查看redis的当前版本:

[root@localhost conf]# /usr/local/soft/redis5/bin/redis-server -v
​​​​​​​Redis server v=5.0.7 sha=00000000:0 malloc=libc bits=64 build=8e31d2ed9a4c9593

使redis可以用systemd方式启动和管理

1,编辑service文件

[root@localhost liuhongdi]# vim /lib/systemd/system/redis.service

2,service文件内容:

[Unit]Description=RedisAfter=network.target
[Service]Type=forkingPIDFile=/var/run/redis_6379.pidExecStart=/usr/local/soft/redis5/bin/redis-server /usr/local/soft/redis5/conf/redis.confExecReload=/bin/kill -s HUP $MAINPIDExecStop=/bin/kill -s QUIT $MAINPIDPrivateTmp=true
[Install]WantedBy=multi-user.target

3.重载系统服务

[root@localhost liuhongdi]# systemctl daemon-reload

4,用来管理redis

启动

systemctl start redis

查看状态

systemctl status redis

使开机启动

systemctl enable redis

查看本地centos的版本:

[root@localhost lib]# cat /etc/redhat-release
CentOS linux release 8.1.1911 (Core)

客户端连接redis

1、阿里云得设置redis.conf中的bind 后跟着的127.0.0.1修改为0.0.0.0,重启redis

2、开放端口:开放服务器的端口号,步骤如下:

打开实例列表,点击“ 更多”按钮,选择“ 网络和安全组 ”中的“安全组配置”,选择 “安全组列表”tab页面,点击 “配置规则”按钮,点击 “快速添加”按钮,勾选“Redis(6379)”,点击 “确定”之后就可以正常连接了。

3、给redis设置连接密码:

查找到# requirepass foobared 注释去掉并写入要设置的密码,例如:requirepass 123456

redis启动之后测试是否可以连接命令

./redis-cli -h 127.0.0.1 -p 6379
127.0.0.1:6379> auth 123456//此处是你的密码

注意: 如果是阿里云的话一定要设置密码,否则很可能被矿机程序注入定时任务,用你的服务器挖矿,阿里云一直会有信息提示你。

Redis限流

服务器上的Redis已经安装完成了(安装步骤见上文),今天就让我们使用Redis来做个小功能:自定义拦截器限制访问次数,也就是限流。

首先我们要在项目中引入Redis

1、引入依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

<!-- redis依赖commons-pool 这个依赖一定要添加 -->
<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-pool2</artifactId>
</dependency>

2、application.yml配置

server:
port: 8181

spring:
redis:
 host: 127.0.0.1
 port: 6379
 timeout: 10s
 lettuce:
  pool:
  # 连接池中的最小空闲连接 默认0
   min-idle: 0
   # 连接池中的最大空闲连接 默认8
   max-idle: 8
   # 连接池最大连接数 默认8 ,负数表示没有限制
   max-active: 8
   # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认-1
   max-wait: -1ms
 #选择哪个库存储,默认是0
 database: 0
 password: 123456

3、创建redisConfig,引入redisTemplate

@Configuration
public class RedisConfig {
 @Bean
 publicRedisTemplate<String, Object>redisTemplate(LettuceConnectionFactoryredisConnectionFactory) {
   RedisTemplate<String, Object>redisTemplate=newRedisTemplate<String, Object>();
   redisTemplate.setKeySerializer(newStringRedisSerializer());
   redisTemplate.setValueSerializer(newGenericJackson2jsonRedisSerializer());
   redisTemplate.setHashKeySerializer(newStringRedisSerializer());
   redisTemplate.setHashValueSerializer(newGenericJackson2JsonRedisSerializer());
   redisTemplate.setConnectionFactory(redisConnectionFactory);
   returnredisTemplate;
 }
}

自定义注解和拦截器

1、自定义注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface AccessLimit {
 intseconds(); //秒数
 intmaxCount(); //最大访问次数
 booleanneedLogin()default true;//是否需要登录
}

2、创建拦截器

@Component
public class FangshuaInterceptor extendsHandlerInterceptorAdapter{

 @Autowired
 privateRedisTemplateredisTemplate;

 @Override
 public booleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse, Objecthandler) throwsException{
   //判断请求是否属于方法的请求
   if(handlerinstanceofHandlerMethod){
     HandlerMethodhm=(HandlerMethod)handler;
     //获取方法中的注解,看是否有该注解
     AccessLimitaccessLimit=hm.getMethodAnnotation(AccessLimit.class);
     if(accessLimit==null){
       return true;
     }
     intseconds=accessLimit.seconds();
     intmaxCount=accessLimit.maxCount();
     booleanlogin=accessLimit.needLogin();
     Stringkey=request.getRequestURI();
     //如果需要登录
     if(login){
       //获取登录的session进行判断,此处只是例子,不写具体的业务
       //.....
       key+=""+"1"; //这里假设用户是1,项目中是动态获取的userId
     }

     //从redis中获取用户访问的次数
     Integercount;
     if(Objects.isNull(redisTemplate.opsForValue().get(key))){
       count=0;
     }else{
       count=(Integer)redisTemplate.opsForValue().get(key);
     }
     if(count==0){
       redisTemplate.opsForValue().set(key,1,seconds,TimeUnit.SECONDS);
     }else if(count<maxCount){
       //key的值加1
       redisTemplate.opsForValue().increment(key);
     }else{
       //超出访问次数
       Map<String,Object>errMap=newHashMap<>();
       errMap.put("code",400);
       errMap.put("msg","请求超时,请稍后再试");
       render(response,errMap); //这里的CodeMsg是一个返回参数
       return false;
     }
   }
   return true;
 }


 private voidrender(HttpServletResponseresponse,Map<String,Object>errMap) throwsException{
   response.setContentType("application/json;charset=UTF-8");
   OutputStreamout=response.getOutputStream();
   Stringstr=JSON.toJSONString(errMap);
   out.write(str.getBytes("UTF-8"));
   out.flush();
   out.close();
 }
}

3、将自定义拦截器加入到拦截器列表中

@Configuration
public class WebConfig extendsWebMvcConfigurerAdapter{

 @Autowired
 privateFangshuaInterceptorinterceptor;

 @Override
 public voidaddInterceptors(InterceptorRegistryregistry) {
   registry.addInterceptor(interceptor);
 }
}

最后做一下简单的测试

@RestController
@RequestMapping("test")
public class TestController {

 //每三十秒最多可以请求三次,不需要登录
 @AccessLimit(seconds=30,maxCount=3,needLogin=false)
 @PostMapping("/fangshua")
 public Stringfangshua(){
   return "成功";
 }
}

以上就是Redis+AOP+自定义注解实现限流的详细内容,更多关于Redis限流的资料请关注我们其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Redis+AOP+自定义注解实现限流

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis+AOP+自定义注解实现限流

目录Redis安装下载解压准备编译编译测试编译安装配置运行检查端口是否在使用中查看redis的当前版本:使redis可以用systemd方式启动和管理查看本地centos的版本:客户端连接redisRedis限流1、引入依赖2、applic
2022-06-28

Redis+AOP怎么自定义注解实现限流

今天小编给大家分享一下Redis+AOP怎么自定义注解实现限流的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。下载1,下载页面
2023-07-02

AOP Redis自定义注解实现细粒度接口IP访问限制

这篇文章主要为大家介绍了AOP Redis自定义注解实现细粒度接口IP访问限制,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

SpringBoot搭配AOP实现自定义注解

这篇文章主要为大家详细介绍了SpringBoot如何搭配AOP实现自定义注解,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
2022-12-09

使用Spring AOP 如何实现自定义注解

这期内容当中小编将会给大家带来有关使用Spring AOP 如何实现自定义注解,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1.在Maven中加入以下以依赖: