Spring Integration JMS使用DSL确保消息传递

时间:2018-06-26 13:31:21

标签: spring-integration spring-jms spring-integration-dsl

我正在尝试创建流(1),其中从TCP适配器(可以是客户端或服务器)接收消息,并将其发送到ActiveMQ代理。

我的另一个流程(2)从所需的队列中选择消息并发送到目的地

TCP(客户端/服务器)==(1)==> ActiveMQ Broker ==(2)==> HTTP出站适配器

我想确保万一我的邮件没有传递到所需的目的地,那么它会再次尝试再次发送邮件。

我目前流向经纪人的流量(1)是:

IntegrationFlow flow = IntegrationFlows
            .from(Tcp
                    .inboundAdapter(Tcp.netServer(Integer.parseInt(1234))
                            .serializer(customSerializer).deserializer(customSerializer)
                            .id("server").soTimeout(5000))
                    .id(hostConnection.getConnectionNumber() + "adapter"))).channel(directChannel())
            .wireTap("tcpInboundMessageLogChannel").channel(directChannel())
            .handle(Jms.outboundAdapter(activeMQConnectionFactory)
                    .destination("jmsInbound"))
            .get();

    this.flowContext.registration(flow).id("outflow").register();

和我从经纪人到http出站的流量(2):

flow = IntegrationFlows
            .from(Jms.messageDrivenChannelAdapter(activeMQConnectionFactory)
                    .destination("jmsInbound"))
            .channel(directChannel())
            .handle(Http.outboundChannelAdapter(hostConnection.getUrl()).httpMethod(HttpMethod.POST)
                    .expectedResponseType(String.class)
                    .mappedRequestHeaders("abc"))
            .get();
    this.flowContext.registration(flow).id("inflow").register();

问题:

  • 如果在发送过程中发生任何异常,例如我的目标URL无法正常工作,则它会尝试发送消息。

  • 不成功的尝试后,它重试7次,即max attempt to 7

  • 如果尝试仍然失败,则会将消息发送到ActiveMQ.DLQ(死信队列),并且由于消息从实际队列中出队并发送到{{1},因此不会再次尝试}。

因此,我希望不会丢失任何消息并且按顺序处理消息的情况。

1 个答案:

答案 0 :(得分:0)

首先:我相信您可以为无限次重试配置jmsInbound

/**
 * Configuration options for a messageConsumer used to control how messages are re-delivered when they
 * are rolled back.
 * May be used server side on a per destination basis via the Broker RedeliveryPlugin
 *
 * @org.apache.xbean.XBean element="redeliveryPolicy"
 *
 */
public class RedeliveryPolicy extends DestinationMapEntry implements Cloneable, Serializable {

另一方面,您可以为.handle(Http.outboundChannelAdapter(配置一个RequestHandlerRetryAdvice,以获得类似的重试行为,但是在应用程序内部无需往返JMS和返回:https://docs.spring.io/spring-integration/docs/5.0.6.RELEASE/reference/html/messaging-endpoints-chapter.html#retry-advice

以下是一些示例,可以从Java DSL角度配置它:

    @Bean
    public IntegrationFlow errorRecovererFlow() {
        return IntegrationFlows.from(Function.class, "errorRecovererFunction")
                .handle((GenericHandler<?>) (p, h) -> {
                    throw new RuntimeException("intentional");
                }, e -> e.advice(retryAdvice()))
                .get();
    }

    @Bean
    public RequestHandlerRetryAdvice retryAdvice() {
        RequestHandlerRetryAdvice requestHandlerRetryAdvice = new RequestHandlerRetryAdvice();
        requestHandlerRetryAdvice.setRecoveryCallback(new ErrorMessageSendingRecoverer(recoveryChannel()));
        return requestHandlerRetryAdvice;
    }

    @Bean
    public MessageChannel recoveryChannel() {
        return new DirectChannel();
    }

可以将RequestHandlerRetryAdviceRetryTemplate配置为应用AlwaysRetryPolicy之类的内容。有关更多信息,请参见Spring Retry项目:https://github.com/spring-projects/spring-retry