应用场景如下:
先进行短链接跳转(第一步),跳转后需要进行访问监控的记录(第二步)。
由于高并发情况不可能同时进行跳转和监控记录,所以需要异步调用。
先搞清楚消息队列和延迟队列的作用:
1. 消息队列:
用于解耦跳转逻辑与访问记录监控。所有请求首先进入消息队列,以便异步处理,实现更快的响应速度和系统扩展性。
2. 延迟队列:
用于处理拿不到锁的请求。避免线程阻塞,将无法立即处理的请求放入延迟队列,在稍后重新尝试获取所需资源。
考虑一个场景:某热点短链接正在修改分组,拿到了写锁后,大量访问请求同时过来,假设修改分组占用写锁较长时间。
再依次看以下几种方案:
(1)无消息队列,无延迟队列,跳转与监控不解耦
拿不到读锁的请求导致线程阻塞。Tomcat中的10个核心线程很快被占满,接着200个最大线程也都占满,超过200个线程就会放入无界阻塞队列,可能导致内存溢出(OOM)。
(2)有消息队列,无延迟队列,跳转监控解耦
监控数据被打包成消息,并投入消息队列。10个固定消费者线程处理请求。如果拿不到读锁,消费者线程会被阻塞,但只会影响这10个线程。其余消息会在消息队列中堆积,等锁释放后逐步消费。
(3)有消息队列,有延迟队列,跳转监控解耦
请求先进入消息队列。消费者线程尝试处理时,如果发现无法获得读锁,则将该请求放入延迟队列,并在适当的时间间隔后重试。这样,即使写锁被长时间占用,线程不会长时间阻塞,维护系统响应效率。延迟队列的使用保证了仅在资源可用时进行重试,减少不必要的阻塞和资源消耗。
这种组合保证消息处理与系统资源使用的高效协调,同时避免直接阻塞线程,增强了系统的稳定性和灵活性。
方案选择:
可根据项目实际情况在方案(2)和(3)中进行选择,有时仅需方案(2)即可,不太影响实际使用的同时也简化了代码。