OSGi 容器中的骆驼:将 InterceptStrategy 应用于所有骆驼上下文
Posted
技术标签:
【中文标题】OSGi 容器中的骆驼:将 InterceptStrategy 应用于所有骆驼上下文【英文标题】:Camel in OSGi Container: Apply InterceptStrategy to all camel contexts 【发布时间】:2015-06-30 21:24:27 【问题描述】:我有几个包(A、B 和 C)部署到一个 OSGi 容器,每个包都包含一个 CamelContext
和一些路由。我有另一个捆绑包(M),带有一个带有路由(用于收集监控数据)的CamelContext
和一个InterceptStrategy
bean。我希望 M 中的 InterceptStrategy
bean 自动应用于容器中的所有其他 CamelContext
s(即 A、B 和 C 中的那些),而无需修改其他包。
最终,目标是将来自每个 CamelContext
的数据窃听到 M 中的路由中,而无需对 A、B 或 C 进行任何更改以显式路由 Exchange
。这种方法或类似方法是否可行?
所有的CamelContext
s 都是使用 Spring XML 配置的。
更新:附加上下文
捆绑包 A、B 和 C 包含负责处理数据的核心产品。 Bundle M 包含一个可选监控工具,旨在测量流经 A、B 和 C 的数据的某些参数。目前,添加可选工具需要更改 A、B 和 C 中的路由以添加额外的Processor
s用监控数据丰富Exchange
,并读取<to />
端点之前的监控数据。
我们的目标是能够将 Bundle M 放入一个已经验证过的具有 A、B 和 C 的系统中;并让它自动应用于现有路由,而无需修改现有和工作包的配置。 可以对 A、B 和 C 进行修改以支持这一点,只要这些更改不会导致 A、B 和 C 依赖于 M 运行(即 ABC 必须仍然在没有 M 的情况下运行)。
如果有比使用拦截器更好的方法来做到这一点,我愿意接受。主要目标是:
-
保持 A、B 和 C 与 M 分离(尤其是在开发期间)
确保尽可能轻松地将 M 与 A、B 和 C 集成
无需手动更改 A、B 或 C 即可集成 M
【问题讨论】:
【参考方案1】:要么使用 Spring-DM,要么更好地将所有基于 spring xml 的路由转换为蓝图路由。这是在 Karaf/Osgi 中使用基于 XML 的路由的最佳支持方式。
【讨论】:
你能提供一个例子来说明 Spring-DM 如何在这里提供帮助吗?这是我最初看到的东西之一,但我发现使用它的所有解决方案都涉及修改捆绑包 A、B 和 C(例如添加<osgi:reference>
标签)。
在这种情况下,spring-dm 确保所有的 spring 上下文都正确启动,并且 Spring Beans 的连接被正确处理。当然,它也用于引用要注入到您的应用程序中的 osgi 服务。
但据我所知,这在这种特定情况下仍然无济于事(导致 bean 在其他包中可用而不修改包含它的包)。
不,因为您需要正确的导入包导出包。但是,如果这些接线正确,spring-dm 扩展器有助于找到这些【参考方案2】:
我认为使用InterceptorStrategy
是不可能的,因为它期望它在同一个骆驼上下文中运行。我知道跨多个上下文工作的唯一方法是使用 VM 端点(显然仅限于同一个 JVM),但是在这种情况下,您可能会更好地使用 JMS、JMX 或类似的东西。
JMS
为A, B & C
中的每个骆驼上下文创建一个InterceptorStrategy
,将您的消息发布到M
intercept().bean(transformForMonitoring).to("jms:queue:monitoring");
from("whatever:endpoint")
.process(myProcessor)
.to("target:endpoint");
如果您不想要 JMS 的开销,您也可以在 intercept()
上使用 vm
组件,但这会将您的监控组件限制为单个 JVM。
JMX
这有点复杂,但基本思想是告诉骆驼上下文为A, B & C
发布MBeans
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<jmxAgent id="agent" mbeanObjectDomainName="your.domain.name"/>
...
</camelContext>
然后让M
连接到JVM MBean 服务器并利用NotificationListener 之类的东西对交换做出反应。
【讨论】:
我喜欢你在这里提出的想法,但是有一个问题我的描述并不清楚:监控代码的某些步骤需要在@中的路由中同步执行987654332@、B
和 C
(例如,因为它们在 Exchange
上设置属性),因此仅将消息定向到异步队列是不够的。我看到在 Camel 2.16.0 中,direct-vm 组件将能够处理 no-present-consumers 条件,这将解决问题。您是否知道 Camel 2.12.0 中可用的任何类似机制允许同步但可选路由?
不,不能跨骆驼上下文工作,除非您想在拦截器中使用类似 Web 服务调用的东西,如果没有侦听器就吞下任何异常..【参考方案3】:
其中一种可能性是在 Bundle 'M' 中定义 custom Tracer 并将其导出为 osgi 服务。
在包 A、B、C 中定义 osgi-reference 到导出的 Tracer bean
使用camel JMX 启用跟踪。
这将导致捆绑包 A、B、C 发生变化,但变化很小,而且还可以集成和配置跟踪(拦截)
我自己没有尝试过,但是hth
【讨论】:
我们尝试过类似的方法。这种方法的问题是如果没有 M 存在,包 A、B 和 C 将无法启动,因为 osgi:reference 将不被满足。有没有办法解决这个问题? 如果您使用的是 spring-dm...您可以在参考上设置基数 [0..1],如果不是,您可以尝试将分辨率设置为清单中参考接口的可选吗?跨度>以上是关于OSGi 容器中的骆驼:将 InterceptStrategy 应用于所有骆驼上下文的主要内容,如果未能解决你的问题,请参考以下文章
无法从 Karaf 2.2.0 OSGi 容器中的根上下文运行 WAR