.NET 环境下的轻量级监控与管理:NetMX 介绍

在 Windows 应用程序的监控与管理领域,WMI(Windows Management Instrumentation)技术广为人知。它经过了广泛的测试,与编程语言无关,并且被众多管理应用程序所支持。.NET Framework 也提供了对 WMI 的支持(通过 System.Management 库)。然而,当考虑是否要构建具有相似功能的自定义解决方案时,需要考虑以下几点:

.NETFramework 对WMI的支持主要集中在使用提供的管理对象上。构建自己的提供者相对复杂。

WMI 是一种重量级技术。实例化 WMI 对象会消耗大量的内存和 CPU 周期。

那么,如果只需要管理自己的系统(而不是例如整个域),或者需要快速为现有的 .NET 应用程序(例如,用 C# 编写的 Windows 服务)添加远程管理和监控功能,WMI 并不适合这种情况。作者在面对这样的问题时,最初考虑快速构建一个脏库,使用反射来工具化对象,并将它们的操作和属性远程发布。然后作者意识到,在 Java 中有类似的东西,叫做 JMX(Java Management Extensions)。作者决定创建一个 .NET 版本的 JMX - NetMX。

作者的目标是在现有的 Windows 服务中添加监控管理功能。其中一部分是一个导出组件,它从数据库中获取数据(消息)并将其写入磁盘上的文件。作者想知道自服务启动以来导出了多少消息(按类型分组)。组件定义是一个简单的类,如下所示:

public class Exporter { public void ExportMessages() { // Export... } }

如果这是一个 Java 类,使用 JMX,作者可以通过定义以下接口将其转换为所谓的标准 MBean:

public interface ExporterMBean { int getType1ExportedCount(); int getType2ExportedCount(); ... }

作者希望在 .NET 下拥有相同的功能。

在实现方面,作者应该在这里赞扬 JMX 规范的架构师。它非常强大,同时不失简单性。值得一提的是,它非常通用,以至于整个应用服务器都建立在 JMX 微核(如 JBoss)之上。意识到这些人比作者更有经验,作者决定在将 JMX 移植到 .NET 时尽可能少地改变 API。作者决定引入的变更包括:

在标准 MBean 中属性的其他表示。属性在.NET中的自然表示是属性,作者决定用它们代替 getXxx/setXxx 命名约定。

默认和强制的远程访问实现在 JMX 中使用 RMI。在 NetMX 中,它使用.NET远程。

所有工厂使用配置节(System.Configuration)作为其数据源。

回调接口被委托替换。这是直观的,并且更适合 .NET 风格。

标准 MBean 可以在其管理接口中定义事件,从而成为通知发射器。

让离开上述提到的实际 NetMX 使用场景,尝试从抽象功能开始,即计数器。计数器是一个设备,应该具有以下特性:

允许获取或设置步长值。

允许按步长值递增。

允许通过任意提供的值更改值。

可以重置(其值设置为 0)。

在值更改时通知感兴趣的各方。

这些要求可以翻译成以下 MBean 接口规范:

public interface CounterMBean { [Description("Gets or sets step value")] int Step { get; set; } [Description("Increments counter value")] void Increment(); [Description("Adds provided value to counter value")] void Add(int value); [Description("Resets counter")] void Reset(); [MBeanNotification("Counter.ValueChanged")] event EventHandler ValueChanged; }

使用 Description 属性的可能性是 JMX 规范的扩展(它不使用注释 - Java 等价于属性)。同样,定义 ValueChanged 通知的方式是 NetMX 独有的。在标准 JMX 中,实现 CounterMBean 的类必须自己实现 NotificationEmitter 接口(或派生自辅助基类)。在这里,一切都是通过通知完成的,管道由容器(MBean 服务器)提供。

计数器的实现如下所示:

public class Counter : CounterMBean { private int value; private int step; public int Step { get { return step; } set { step = value; } } public void Increment() { value += step; OnValueChanged(); } public void Add(int value) { this.value += value; OnValueChanged(); } public void Reset() { value = 0; OnValueChanged(); } public event EventHandler ValueChanged; private void OnValueChanged() { if (ValueChanged != null) { ValueChanged(this, new NotificationEventArgs("Value changed", value)); } } }

这就是需要发布计数器功能的全部。执行此发布的代码也很简单:

IMBeanServer server = MBeanServerFactory.CreateMBeanServer(); Counter o = new Counter(); ObjectName name = new ObjectName("Counter:"); server.RegisterMBean(o, name); Uri serviceUrl = new Uri("tcp://localhost:1234/MBeanServer.tcp"); using (INetMXConnectorServer connectorServer = NetMXConnectorServerFactory.NewNetMXConnectorServer(serviceUrl, server)) { connectorServer.Start(); Console.WriteLine("Press any key to quit"); Console.ReadKey(); }

当然,NetMX 将提供一组标准的 ASP.NET 控件,这些控件可以与服务器建立连接,并通过 HTTP 远程控制计数器。

作者在开始 NetMX 项目时设定的目标似乎是可以实现的。尽管 NetMX 远未完成,但现在看来,关于性能(即创建管理对象)的假设以及对现有类进行工具化的少量编码工作是正确的。应该再次强调,NetMX 不是WMI的竞争对手。它只是对于那些被 WMI 压倒并寻求更轻量级(在所有方面)解决方案的人的另一种选择。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485