分布式接口幂等性、分布式限流(Guava

}

//同步阻塞限流

@GetMapping(“/acquire”)

public String acquire(Integer count){

limiter.acquire(count);

log.info(“成功,允许通过,速率为{}”,limiter.getRate());

return “success”;

}

}

2)基于Nginx的限流

============

1.iP限流

1.编写Controller

@RestController

@Slf4j

public class Controller{

//nginx测试使用

@GetMapping(“/nginx”)

public String nginx(){

log.info(“Nginx success”);

}

}

2.修改host文件,添加一个网址域名

127.0.0.1 www.test.com

3.修改nginx,将步骤2中的域名,添加到路由规则当中

打开nginx的配置文件

vim /usr/local/nginx/conf/nginx.conf

添加一个服务

#根据IP地址限制速度

#1)$binary_remote_addr binary_目的是缩写内存占用,remote_addr表示通过IP地址来限流

#2)zone=iplimit:20m iplimit是一块内存区域(记录访问频率信息),20m是指这块内存区域的大小

#3)rate=1r/s 每秒放行1个请求

limit_req_zone $binary_remote_addr zone=iplimit:20m rate=1r/s;

server{

server_name www.test.com;

location /access-limit/ {

proxy_pass http://127.0.0.1:8080/;

#基于ip地址的限制

#1)zone=iplimit 引用limit_rep_zone中的zone变量

#2)burst=2 设置一个大小为2的缓冲区域,当大量请求到来,请求数量超过限流频率时,将其放入缓冲区域

#3)nodelay 缓冲区满了以后,直接返回503异常

limit_req zone=iplimit burst=2 nodelay;

}

}

4.访问地址,测试是否限流

www.test.com/access-limit/nginx

2.多维度限流

1.修改nginx配置

#根据IP地址限制速度

limit_req_zone $binary_remote_addr zone=iplimit:20m rate=10r/s;

#根据服务器级别做限流

limit_req_zone $server_name zone=serverlimit:10m rate=1r/s;

#根据ip地址的链接数量做限流

limit_conn_zone $binary_remote_addr zone=perip:20m;

#根据服务器的连接数做限流

limit_conn_zone $server_name zone=perserver:20m;

server{

server_name www.test.com;

location /access-limit/ {

proxy_pass http://127.0.0.1:8080/;

#基于ip地址的限制

limit_req zone=iplimit burst=2 nodelay;

#基于服务器级别做限流

limit_req zone=serverlimit burst=2 nodelay;

#基于ip地址的链接数量做限流 最多保持100个链接

limit_conn zone=perip 100;

#基于服务器的连接数做限流 最多保持100个链接

limit_conn zone=perserver 1;

#配置request的异常返回504(默认为503)

limit_req_status 504;

limit_conn_status 504;

}

location /download/ {

#前100m不限制速度

limit_rate_affer 100m;

#限制速度为256k

limit_rate 256k;

}

}

3)基于Redis+Lua的分布式限流

===================

1.Lua脚本

Lua是一个很小巧精致的语言,它的诞生(1993年)甚至比JDK 1.0还要早。Lua是由标准的C语言编写的,它的源码部分不过2万多行C代码,甚至一个完整的Lua解释器也就200k的大小。

Lua往大了说是一个新的编程语言,往小了说就是一个脚本语言。对于有编程经验的同学,拿到一个Lua脚本大体上就能把业务逻辑猜的八九不离十了。

Redis内置了Lua解释器,执行过程保证原子性

2.Lua安装

安装Lua:

1.参考http://www.lua.org/ftp/教程,下载5.3.5_1版本,本地安装

如果你使用的是Mac,那建议用brew工具直接执行brew install lua就可以顺利安装,有关brew工具的安装可以参考https://brew.sh/网站,使用brew安装后的目录在/usr/local/Cellar/lua/5.3.5_1

2.安装IDEA插件,在IDEA->Preferences面板,Plugins,里面Browse repositories,在里面搜索lua,然后就选择同名插件lua。安装好后重启IDEA

3.配置Lua SDK的位置:IDEA->File->Project Structure,选择添加Lua,路径指向Lua SDK的bin文件夹

4.都配置好之后,在项目中右键创建Module,左侧栏选择lua,点下一步,选择lua的sdk,下一步,输入lua项目名,完成

3.编写hello lua

print ‘Hello Lua’

4.编写模拟限流

– 模拟限流

– 用作限流的key

local key = ‘my key’

– 限流的最大阈值

local limit = 2

– 当前限流大小

local currentLimit = 2

– 是否超过限流标准

if currentLimit + 1 > limit then

print ‘reject’

return false

else

print ‘accept’

return true

end

5.限流组件封装

1.添加maven

org.springframework.boot

spring-boot-starter-data-redis

org.springframework.boot

spring-boot-starter-aop

com.google.guava

guava

18.0

2.添加Spring配置

不是重要内容就随便写点,主要就是把reids配置一下

server.port=8080

spring.redis.database=0

spring.redis.host=localhost

spring.redis.port=6376

3.编写限流脚本

lua脚本放在resource目录下就可以了

– 获取方法签名特征

local methodKey = KEYS[1]

redis.log(redis.LOG_DEBUG,‘key is’,methodKey)

– 调用脚本传入的限流大小

local limit = tonumber(ARGV[1])

– 获取当前流量大小

local count = tonumber(redis.call(‘get’,methodKey) or “0”)

–是否超出限流值

if count + 1 >limit then

– 拒绝访问

return false

else

– 没有超过阈值

– 设置当前访问数量+1

redis.call(‘INCRBY’,methodKey,1)

– 设置过期时间

redis.call(‘EXPIRE’,methodKey,1)

– 放行

return true

end

4.使用spring-data-redis组件集成Lua和Redis

创建限流类

@Service

@Slf4j

public class AccessLimiter{

@Autowired

private StringRedisTemplate stringRedisTemplate;

@Autowired

private RedisScript rateLimitLua;

public void limitAccess(String key,Integer limit){

boolean acquired = stringRedisTemplate.execute(

rateLimitLua,//lua脚本的真身

Lists.newArrayList(key),//lua脚本中的key列表

limit.toString()//lua脚本的value列表

);

if(!acquired){

log.error(“Your access is blocked,key={}”,key);

throw new RuntimeException(“Your access is blocked”);

}

}

}

创建配置类

@Configuration
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

ActiveMQ消息中间件面试专题

  • 什么是ActiveMQ?
  • ActiveMQ服务器宕机怎么办?
  • 丢消息怎么办?
  • 持久化消息非常慢怎么办?
  • 消息的不均匀消费怎么办?
  • 死信队列怎么办?
  • ActiveMQ中的消息重发时间间隔和重发次数吗?

ActiveMQ消息中间件面试专题解析拓展:

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


redis面试专题及答案

  • 支持一致性哈希的客户端有哪些?
  • Redis与其他key-value存储有什么不同?
  • Redis的内存占用情况怎么样?
  • 都有哪些办法可以降低Redis的内存使用情况呢?
  • 查看Redis使用情况及状态信息用什么命令?
  • Redis的内存用完了会发生什么?
  • Redis是单线程的,如何提高多核CPU的利用率?

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


Spring面试专题及答案

  • 谈谈你对 Spring 的理解
  • Spring 有哪些优点?
  • Spring 中的设计模式
  • 怎样开启注解装配以及常用注解
  • 简单介绍下 Spring bean 的生命周期

Spring面试答案解析拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


高并发多线程面试专题

  • 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
  • Java 中 wait 和 sleep 方法有什么区别?
  • 如何在 Java 中实现一个阻塞队列?
  • 如何在 Java 中编写代码解决生产者消费者问题?
  • 写一段死锁代码。你在 Java 中如何解决死锁?

高并发多线程面试解析与拓展

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM


jvm面试专题与解析

  • JVM 由哪些部分组成?
  • JVM 内存划分?
  • Java 的内存模型?
  • 引用的分类?
  • GC什么时候开始?

JVM面试专题解析与拓展!

BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!
0)]


高并发多线程面试专题

  • 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
  • Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
  • Java 中 wait 和 sleep 方法有什么区别?
  • 如何在 Java 中实现一个阻塞队列?
  • 如何在 Java 中编写代码解决生产者消费者问题?
  • 写一段死锁代码。你在 Java 中如何解决死锁?

高并发多线程面试解析与拓展

[外链图片转存中…(img-4Ps90kDB-1711894252790)]


jvm面试专题与解析

  • JVM 由哪些部分组成?
  • JVM 内存划分?
  • Java 的内存模型?
  • 引用的分类?
  • GC什么时候开始?

JVM面试专题解析与拓展!

[外链图片转存中…(img-bF4cvKH5-1711894252790)]

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门即可获取!

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值