最近我进入了JMX的世界,尝试检测我们的应用程序,并通过自定义JMXClient公开一些操作。已经完成了如何在不必改变现有代码的情况下确定如何对类进行检测的工作。我使用DynamicMBean实现完成了这个。具体来说,我创建了一组注释,我们用它来装饰我们的类。然后,当创建对象(或者如果它们被用作静态类时初始化),我们通过静态类向我们的MBeanServer注册它们,该类为类构建dynamicMBean并注册它。当我们只使用JConsole或VisualVM时,这已经很好了。我们可以执行操作并查看字段的状态,就像我们应该能够做到的那样。我的问题更倾向于创建像JConsole这样的半实时JMXClient。
我面临的最大问题是如何使JMXClient报告字段的状态尽可能接近实时,而不必修改已检测的库以推送通知(例如,在某个类的setter方法,设置字段,然后触发JMX通知)。我们希望这些课程完全不知道他们正在进行仪器化。如果在检查属性时检出JConsole,则屏幕底部会有一个刷新按钮,用于刷新属性值。它显示给您的值是当该属性加载到视图中时检索到的值,并且在不使用刷新按钮的情况下不会更改。我希望这可以自己发生。
我编写了一个小UI,显示了一些关于连接状态的数据,以及一些检测类的一些字段。为了使这些值反映当前状态,我有一个在后台旋转的Thread。每隔一秒左右,线程就会尝试获取我感兴趣的字段的当前值,然后UI会因此而更新。我不太喜欢这个解决方案,因为编写更新底层模型的逻辑非常棘手。甚至更难以以不会导致奇怪错误的方式更新UI(使用Swing)。
我还可以在我们的应用程序端编写JMXAgent的另一部分,其中一个线程贯穿已注册的DynamicMBeans列表,确定其属性的值是否已更改,然后按下通知(s )。这会将通知逻辑移出已检测的库,但仍会对应用程序施加更多负担:(。
我只是想知道你是否有人在JMX或其他方面处于这个位置,并且可以指导我正确的方向为JMXClient的设计方法或实际上任何其他可以做到这一点的建议解决方案比我的解决方案更优雅。
你们的任何建议都会受到赞赏。
答案 0 :(得分:1)
如果您不想更改实体,则必须对某些实体进行轮询。您的JMXAgent
或JMX客户端将不得不经常请求bean。你没有办法绕过这个性能打击,虽然因为你正在调用一堆获取,我认为它不会非常昂贵。当然,你的JMXAgent
会比JMX客户端轮询更好。但是,如果客户端无论如何都在轮询所有bean,那么成本可能完全相同。
如果对象可以调用代理来表明它们已被更改或者它们是否支持某种isDirty()
方法,则不需要进行轮询。
在我们的系统中,我们有一个各种组件使用的指标系统。每个类都增加了自己的度量标准,并且它是连接到持久性的度量标准。您可以使用JMX请求度量标准值,或将它们持久保存到磁盘或线路。通过使用Metric
类型,正在进行计数的实体与需要访问所有度量值的实体之间存在分离。
通过转到已注册的Metric
对象类型模型,您的GUI可以查询MetricRegistrar
所有指标并通过JMX,HTML或其他任何方式显示它们。因此,您的实体只会执行metric.increment()
或metric.set(...)
,并且只要需要该值,GUI就会查询该指标。
希望这里有所帮助。
答案 1 :(得分:0)
本身不是解决方案,但您可以使用spring集成简化轮询事件转换器JMXAgent实现。它有一个叫做JMX属性轮询频道的东西,似乎可以满足你的需求。 example here
答案 2 :(得分:0)
这里有效率意味着留在包含您正在查看的bean的mbean服务器中。你想要的是一种转换 mbeans的方法,这些mbeans不知道如何向做的mbeans发出通知。
要查看数字和字符串属性,可以使用监视程序包中的标准mbeans。实例化 in 包含您实际要查看的bean的mbean服务器,然后适当地设置属性。您可以在不向目标添加代码的情况下执行此操作,因为监视程序包是JVM中的标准。监视器bean将监视您为更改选择的对象,并仅在观察到实际更改时发出更改通知。使用setGranularityPeriod告诉监视器bean查看目标的频率。
一旦监控bean到位,只需注册将在更改时创建的MonitorNotifications。