JMX 之 Object Names 规范

Object Names(对象命名)

每个JMX MBean都需要一个“Object Name”,选择一个始终一致的、可用的Object Names将是非常重要的;客户端与你的对象模型(model)交互时,或许是直接将它展示且可读,比如jconsole;或者它被应用程序使用Object Names直接访问你声明的对象模型。所以,在多个models之间,MBean的对象命名一个尽可能唯一。

Object Name语法格式

一个Object Name是“javax.management.ObjectName”的实例,Object Name可以是一个MBean的名字,也可以是一个“表达式”、匹配多个MBeans名称。

它看起来像这样:

1
domain:key-property-list(关键属性列表)

比如:

1
com.sun.someapp:type=Whatsit,name=25

其中“domain”原则上可以为任意字符串,如果domain值为空,它将使用MBean Server的名称作为默认值;如果domain中包含 “”、“?” 等正则表达式字符,这些字符串只能用来匹配(访问、查询、过滤)MBeans,不能用来声明一个MBean实例。此外domain不能包含“:”特殊字符,因为 “:” 是“domain”与“propery-list”的分隔符。通配符 “\“ 匹配零个或者多个任意序列,而问号 “?” 则指匹配一个字符。

“key-property-list”有一个或者多个关键属性组成,格式为“key=value”,比如“type=Thread”;当多个properties是,它们之间以“,”分割,比如“name=DGC,type=Thread”;需要注意,空格是有意义的,我们不需要在“,”之后使用空格,比如“type=Thread, name=DGC”,那么“ name”将会被认为是属性名称。

此外,key的名称是有字符限制的,我们建议使用JAVA允许的、合法的标识符。value的字符也是有限制的,对于有些特殊字符,我们需要进行转义:ObjectName.quote;默认情况下,如果value是字符串(不是数字),我们应该总是转义它,除非我们能够确定它不会出现特殊字符。比如下述两个Object Names包含特殊字符(需要转义):

1
2
com.demo.myproject:type=Whatsit,name="25"
com.demo.myproject:type=Whatsit,name="25,26"

第二种情况,如果不转义将被认为是非法的。

对于表达式,“key-property-list”可以与上述的格式一样,也可以包含比如“”、“?”甚至空字符串(与“”等同),可以为“,”结尾表示一个列表等。最终,这种格式用于匹配多个Object Names,它们具有指定的确切关键属性(如果有)、加上任何其他关键属性。比如“:type=Thread,*”可以匹配“somedomain:type=Thread”、“somedomain:type=Thread,name=DGC”。

Object Name约定(规范)

  1. 一个MBean的Object Name应该是可以“预测的”,这意味着一个可以成为MBean的对象,我们应该能够知道它的Object Name将会什么。名称中不应该包含那些不是该对象固有部分的属性;此外,同一个对象的name不应该在application不同执行阶段而改变,比如不应该包含像“JVM进程ID”、“MBean Server ID”等这些每次执行会变化的属性。(“同一对象”的改变并不总是清晰或者有意义的,不过如果是这样,那么同一个对象始终具有相同的名称)

  2. domain部分,应该以此对象的package名称作为前缀,以避免来自不同子系统(模块)所引入的冲突;比如:

    1
    2
    com.demo.project1:type=Whatsit,name=5
    org.demo.project2:typpe=Whatsit

    domain不应该包含“/”,此字符串为MBean Server层次结构(级联)保留的,将会在后续版本中进行解释。

  3. 对于指定“type”的Object Name,应该包含相同的关键属性列表且它们具有相同的语法,且value具有相同语义。如果在特定domain中,对于指定“type”的MBean只允许一个实例,那么它通常不再需要除“type”之外的、其他额外的属性。
    如果同一“type”中可能有多个实例,它们可以通过使用不同的domain(即package名)或者其他关键属性来区分。大部分情况下,domain是一样的,我们通过使用不同的“name”属性值。

  4. 最常用的关键属性为:name和type。
    通常“type=X,name=Y”组合属性对一个MBean命名就足够了;一些JMX感知的控制台能够使用比其他名称更容易阅读的简写形式来显示这种形式的名称。
    有时候,我们也可以声明额外的属性,来满足上述种正则表达式匹配查询MBean的情况。比如“category”、“group”等。

    Object containment(遏制)

    有些托管对象(MBean)在逻辑上被其他托管对象所包含,这些对象或许无法独立存在。此时,下述模式是可行的。假如Server对象包含Application对象,Application包含WebModule对象,WebModule又包含Servlet;那么它们的名称看起来是这样的:

    1
    2
    3
    domain:type=Server,name=server5
    domain:type=Server.Application,Server=server5,name=app1 domain:type=Server.Application.WebModule,Server=server5,Application=app1,name=module3
    domain:type=Server.Application.WebModule.Servlet,Server=server5....WebModule=module3,name=servlet1

这种分层级的“type”属性可以让我们在不需要预知Model的前提下即可理解其他keys的含义;由于Object Name中key是无序的,因此无法知道例如在这里的第三个和第四个名称中,Application是否包含在Server中,反之亦然。这种模式意味着如果一个指定type的对象包含在其他type的对象中,那么它应该总是被包含。比如Server.Application总是包含在Server中。如果有其他Application没有包含在Server对象中,那么他们应该是不同的type,即事实上它们的type属性不应该为“Server.Application”;这与“特定type的MBean总是隐含相同key属性列表”的规则是一致的。

参考《Java Management Extensions (JMX) - Best Practices