Java 如何做限流
我们在刷短视频的时候,是不是经常碰到“操作太频繁,请稍后再试”的提示?点外卖抢优惠券时,就算手速再快,同一时间也只有几个人能抢到——这些都是“限流”在背后起作用。简单说,限流就是给系统设个“客流量上限”,防止太多请求把系统压垮。那Java作为常用的开发语言,怎么实现这个实用功能呢?
最省心的工具:用开源组件直接用
不用自己从零写代码,直接用现成的开源组件是最省事的方式,适合大部分中小项目。这里推荐两个大家用得最多的:

第一个是Google的Guava工具包,里面有个叫RateLimiter的类,就像给系统配了个“水龙头”,能精准控制每秒通过的请求数。比如做电商的秒杀活动,想控制每秒最多100个请求,只要写几行代码就行:先引入Guava的依赖,再创建一个每秒允许100个请求的RateLimiter对象,每次处理请求前,调用acquire()方法“占位置”,如果拿到了就继续处理,拿不到就拒绝或者排队。就像奶茶店做活动,老板规定每秒只能做100杯,前100个顾客能下单,后面的要么等要么换时间,不用自己算时间,工具会自动搞定。
另一个常用的是阿里的Sentinel,它功能更全,除了限流还能管熔断、降级,适合大一点的项目。比如做外卖平台的订单系统,既能设每秒最多500个普通订单的上限,还能给会员订单开“绿色通道”,不占用普通订单的额度,相当于餐厅给会员设专属窗口,普通顾客走普通窗口,两边都不耽误。
自己写简单逻辑:适合小场景
如果项目很小,不想加额外的依赖,也能自己写个简单的限流逻辑。比如用计数器,就像小区的门禁,门口的保安数着“每秒最多进5个人”:定义一个变量存当前秒的请求数,再存一个记录当前时间的变量。每次来请求时,先对比现在的时间和之前的时间,如果已经过了1秒,就把计数器清零,更新时间;如果没到1秒,就看看计数器有没有超过上限,没超过就加1处理请求,超过了就返回“太频繁”的提示。
还有更简单的时间窗口法,比如把1分钟分成60个1秒的小格子,每个格子记请求数,只要任何一个格子的请求数没到上限,就处理,到了就拒绝。就像图书馆的自习室,1分钟最多进60个人,每1秒的格子里最多1个,只要某一秒的格子没满,就能进去,不用等整分钟结束。
注意别踩这些小坑
用Java做限流的时候,有几个细节得留意。比如如果是分布式系统,就是有好多个服务器一起干活的情况,刚才说的Guava计数器只管单个服务器,要是用户同时连了好几个服务器,总请求数可能还是超了。这时候得把限流的计数存在公共的地方,比如Redis里,所有服务器都从这拿数,相当于小区多个出入口的保安共用一个计数器,总人数不会超。
还有,限流的规则别写死,比如做促销活动时,本来每秒最多100个请求,突然订单量涨了,得能随时改成200个,不然可能错过销售机会。就像餐厅本来每秒做50杯奶茶,活动时临时改成100杯,得能快速调整规则。
总的来说,Java实现限流不用复杂的操作,要么用现成的工具省心,要么自己写简单逻辑够用,分布式场景就加个公共存储,根据项目大小选合适的方式,就能轻松防止系统被“挤爆”啦。