异步@RabbitListener 中的同步代码?
Synchronous code in the asynchronous @RabbitListener?
从 RabbitMQ 文档中,使用 @RabbitListener
端点异步接收消息:
"The easiest way to receive a message asynchronously is to use the annotated listener endpoint infrastructure. In a nutshell, it allows you to expose a method of a managed bean as a Rabbit listener endpoint."
@RabbitListener(queues = "myQueue")
public void processOrder(String data) {
...
}
这里的异步接收到底是什么意思?使用阻塞调用的效果是什么,例如给定 receiving asynchronously
的定义,上面 processOrder(...)
函数内部的同步 HTTP?
这里异步的意思是你不直接调用那个方法,而是一些后台服务会在某个时刻调用它,这不受你的控制。在哪个线程上调用此方法取决于该服务的配置。通常此类服务使用线程池。
在异步方法中使用阻塞调用的效果是运行该方法的线程被阻塞,无法为其他异步调用提供服务。如果异步服务背后的线程池线程数有限,那么可能会出现所谓的"thread starvation",无法处理新的异步调用。否则,如果线程池是无限的,它可能会消耗所有可用内存,因为每个线程需要 0.5-1 MB 用于其调用堆栈。为了避免这样的负面后果,异步服务必须被构造成足够高的吞吐量来承受预期的负载,并且在负载很重的情况下,应该采取预防措施让服务优雅地降级,而不是让整个 JVM 崩溃 OOM。
从 RabbitMQ 文档中,使用 @RabbitListener
端点异步接收消息:
"The easiest way to receive a message asynchronously is to use the annotated listener endpoint infrastructure. In a nutshell, it allows you to expose a method of a managed bean as a Rabbit listener endpoint."
@RabbitListener(queues = "myQueue")
public void processOrder(String data) {
...
}
这里的异步接收到底是什么意思?使用阻塞调用的效果是什么,例如给定 receiving asynchronously
的定义,上面 processOrder(...)
函数内部的同步 HTTP?
这里异步的意思是你不直接调用那个方法,而是一些后台服务会在某个时刻调用它,这不受你的控制。在哪个线程上调用此方法取决于该服务的配置。通常此类服务使用线程池。
在异步方法中使用阻塞调用的效果是运行该方法的线程被阻塞,无法为其他异步调用提供服务。如果异步服务背后的线程池线程数有限,那么可能会出现所谓的"thread starvation",无法处理新的异步调用。否则,如果线程池是无限的,它可能会消耗所有可用内存,因为每个线程需要 0.5-1 MB 用于其调用堆栈。为了避免这样的负面后果,异步服务必须被构造成足够高的吞吐量来承受预期的负载,并且在负载很重的情况下,应该采取预防措施让服务优雅地降级,而不是让整个 JVM 崩溃 OOM。