我已经创建了一个简单的例子来了解重试和建议。以下是示例配置:
@Configuration
@EnableIntegration
@IntegrationComponentScan
@ComponentScan
public class SimpleConfiguration2 {
@Bean
public DirectChannel requestChannel() {
return new DirectChannel();
}
@Bean
public DirectChannel aChannel() {
return new DirectChannel();
}
@Bean
public DirectChannel retryLaterChannel() {
return new DirectChannel();
}
@Bean
public DirectChannel tapChannel() {
return new DirectChannel();
}
@Bean
public DirectChannel endChannel() {
return new DirectChannel();
}
@Bean
public ExceptionThrowingTransformer exceptionThrowingTransformer() {
return new ExceptionThrowingTransformer();
}
@Bean
public IntegrationFlow initFlow() {
return IntegrationFlows.from(requestChannel())
.gateway(aChannel(), e -> e.advice(retryAdvice())
.errorChannel(retryLaterChannel()))
.get();
}
@Bean
public Advice retryAdvice() {
final RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice();
advice.setRetryTemplate(retryTemplate());
return advice;
}
@Bean
public RetryTemplate retryTemplate() {
final RetryTemplate ret = new RetryTemplate();
ret.setRetryPolicy(retryPolicy());
ret.setThrowLastExceptionOnExhausted(false);
return ret;
}
@Bean
public RetryPolicy retryPolicy() {
final Map<Class<? extends Throwable>, Boolean> map = new HashMap<Class<? extends Throwable>, Boolean>() {{
put(RuntimeException.class, true);
}
private static final long serialVersionUID = -1L;
};
final RetryPolicy ret = new SimpleRetryPolicy(3, map, true);
return ret;
}
@Bean
public IntegrationFlow aChannelFlow() {
return IntegrationFlows.from(aChannel())
.transform("C: "::concat)
.transform(exceptionThrowingTransformer())
.channel(endChannel())
.get();
}
@Bean
public IntegrationFlow endFlow() {
return IntegrationFlows.from(endChannel())
.handle(String.class, (p, h) -> p)
.get();
}
@Bean
public IntegrationFlow retryLaterFlow() {
return IntegrationFlows.from(retryLaterChannel())
.wireTap(tapChannel())
// .bridge(null)
// .handle(String.class, (p, h) -> p)
.get();
}
@Bean
public IntegrationFlow tapFlow() {
return IntegrationFlows.from(tapChannel())
.handle(m -> System.err.println("tap [" + Thread.currentThread().getName() + "] " + m.getPayload() ))
.get();
}
}
这里是ExceptionThrowingTransformer:
public class ExceptionThrowingTransformer implements GenericTransformer<String, String> {
@Override
public String transform(final String source) {
printAndThrow();
return Thread.currentThread().getName() + " " + source;
}
private void printAndThrow() {
if(numFail > 0) {
numFail--;
final String msg = numFail > 0 ? " will fail " + numFail + " more times"
: "last failure";
System.out.println(Thread.currentThread().getName() + " ExceptionThrowingTransformer " + msg);
throw new RuntimeException();
}
}
private static int numFail = 2;
}
以下是单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SimpleConfiguration2.class)
public class DependenciesApplicationTests {
@Test
public void t1() {
System.out.println(gw.echo("MSG1"));
}
@Autowired
private EchoGateway gw;
}
和echo网关:
@MessagingGateway(defaultReplyTimeout=600)
public interface EchoGateway {
@Gateway(requestChannel = "requestChannel")
String echo(String message);
}
问题1: 如果我按原样运行代码,输入&#34; MSG1&#34;放在requestChannel上,我得到以下输出:
main ExceptionThrowingTransformer will fail 1 more times
tap [main] org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException
main ExceptionThrowingTransformer last failure
tap [main] org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException
main C: MSG1
虽然我希望看到类似的东西:
main ExceptionThrowingTransformer will fail 1 more times
main ExceptionThrowingTransformer last failure
main C: MSG1
重试发生,但原始异常仍然传播到initFlow网关中指定的errorChannel。有没有办法防止这种情况?
问题2: 当numFail更改为3时,除问题1中的输出外,还会向调用者返回异常:
org.springframework.messaging.MessagingException: failure occurred in error-handling flow; nested exception is org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:-1.retryLaterChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
如果仅取消注释retryLaterFlow中的第一个注释,则将exceptionThrowingTransformer抛出的异常返回给调用者。 为什么这样,假设retryTemplate有setThrowLastExceptionOnExhausted(false)?
问题3: 如果仅取消注释retryLaterFlow中的第二个注释,则输出如下所示:
main ExceptionThrowingTransformer will fail 2 more times
tap [main] org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException
org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException
为什么重试没有生效? (对问题1的回答也可以回答这个问题)
答案 0 :(得分:0)
你有两个网关(初始和中间流),你建议中流网关,以便它按预期工作。
您应该建议变压器获得您期望的结果。