简体   繁体   English

重试特性中的Rabbit监听器与Rabbit模板

[英]Rabbit listener vs Rabbit template in retry properites

We are doing retry operation for business exception and storing message after some attempts by using MessageRecoverer , so we had the first configuration in XML for retries like max attempt and interval, etc. so after refereed common properties for retry in this link https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html#%20RABBIT now changed to the properties file 我们正在做一些尝试通过使用MessageRecoverer后重试业务异常操作和存储信息,所以我们不得不在XML第一构像最大的尝试和间隔等这样吹罚后重试公共属性在这个环节上试https://开头docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html#%20RABBIT现在更改为属性文件

spring.rabbitmq.listener it asynchronous and it had a lot of features like stateless and concurrency spring.rabbitmq.listener异步,它具有很多功能,例如无状态和并发

spring.rabbitmq.template its synchronous spring.rabbitmq.template其同步

But both are doing the same operation except asynchronous and synchronous one more question. 但是除了异步和同步这两个问题,它们都在执行相同的操作。 Kindly correct me if I am wrong and which one have the more efficient way like in performance. 如果我做错了,请纠正我,哪一个有更有效的表现方式。

updated post 更新的帖子

if we are getting exception based on retry has to perform like 如果我们基于重试而获得异常,则必须执行如下操作

1) if business exception occurs retry for 3 times 1)如果发生业务异常,请重试3次

2) if runtime exception** occurs retry for 1 time 2)如果发生运行时异常**,请重试1次

3) Then have to recover by messagerecover and store exception 3)然后必须通过messagerecover进行恢复并存储异常

main class 主班

public class Main {
        @SuppressWarnings("resource")
    public static void main(String[] args) {
        new ClassPathXmlApplicationContext("/applicationContext.xml");
    }
}

xml XML文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:rabbit="http://www.springframework.org/schema/rabbit"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
       http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.6.xsd">

    <!-- Spring configuration -->

    <context:component-scan base-package="com.spring.rabbit.first.*" />
    <context:mbean-export default-domain="com.spring.rabbit.first.deadletter" />

    <!-- RabbitMQ common configuration -->

    <rabbit:connection-factory id="connectionFactory"
        username="guest" password="guest" port="5672" virtual-host="/" host="localhost" />


    <!-- <rabbit:connection-factory id="connectionFactory"/> -->
    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory" />
    <rabbit:admin connection-factory="connectionFactory" />

    <!-- Queues -->

    <!-- <rabbit:queue id="springQueue" name="spring.queue" -->
    <!-- auto-delete="true" durable="false" /> -->

    <rabbit:listener-container
        connection-factory="connectionFactory" advice-chain="retryAdvice">
        <rabbit:listener queues="BBBqueue" ref="messageListener" />
    </rabbit:listener-container>

    <rabbit:listener-container
        connection-factory="connectionFactory" advice-chain="retryAdvice">
        <rabbit:listener queues="DDDqueue" ref="messageListener" />
    </rabbit:listener-container>

    <bean id="messageListener" class="com.spring.rabbit.first.deadletter.MessageHandler" />

    <bean id="retryAdvice"
        class="org.springframework.amqp.rabbit.config.StatelessRetryOperationsInterceptorFactoryBean">
        <property name="messageRecoverer" ref="rejectAndDontRequeueRecoverer" />
        <property name="retryOperations" ref="retrytest" />
    </bean>

    <bean id="rejectAndDontRequeueRecoverer"
        class="com.spring.rabbit.first.deadletter.AutoConfiguringRepublishMessageRecoverer" />
    <!-- <constructor-arg ref="amqpTemplate" </constructor-arg> -->
    <!-- <constructor-arg name="errorTemplate" value="test"</constructor-arg> -->
    <!-- </bean> -->


    <!-- <bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate"> 
        <property name="backOffPolicy"> -->
    <!-- <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy"> -->
    <!-- <property name="initialInterval" value="2000" /> -->
    <!-- <property name="multiplier" value="10.0" /> -->
    <!-- <property name="maxInterval" value="30000" /> -->
    <!-- </bean> -->
    <!-- </property> -->
    <!-- <property name="retryPolicy"> -->
    <!-- <bean class="org.springframework.retry.policy.SimpleRetryPolicy"> -->
    <!-- <property name="retry" value="retrytest" /> -->
    <!-- </bean> -->
    <!-- </property> <property name="retryPolicy" ref="retrytest"></property> 
        </bean> -->

    <bean id="retrytest" class="com.spring.rabbit.first.retry.RetryOperationTest" />


    <rabbit:topic-exchange name="AAAqexchnage">
        <rabbit:bindings>
            <rabbit:binding queue="BBBqueue" pattern="" />
        </rabbit:bindings>
    </rabbit:topic-exchange>

    <rabbit:queue name="BBBqueue"></rabbit:queue>

    <rabbit:topic-exchange name="CCCexchange">
        <rabbit:bindings>
            <rabbit:binding queue="DDDqueue" pattern="" />
        </rabbit:bindings>
    </rabbit:topic-exchange>

    <rabbit:queue name="DDDqueue"></rabbit:queue>

</beans>

message handler 消息处理程序

public class MessageHandler implements MessageListener {

    @Override
    public void onMessage(Message message) {

        System.out.println("Received message: " + message);
        System.out.println("Text: " + new String(message.getBody()));


        if(message!=null)
        {
        message = null;
        if (message == null) {
            throw new NullPointerException();
        }
        }


    }
}




@Configuration
public class RetryOperationTest {

     @Bean
      public RetryTemplate retryTemplate() {
        final RetryTemplate ret = new RetryTemplate();
        ret.setRetryPolicy(retryPolicy());
        return ret;
      }

      @Bean
      public RetryPolicy retryPolicy() {
        final Map<Class<? extends Throwable>, Boolean> map = new HashMap<Class<? extends Throwable>, Boolean>() {{
            put(RuntimeException.class, true);
          }
        };
        final RetryPolicy ret = new SimpleRetryPolicy(1, map, true);
        return ret;
      }

}

am getting error after debug like 调试后出现错误

00:33:41.233 [main] WARN org.springframework.context.support.ClassPathXmlApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer#0': Cannot resolve reference to bean 'retryAdvice' while setting bean property 'adviceChain'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'retryAdvice' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type [com.spring.rabbit.first.retry.RetryOperationTest$$EnhancerBySpringCGLIB$$649b8c8] to required type [org.springframework.retry.RetryOperations] for property 'retryOperations'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [com.spring.rabbit.first.retry.RetryOperationTest$$EnhancerBySpringCGLIB$$649b8c8] to required type [org.springframework.retry.RetryOperations] for property 'retryOperations': no matching editors or conversion strategy found

Your question is not clear. 您的问题不清楚。

But both are doing the same operation except asynchronous and synchronous 但是除了异步和同步之外,两者都执行相同的操作

That is not true; 那是不对的。 the listener can only receive messages (message-driven), the template can send or receive (poll for) messages. 侦听器只能接收消息(消息驱动),模板可以发送或接收(轮询)消息。

When receiving, message-driven is generally more efficient; 接收时,消息驱动通常更有效; polling would typically only be used for on-demand message-reception. 轮询通常仅用于按需接收消息。

For more sophistication with retry (such as customizing the message recoverer, configuring the RetryTemplate to have conditional retries based on the exception types, you need to define the beans ( RabbitTemplate , SimpleRabbitListenerContainerFactory yourself rather than using Spring Boot's default beans. 要使重试更加复杂(例如自定义消息恢复器,将RetryTemplate配置为基于异常类型进行条件重试,您需要自己定义Bean( RabbitTemplateSimpleRabbitListenerContainerFactory而不是使用Spring Boot的默认Bean。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM