SpringAMQP errorHandler 和 returnExceptions 问题
SpringAMQP errorHandler and returnExceptions problem
我不确定我对 errorHandler 和 returnExceptions 的理解是否正确。
但这是我的目标:我从 App_A 发送消息,使用 @RabbitListener 在 App_B 接收消息。
我假设如果APP_B在处理消息的过程中有业务异常,通过在@RabbitListener上以正确的方式设置errorHandler和return异常可以让异常返回到App_A .
我理解的对吗?
如果我是正确的,如何正确使用它?
使用我的代码,我在 APP_A 中什么也得不到。
这是我在 APP_B
中的代码
错误处理程序:
@Component(value = "errorHandler")
public class ErrorHandler implements RabbitListenerErrorHandler {
@Override
public Object handleError(Message arg0, org.springframework.messaging.Message<?> arg1,
ListenerExecutionFailedException arg2) throws ListenerExecutionFailedException {
throw new ListenerExecutionFailedException("msg", arg2, null);
}
}
兔子监听器:
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "MRO.updateBaseInfo.queue", durable = "true"),
exchange = @Exchange(name = "MRO_Exchange", type = ExchangeTypes.DIRECT, durable = "true"),
key = "baseInfoUpdate"
),
// errorHandler = "errorHandler",
returnExceptions = "true"
)
public void receiveLocationChangeMessage(String message){
BaseUpdateMessage newBaseInfo = JSON.parseObject(message, BaseUpdateMessage.class);
dao.upDateBaseInfo(newBaseInfo);
}
和 APP_A
中的代码
@Component
public class MessageSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void editBaseInfo(BaseUpdateMessage message)throws Exception {
//and i am not sure set RemoteInvocationAwareMessageConverterAdapter in this way is right
rabbitTemplate.setMessageConverter(new RemoteInvocationAwareMessageConverterAdapter());
rabbitTemplate.convertAndSend("MRO_Exchange", "baseInfoUpdate", JSON.toJSONString(message));
}
}
我很迷惑三点:
1)我必须同时使用 errorHandler 和 returnExceptions 吗?我认为 errorHandler 类似于后处理器,可以让我自定义 exception.if 我不需要自定义异常我可以只设置 return 没有 errorHandler 的异常吗?
2)用@RabbitListener注解的方法return something 还是 void 就好了?
3)在发送端(我的情况是APP_A),有没有具体的配置来捕获异常?
我的工作环境:
Spring 启动 2.1.0
docker
上的 rabbitMQ 服务器 3.7.8
1) 不,你不需要错误处理程序,除非你想增强异常。
2) 如果方法returns无效;发件人最终将等待超时等待永远不会到达的答复,以防万一可能抛出异常;这可能不是对资源的良好利用。最好总是发送回复,以释放发布方。
3) 只是 RemoteInvocationAwareMessageConverterAdapter
.
这是一个例子:
@SpringBootApplication
public class So53846303Application {
public static void main(String[] args) {
SpringApplication.run(So53846303Application.class, args);
}
@RabbitListener(queues = "foo", returnExceptions = "true")
public String listen(String in) {
throw new RuntimeException("foo");
}
@Bean
public ApplicationRunner runner(RabbitTemplate template) {
template.setMessageConverter(new RemoteInvocationAwareMessageConverterAdapter());
return args -> {
try {
template.convertSendAndReceive("foo", "bar");
}
catch (Exception e) {
e.printStackTrace();
}
};
}
}
和
org.springframework.amqp.AmqpRemoteException: java.lang.RuntimeException: foo
at org.springframework.amqp.support.converter.RemoteInvocationAwareMessageConverterAdapter.fromMessage(RemoteInvocationAwareMessageConverterAdapter.java:74)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertSendAndReceive(RabbitTemplate.java:1500)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertSendAndReceive(RabbitTemplate.java:1433)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertSendAndReceive(RabbitTemplate.java:1425)
at com.example.So53846303Application.lambda[=11=](So53846303Application.java:28)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:794)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:324)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.example.So53846303Application.main(So53846303Application.java:15)
Caused by: java.lang.RuntimeException: foo
at com.example.So53846303Application.listen(So53846303Application.java:20)
如您所见,有一个本地 org.springframework.amqp.AmqpRemoteException
原因是远程服务器上抛出的实际异常。
我不确定我对 errorHandler 和 returnExceptions 的理解是否正确。
但这是我的目标:我从 App_A 发送消息,使用 @RabbitListener 在 App_B 接收消息。
我假设如果APP_B在处理消息的过程中有业务异常,通过在@RabbitListener上以正确的方式设置errorHandler和return异常可以让异常返回到App_A .
我理解的对吗?
如果我是正确的,如何正确使用它?
使用我的代码,我在 APP_A 中什么也得不到。
这是我在 APP_B
中的代码错误处理程序:
@Component(value = "errorHandler")
public class ErrorHandler implements RabbitListenerErrorHandler {
@Override
public Object handleError(Message arg0, org.springframework.messaging.Message<?> arg1,
ListenerExecutionFailedException arg2) throws ListenerExecutionFailedException {
throw new ListenerExecutionFailedException("msg", arg2, null);
}
}
兔子监听器:
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "MRO.updateBaseInfo.queue", durable = "true"),
exchange = @Exchange(name = "MRO_Exchange", type = ExchangeTypes.DIRECT, durable = "true"),
key = "baseInfoUpdate"
),
// errorHandler = "errorHandler",
returnExceptions = "true"
)
public void receiveLocationChangeMessage(String message){
BaseUpdateMessage newBaseInfo = JSON.parseObject(message, BaseUpdateMessage.class);
dao.upDateBaseInfo(newBaseInfo);
}
和 APP_A
中的代码@Component
public class MessageSender {
@Autowired
private RabbitTemplate rabbitTemplate;
public void editBaseInfo(BaseUpdateMessage message)throws Exception {
//and i am not sure set RemoteInvocationAwareMessageConverterAdapter in this way is right
rabbitTemplate.setMessageConverter(new RemoteInvocationAwareMessageConverterAdapter());
rabbitTemplate.convertAndSend("MRO_Exchange", "baseInfoUpdate", JSON.toJSONString(message));
}
}
我很迷惑三点:
1)我必须同时使用 errorHandler 和 returnExceptions 吗?我认为 errorHandler 类似于后处理器,可以让我自定义 exception.if 我不需要自定义异常我可以只设置 return 没有 errorHandler 的异常吗?
2)用@RabbitListener注解的方法return something 还是 void 就好了?
3)在发送端(我的情况是APP_A),有没有具体的配置来捕获异常?
我的工作环境:
Spring 启动 2.1.0
docker
上的 rabbitMQ 服务器 3.7.81) 不,你不需要错误处理程序,除非你想增强异常。
2) 如果方法returns无效;发件人最终将等待超时等待永远不会到达的答复,以防万一可能抛出异常;这可能不是对资源的良好利用。最好总是发送回复,以释放发布方。
3) 只是 RemoteInvocationAwareMessageConverterAdapter
.
这是一个例子:
@SpringBootApplication
public class So53846303Application {
public static void main(String[] args) {
SpringApplication.run(So53846303Application.class, args);
}
@RabbitListener(queues = "foo", returnExceptions = "true")
public String listen(String in) {
throw new RuntimeException("foo");
}
@Bean
public ApplicationRunner runner(RabbitTemplate template) {
template.setMessageConverter(new RemoteInvocationAwareMessageConverterAdapter());
return args -> {
try {
template.convertSendAndReceive("foo", "bar");
}
catch (Exception e) {
e.printStackTrace();
}
};
}
}
和
org.springframework.amqp.AmqpRemoteException: java.lang.RuntimeException: foo
at org.springframework.amqp.support.converter.RemoteInvocationAwareMessageConverterAdapter.fromMessage(RemoteInvocationAwareMessageConverterAdapter.java:74)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertSendAndReceive(RabbitTemplate.java:1500)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertSendAndReceive(RabbitTemplate.java:1433)
at org.springframework.amqp.rabbit.core.RabbitTemplate.convertSendAndReceive(RabbitTemplate.java:1425)
at com.example.So53846303Application.lambda[=11=](So53846303Application.java:28)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:804)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:794)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:324)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248)
at com.example.So53846303Application.main(So53846303Application.java:15)
Caused by: java.lang.RuntimeException: foo
at com.example.So53846303Application.listen(So53846303Application.java:20)
如您所见,有一个本地 org.springframework.amqp.AmqpRemoteException
原因是远程服务器上抛出的实际异常。