版本说明
本文源码分析基于 Redisson 3.24.3,文中 Lua 脚本与结论均以该版本为准;涉及历史行为对比时另行标注版本号。
核心设计
Redisson 的 RRateLimiter 采用"发放记账、到期回收"的滑动窗口模型,状态拆成三个 Redis 结构(以 key 为 mykey、60 秒放行 1 次、OVERALL 模式为例):
版本说明
本文源码分析基于 Redisson 3.24.3,文中 Lua 脚本与结论均以该版本为准;涉及历史行为对比时另行标注版本号。
Redisson 的 RRateLimiter 采用"发放记账、到期回收"的滑动窗口模型,状态拆成三个 Redis 结构(以 key 为 mykey、60 秒放行 1 次、OVERALL 模式为例):
在线支付业务中,经常会遇到掉单问题:用户已完成支付,但订单状态仍显示"待付款"。通常,用户支付完成后,第三方支付平台会通过梯度通知机制向商户同步支付结果。然而,若支付平台因网络波动、系统故障等原因导致通知失败,就需要引入补偿机制——比如:通过定时任务每隔一段时间主动查询特定时段内的待支付订单,批量发送至第三方支付平台查询支付结果,并同步更新系统订单状态,通知下游服务。为了高效处理这类订单,通常会借助线程池实现并发处理。
Q:定时任务多久查一次?
A:假设用户通常在5分钟内完成支付,那么定时任务每隔5分钟查询一次。
Q:每次查询的时间跨度是多少?
A:查一天前到5分钟前待支付的订单。
Q:每次查询出的待支付订单期望多久时间处理完?
A:每批订单期望1分钟内处理完。
Q:平时和大促期间,单位时间内大约发生多少次掉单情况?
A:平时每5分钟大约掉单1200次,大促期间每5分钟大约5000次。
在 Java 服务端开发中,线程池几乎无处不在。
异步任务、接口聚合、批量处理、消息消费、第三方 RPC...只要一个任务不希望直接占用当前线程太久,我们往往都会想到线程池。
而线程池最让人头疼的问题之一,就是:
corePoolSize 到底应该设置多少?
maximumPoolSize 设置多少合适?
queueCapacity 到底应该设置 10、50,还是 1000?
现代操作系统在运行一个程序时,会为其创建一个进程。例如,启动一个 Java 程序,操作系统就会创建一个 Java 进程。线程也叫轻量级进程(light Weight Process),是现代操作系统调度的最小单元。在一个进程里可以创建多个线程,处理器在这些线程上高速切换,让使用者感觉到这些线程是在同时执行。
使用多线程技术,将计算逻辑分配到多个处理器核心上,就会显著减少程序的处理时间,并且随着更多处理器核心的加入而变得更有效率。