Spring Integration:如何根据其他服务的状态打开服务的断路器?

时间:2014-10-23 12:19:18

标签: spring-integration

我有一个类似于使用Spring Integration 4.0.4的应用程序中的流程:

Inbound --A--> Service 1 --B--> Service 2 --C--> Service 3 --D--> End service 4

服务3 可能会定期失败(这是预期的)。我在 Service 3 上使用RequestHandlerCircuitBreakerAdvice来处理此故障,并在一段时间后重试。但是,如果打开 Service 3 断路器,我需要阻止 Service 2 处理从通道B 收到的消息(某些上下文: Service 3 通过 Service 2 导入放入Amazon S3存储桶中的文件。如果 Service 3 关闭,则上传文件没有意义,因为这个操作不是免费的。)

到目前为止,我有一些想法:我会以与AbstractRequestHandlerAdvice类似的方式对RequestHandlerCircuitBreakerAdvice进行子类化,然后使用稍微修改后的doInvoke()版本来检查只有当前服务的状态( Service 2 ),还有 Service 3 的状态,然后打开 Service 2 如果 Service 3 处于失败状态。但是,如何识别哪个服务调用doInvoke()方法?区分是在target参数上进行的(因为这是存储在状态Map中的事物),但它是作为Object收到的。

target可以转换为AbstractReplyProducingMessageHandler.RequestHandler,但这对识别服务没有多大帮助。

问题

如何识别doInvoke()方法中正在检查的服务?有没有其他方法可以实现这样一个"同步断路器"特征?当消息发送到 Service 3 时,我正在考虑在消息头中添加特定标志,以便我知道target实际上是 Service 3 。 ..但是对于更聪明的解决方案的任何意见都将受到高度赞赏!

其他信息

我试着按照以下方式实施加里的答案:

<!-- Service bean definition -->
<bean id="service3Bean" class="com.me.Service3"/>

<!-- Circuit breaker advice -->
<bean id="circuitBreaker" class="com.me.Service3StateBasedCircuitBreaker">
    <property name="threshold" value="10" />
    <property name="halfOpenAfter" value="60000" />
    <property name="service3" ref="service3.handler" />
</bean> 

<int:chain input-channel="channelC" output-channel="channelD">
    <int:header-enricher>
        (...)
    </int:header-enricher>

    <!-- Transformer implementing Service 3 definition -->
    <int:transformer id="service3" ref="service3Bean" method="doSomething">
        <int:request-handler-advice-chain>
            <ref bean="circuitBreaker" />
        </int:request-handler-advice-chain>
    </int:transformer>
</int:chain>

这在运行时给出了No bean named 'service3.handler' is defined错误。也许是一个优先问题,但我无法发现它。谢谢你的帮助:)

1 个答案:

答案 0 :(得分:0)

子类可以工作 - 将相同的建议实例应用于两个服务(因此它们共享状态Map)。

将service3的处理程序注入您的建议(<property name="service3" ref="service3.handler" />) - 处理程序获得beanName.handler的别名。

然后在逻辑中,以及测试目标的状态,你也可以检查service3的状态(或者只测试service3)。

如果您以通用方式执行此操作(例如,允许注入Collection其他服务处理程序进行检查),我们很乐意考虑将此功能添加到框架中。

请参阅contributing guidelines