我正在尝试创建流(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},因此不会再次尝试}。
因此,我希望不会丢失任何消息并且按顺序处理消息的情况。
答案 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();
}
可以将RequestHandlerRetryAdvice
与RetryTemplate
配置为应用AlwaysRetryPolicy
之类的内容。有关更多信息,请参见Spring Retry项目:https://github.com/spring-projects/spring-retry