我使用
@MessagingGateway
是为了在 spring-mvc
@Controller
和 spring-integration
之间架起桥梁。 @MessagingGateway
声明如下所示:
package a.b.c;
import org.springframework.integration.annotation.*;
import org.springframework.stereotype.Component;
@MessagingGateway(name="inboundGateway" defaultRequestTimeout="2000"
defaultReplyTimeout="2000")
@Component
public interace InboundGateway {
@Gateway(requestChannel = "getSomething")
Message<SomeValue> getSomething(@Headers Map<String, Object> headers);
}
从控制器引用
@Controller
@RequestMapping("/some/base/path")
public class SomeController {
private final InboundGateway inboundGateway;
public SomeController(InboundGateway inboundGateway) {
this.inboundGateway = inboundGateway;
}
@GetMapping(value = "things", produces = { "application/json" })
public ResponseEntity<SomeValue> getSomething(RequestContext<String> requestContext) {
Message<SomeValue> response = inboundGateway.getSomething(requestContext);
....
}
我认为如果在指定时间内没有返回响应,
defaultRequestTimeout
和defaultReplyTimeout
的定义会在inboundGateway
处引发超时。
但是,我发现方法
getSomething()
中使用的时间可能超过指定时间,在本例中为 2 秒。看来这2秒是作为下游系统调用的超时时间,而不是作为getSomething()
返回的超时时间。
我的理解正确吗?是否有一些简单的、声明性的方法来管理
inboundGateway
级别的超时?任何指示表示赞赏。
您解释的行为对于您的
inboundGateway
是 DirectChannel
的流程来说是典型的。这样,消息处理就直接在生成该消息的线程上执行。因此,它无法到达 replyTimeout
获取结果,因为该线程被阻塞等待消息处理。
查看不同渠道的文档中的更多信息:https://docs.spring.io/spring-integration/reference/channel/implementations.html
另请参阅有关网关上的超时的文档:https://docs.spring.io/spring-integration/reference/gateway.html
作为满足您期望的简单解决方案,您可以考虑使用
QueueChnanel
来实现 inboundGateway
或 ExecutorChannel
。这样,处理将被移交给不同的线程,并且网关将能够轻松地转到答复等待块。这就是 replyTimeout
发挥作用的地方。
注释属性JavaDocs中也有解释:
/**
* Provides the amount of time dispatcher would wait to send a {@code Message}. This
* timeout would only apply if there is a potential to block in the send call. For
* example if this gateway is hooked up to a {@code QueueChannel}. Value is specified
* in milliseconds; it can be a simple long value or a SpEL expression; array variable
* #args is available.
* See {@link Gateway#requestTimeout()} for per-method configuration.
* @return the suggested timeout in milliseconds, if any
*/
String defaultRequestTimeout() default IntegrationContextUtils.DEFAULT_TIMEOUT_STRING;