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 自动应用于容器中的所有其他 CamelContexts(即 A、B 和 C 中的那些),而无需修改其他包。

最终,目标是将来自每个 CamelContext 的数据窃听到 M 中的路由中,而无需对 A、B 或 C 进行任何更改以显式路由 Exchange。这种方法或类似方法是否可行?

所有的CamelContexts 都是使用 Spring XML 配置的。


更新:附加上下文

捆绑包 A、B 和 C 包含负责处理数据的核心产品。 Bundle M 包含一个可选监控工具,旨在测量流经 A、B 和 C 的数据的某些参数。目前,添加可选工具需要更改 A、B 和 C 中的路由以添加额外的Processors用监控数据丰富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@、BC(例如,因为它们在 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

osgi+camel+karaf运行环境搭建

OSGI 容器中的数据源

OSGi 容器 - Equinox 与 Apache Karaf 中的 Apache Felix

从码头到绝对 URL 的骆驼路线

骆驼运行时计时器更改