我有一个类似于使用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
错误。也许是一个优先问题,但我无法发现它。谢谢你的帮助:)
答案 0 :(得分:0)
子类可以工作 - 将相同的建议实例应用于两个服务(因此它们共享状态Map
)。
将service3的处理程序注入您的建议(<property name="service3" ref="service3.handler" />
) - 处理程序获得beanName.handler
的别名。
然后在逻辑中,以及测试目标的状态,你也可以检查service3的状态(或者只测试service3)。
如果您以通用方式执行此操作(例如,允许注入Collection
其他服务处理程序进行检查),我们很乐意考虑将此功能添加到框架中。