当前位置: 首页 > ActiveMQ in Action 读书笔记 > 正文

14.1 JMX API和ActiveMQ

14.1 The JMX API and ActiveMQ

14.1 JMX API和ActiveMQ

Nearly every story on  management and monitoring in  the Java world begins  with Java Management Extensions (JMX). The JMX API allows you to implement management interfaces for your Java applications  by exposing functionality to be  managed. 在Java世界里,几乎所有和管理与监控相关的故事都是从Java管理扩展(JMX)开始的.JMX API允许 你的Java程序暴露管理功能来实现管理接口.
These  interfaces  consist of  management  beans, usually  called  MBeans, which expose resources of  your application to  external management applications.  For this purpose, ActiveMQ  exposes its management  API through JMX,  and it can  be used to manage and monitor the  broker during runtime. Some of these  management and monitoring tasks may include.
? Obtaining broker statistics, such as number of consumers (total or perdestination)
? Adding new connectors or removing existing ones
? Changing some of the broker configuration properties
这些接口有管理bean组成,通常称为MBeans,它们会暴露你的应用程序中的资源给外部的管理程序.为此,ActiveMQ通过JMX暴露其管理API,这样可以在运行时管理和监控代理.这些管理和监控任务 可能包括:
(1)获取代理统计信息,比如消息消费者数量(总量或每个消息目的地的消费者数量)
(2)新增连接或移除原有连接
(3)修改代理的一些配置属性
These tasks and many more can be achieved using JMX in ActiveMQ. Because JMX is the standard API for Java application management, most monitoring tools support the ability to execute JMX queries. This makes it incredibly easy to integrate the monitoring of a Java application into an existing tool that supports JMX. ActiveMQ中使用JMX可以完成上述任务而且还可以做的更多.因为JMX是Java程序管理的标准API,大多数监控工具都支持执行JMX查询功能.这样将已有的支持JMX的工具和Java应用程序监控集成 起来就变得相当容易了.
In this  section we’ll  learn how  JMX is  used with  ActiveMQ. We’ll start by explaining  the difference  between local  and remote  access to  the broker’s management API, and how to expose ActiveMQ JMX MBeans. While doing this,  we’ll cover  various configuration  options used  to adapt  JMX to  your needs.  Next, we’ll see  an example  of a  Java application  that uses  the JMX API to gather various  broker  statistics.  Finally, we’ll  explain  some  more advanced  JMX configuration topics, such as remote access and security. 本节中,我们将学习如何在ActiveMQ中使用JMX.我们将从解释本来和远程介入代理管理API的 不同点歹势,并说明如何暴露ActiveMQ的JMX MBeans.同时,我们还将介绍各种配置选项以便让 JMX满足你的需求.最后,我们将阐述更多高级JMX配置主题,比如远程访问和安全.

14.1.1 Local vs. remote JMX access

14.1.1 本地和远程JMX访问

The JVM provides what’s known as the JMX agent. The JMX agent is comprised of the MBean server, some agent services, and some protocol adapters and connectors. The JMX agent is used to expose the ActiveMQ MBeans. In order to control various aspects of the JMX agent, a set of properties is provided. Through the use of these properties, various features in the JMX agent can be enabled and disabled. For more information, see the document titled “Monitoring and Management for the Java Platform” (http:// mng.bz/0Dzg). JMX提供了JMX代理.JMX代理由MBean服务器,一些代理服务以及一些协议适配器和连接器组成. JMX代理用于暴露ActiveMQ的MBeans.为了控制JMX代理的各个方面,JMX提供了一系列属性.通过 使用这些属性,可以启用JMX代理的各种功能.更多相关信息,请参阅名称为”Monitoring and  Management for the Java Platform”(监控和管理Java平台,http://mng.bz/0Dzg)的文档.
Here’s a snippet from the ActiveMQ startup script for Linux/Unix concerning the JMX capabilities: 下面是Linux/Unix中开启JMX功能的ActiveMQ启动脚本片段:
if [ -z "$SUNJMX" ] ; then
#SUNJMX="-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false"
SUNJMX="-Dcom.sun.management.jmxremote"
fi
Here’s the same snippet from the ActiveMQ startup script for Windows concerning the SUNJMX variable: 下面是Windows系统中开启SUNJMX变量的ActiveMQ启动脚本片段:
if "%SUNJMX%" == "" set SUNJMX=-Dcom.sun.management.jmxremote ^
REM set SUNJMX=-Dcom.sun.management.jmxremote.port=1099 ^
-Dcom.sun.management.jmxremote.authenticate=false ^
-Dcom.sun.management.jmxremote.ssl=false
Note that each  snippet demonstrates the  use of a  variable named SUNJMX.  This variable is specific to  the ActiveMQ startup scripts,  and is used to  hold the JMX properties that are recognized by the JVM. Each snippet shows that the  only JMX  property that’s  enabled by  default is  the com.sun.management.jmxremote property. Don’t let the name of this property fool you, as it enables the   JMX agent  for  local  access only.   This can  be  easily  tested by  starting  up JConsole  and seeing  ActiveMQ in   the list  of locally  accessible  objects as shown in figure 14.1. 需要注意的是,上面的代码片段解释了名称为SUNJMX的变量的用法.该变量专门用于ActiveMQ的启动脚本,用来保存能够被JVM失败的JMX属性值.每个代码片段都显示了默认情况下默认启用的唯一的JMX属性是com.sun.management.jmxremote.别被这个名称迷惑了,因为该属性启动的JMX代理仅能通过本地访问.这一点可以通过启动JConsole后看到ActiveMQ在本地可访问对象列表中 来简单测试,如图14.1所示.
Upon selecting the ActiveMQ run.jar and clicking the Connect button, the main screen will appear in JConsole, as shown in figure 14.2. 通过选择ActiveMQ的 run.jar然后点击连接按钮,JConsole中将显示主界面,如图14.2所示.
Note  in  figure  14.2  that the  ActiveMQ  JMX  domain  (listed as  org.apache. activemq) is near the cursor. Using the default configuration and startup script in ActiveMQ, this is what will appear in JConsole, indicating that the JMX agent is enabled for local  access. But attempts to  access ActiveMQ remotely (from  a remote host) via JConsole will fail, as the JMX agent hasn’t been exposed on  a specific port number using the com.sun.management.jmxremote.port property.  More on this later. 图14.2中需要注意的是,ActiveMQ的JMX域(显示成org.apache.activemq)在靠近鼠标的位置. 使用ActiveMQ默认配置和启动脚本启动ActiveMQ后,在JConsole中建看到如图所示内容,表明 JMX代理可以通过本地访问.但是如果尝试通过JConsole访问远程的ActiveMQ(从一个远程 主机访问)就会失败,因为JMX代理没有通过一个名称为com.sun.management.jmxremote.port的 属性表示的端口暴露出来.稍后,将介绍更多这方面内容.
Here’s a snippet from the default broker configuration with the useJmx attribute
explicitly enabled (shown in bold):
下面的代码片段来自代理的默认配置,明确的启用了useJmx属性(粗体字所示)
<broker xmlns="http://activemq.org/config/1.0" useJmx="true"
brokerName="localhost"
dataDirectory="${activemq.base}/data">
...
</broker>
By simply changing the useJmx attribute from true to false, the ActiveMQ domain will no longer be available for access: 但是,只要简单的将useJmx属性值从true改成false,ActiveMQ域即不能被访问:
<broker xmlns="http://activemq.org/config/1.0" useJmx="false"
brokerName="localhost"
dataDirectory="${activemq.base}/data">
...
</broker>
Upon making this small configuration change, you’ll be able to access the JMX agent via the ActiveMQ run.jar, but the ActiveMQ domain won’t be available (see figure 14.3). This is because the JMX agent for the JVM and the domain for ActiveMQ are distinct. The JMX agent in the JVM is controlled by the com.sun.management.jmxremote property, whereas the ActiveMQ domain is controlled by the useJmx attribute in the broker configuration file. 通过这个小小的改动,你可以通过ActiveMQ的run.jar访问JMX代理,但是ActiveMQ域将不能访问(如图14.3所示).这是因为用于JVM的JMX代理和用于ActiveMQ域的JMX代理是分开的.JVM中JMX 代理受com.sun.management.jmxremote属性控制,而ActiveMQ域受代理配置文件中useJmx属性 控制.

14.1.2 Exposing the JMX MBeans for ActiveMQ

14.1.2 暴露ActiveMQ的JMX MBeans

By default, the MBeans for ActiveMQ are  enabled to be exposed for ease of  use. In order to  fully utilize the  MBeans, there are  additional properties in  the broker configuration file to enable additional functionality. Listing 14.1 shows in bold  what needs  to be  changed in  the broker  configuration to  enable JMX support.
Listing 14.1 ActiveMQ JMX configuration
为便于使用,ActiveMQ默认启用了MBeans暴露.为了最大限度的使用MBeans,可以使用代理配置文件中 一些其他的属性来开启一些额外的功能.代码清单14.1来自代理配置文件,其中粗体字所示部分需要 被修改以开启JMX支持. (译注: 粗体部分为 useJmx=”true” 和 connectorPort=”2011″ jmxDomainName=”my-broker”)
代码清单14.1 ActiveMQ JMX配置
<broker xmlns="http://activemq.org/config/1.0" useJmx="true"
brokerName="localhost"
dataDirectory="${activemq.base}/data">
<managementContext>
<managementContext connectorPort="2011" jmxDomainName="my-broker" />
</managementContext>
 
<transportConnectors>
<transportConnector name="openwire" uri="tcp://localhost:61616" />
</transportConnectors>
</broker>
Two important items in the preceding configuration file are related to the JMX
configuration. The first is the useJmx attribute of the <broker> element that
enables/disables JMX support. The value of this attribute is true by default so
the broker uses JMX by default, but it’s included in this example configuration
for demonstration purposes.
上述配置文件中与JMX配置相关的有两点.第一个是<broker>元素的useJmx属性值决定是否启用JMX支持.该属性值默认值是true,因此代理默认是启用JMX,但是这里了明确配置了这个属性为 启用是为了说明用.
By default, ActiveMQ starts a connector which enables remote management on port 1099 and exposes MBeans using the org.apache.activemq domain name. These default values are sufficient for most use cases, but if you need to customize the JMX context further, you can do so using the <managementContext> element. In our example we changed the port to 2011 and the domain name to my-broker. See the properties for the management context in table 14.1.

Now we can start the broker with the following command:

默认情况下,ActiveMQ在1099端口启动一个连接允许远程管理代理并使用org.apache.activemq域名来暴露MBeans.大多数情况下,这些默认设置组工使用了,但是如果你需要进一步自定义JMX上下文,你就可以使用<managementContext>元素.在上面的例子中我们修改了端口为2011并且将域名修改 成my-broker.JMX管理上下文属性如表14.1所示.

现在,我们可以通过下面的命令来启动代理了:

$ ${ACTIVEMQ_HOME}/bin/activemq console \
xbean:${EXAMPLES}src/main/resources/org/apache/activemq/book/ch14/ \
activemq-jmx.xml
Table 14.1 ManagementContext properties

Property name Default value Description
useMBeanServer true If true, try to locate and use the existing JVM’s MBeanServer
jmxDomainName org.apache.activemq The JMX domain name
createMBeanServer true If true and if no MBeanServer can be located, create a new MBeanServer
createConnector true If true then create a JMX connector to the MBeanServer for remote management
connectorPort 1099 The port number to be used by the JMX connector
rmiServerPort 0 The port number to be used by the RMI server
connectorPath /jmxrmi The path to be used by the JMX connector

表14.1 管理上下文属性

属性名称 默认值 描述
 useMBeanServer  true 如果配置为true,将尝试查找并使用已有的JVM的MBeanServer
jmxDomainName org.apache.activemq JMX域名
createMBeanServer true 如果配置为true,则在没有MBeanServer存在时,会创建一个新的MBeanServer
createConnector true 如果配置为true,则为进行远程管理,会创建一个JMX连接器连接到MBeanServer
connectorPort 1099 JMX连接器使用的端口
rmiServerPort 0 RMI服务器端口
connectorPath /jmxrmi JMX连接器使用的路径
Among the usual log messages shown during the broker startup, you may notice the following line: 在代理启动时控制台显示的常规日志信息中,你会看到下面的日志信息:
INFO ManagementContext - JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:2011/jmxrmi
This is the JMX URL we can use to connect to the broker using a utility such  as JConsole, as discussed later in the chapter. As you can see from the output, the port number for accessing the broker via JMX has been changed from 1099 to 2011. Now that JMX support has been  enabled in ActiveMQ, you can begin  utilizing the JMX API to interact with the broker. 这就是用类似JConsole的工具可以用来来接到代理的JMX URL,本章稍后将会介绍到相关内容.正如你从输出中看到的,通过JMX操作代理的端口已经从1099变成2011了.既然ActiveMQ已经 支持JMX了,你即可以利用JMX API和代理交互了.

14.1.3 Exploring broker properties using the JMX API

14.1.3 使用JMX API暴露出代理属性

Using the JMX API, statistics can be obtained from a broker at runtime. The example shown in the following listing connects to the broker via JMX and prints out some of the basic statistics such as total number of messages, consumers, and queues. Next it iterates through all available queues and prints their current size and number of consumers subscribed to them.

Listing 14.2 ActiveMQ broker statistics

使用JMX API可以在运行是获得代理的统计数据.下面代码清单中的示例程序通过JMX来接到代理然后 打印出一些诸如消息数量,消费者数量和队列数量等基本的统计数据.紧接着,程序遍历了所有可用的 队列并打印出它们当前的尺寸以及订阅它们的消费者数量.

代码清单14.2 ActiveMQ代理统计数据

public class Stats 
{
  public static void main(String[] args) throws Exception 
  {
    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:2011/jmxrmi");
    JMXConnector connector = JMXConnectorFactory.connect(url, null);
    connector.connect();
    MBeanServerConnection connection =
connector.getMBeanServerConnection();
    ObjectName name = new ObjectName("my-broker:
BrokerName=localhost,Type=Broker");
    BrokerViewMBean mbean =(BrokerViewMBean) MBeanServerInvocationHandler.newProxyInstance(connection,
name, BrokerViewMBean.class, true);
    System.out.println("Statistics for broker "
+ mbean.getBrokerId()+ " - " + mbean.getBrokerName());
    System.out.println("\n-----------------\n");
    System.out.println("Total message count: "
+ mbean.getTotalMessageCount() + "\n");
    System.out.println("Total number of consumers: "
+ mbean.getTotalConsumerCount());
    System.out.println("Total number of Queues: "
+ mbean.getQueues().length);
     
    for (ObjectName queueName : mbean.getQueues()) 
    {
      QueueViewMBean queueMbean = (QueueViewMBean)
MBeanServerInvocationHandler
.newProxyInstance(connection, queueName,
QueueViewMBean.class,true);
      System.out.println("\n-----------------\n");
      System.out.println("Statistics for queue "
+ queueMbean.getName());
      System.out.println("Size: " + queueMbean.getQueueSize());
      System.out.println("Number of consumers: "
+ queueMbean.getConsumerCount());
    }
  }
}
The preceding example is using the standard JMX API to access and use broker and request information. For starters, we have to create an appropriate connection to the broker’s MBean server. Note that we’ve used the URL previously printed in the ActiveMQ startup log. Next, we’ll use the connection to obtain the MBean representing the broker. The MBean is referenced by its name, which in this case has the following form: 前面的例子试用了标准的JMX API了访问并使用代理来获取相关信息.伯母必须从创建一个合适的 连接来连接到代理的MBean服务器.注意,我们使用了前面ActiveMQ启动日志中打印出来的URL.接着,我们将使用前面创建的连接来获取代表代理的MBean.MBean通过name来引用,name必须符合下面的格式:
<jmx domain name>:BrokerName=<name of the broker>,Type=Broker
The JMX object name for the ActiveMQ MBean using the default broker configuration is as follows: ActiveMQ 的MBean使用的 对象名称使用了代理的默认配置,如下所示:
org.apache.activemq:BrokerName=localhost,Type=Broker
But recall back in listing 14.1 that the JMX domain name was changed from localhost to my-broker. Therefore the JMX object name for the changed broker configuration looks like the following: 但是,回顾代码清单14.1克制,JMX域名已经从localhost变成my-broker了.因此,修改后的代理的JMX对象名称看起来应该像下面这个样子:
my-broker:BrokerName=localhost,Type=Broker
With this object name  to fetch the broker  MBean, now the methods  on the MBean can be used to acquire the broker  statistics as shown in listing 14.2. In  this example, we  print the  total number  of messages  (getTotalMessageCount()), the total consumer count (getTotalConsumerCount()),  and the total number  of queues (getQueues().length()).The getQueues() method returns  the object names for  all the queue MBeans.These names  have a format similar  to the broker MBean  object name. For example,  one of the  queues we’re using  in the jobs  queue is named JOBS.suspend and it has the following MBean object name: 使用由该对象名称获取到的代理MBean的方法可以获取代理的统计数据,如代码清单14.2所示.在本例中, 我们打印了消息总数(getTotalMessageCount()),消费者总数(getTotalConsumerCount())和队列总数 (getQueues().length()).getQueues()方法返回所有队列MBeans的对象名称.这些对象名称的格式和代理 的MBean对象格式类似.例如,其中一个用于工作队列中的队列命名为JOBS.suspend,而其MBean对象名称 如下所示:
my-broker:BrokerName=localhost,Type=Queue,Destination=JOBS.suspend
The only difference between this queue’s object name and the broker’s object name is in the portion marked in bold. This portion of the object name states that this MBean represents a type of Queue and has an attribute named Destination with the value JOBS.suspend. 该队列对象名称和代理的对象名称的唯一不同点由粗体字所示.对象名称的该部分表明该MBean代表一种队列并且有一个名称为Destination的属性,其属性值为JOBS.suspend.
Now it’s time  to examine the  job queue example  to see how  to capture broker runtime statistics using the example  from listing 14.2. But first  the consumer must be slowed  down a bit  to be sure  that some messages  exist in the  system before the statistics are gathered. For this purpose the following broker URL is used: 下面是时候查看代码清单14.23所示的job queue这个例子是如何获取运行时统计数据的.但是, 首先消息消费者处理速度必须要降低一点以确保在统计开始时系统中存在一些未处理的消息. 为此,我们使用下面代码所示的代理URL:
private static String brokerURL = "tcp://localhost:61616?jms.prefetchPolicy.all=1";
Note the parameter on the URI for the broker (the bold portion). This  parameter ensures  that  only  one  message  is dispatched  to  the  consumer  at  a time. Additionally, the consumer can  be slowed down by  adding a one-second sleep  to the thread for every message that flows through the Listener.onMessage() method. Here’s an example of this: 注意代理URI的参数部分(粗体字部分),这个参数保证了一次仅发送一个消息个消费者.并且,在每一个消息通过Listener.onMessage()流向消费者后,消费者线程都会休眠1秒,以变降低消费者 的处理速度.下面是示例代码:
public void onMessage(Message message) 
{
  try 
  {
    //do something here
    System.out.println(job + " id:"
+ ((ObjectMessage)message).getObject());
    Thread.sleep(1000);
  } 
  catch (Exception e) 
  {
    e.printStackTrace();
  }
}
The consumer (and listener) modified in this manner have been placed into package org.apache.activemq.book.ch14.jmx, and we’ll use them in the rest of this section. Now the producer can be started just like it was started in chapter 3: 按照上述要求修改后的消费者(同时也是监听器)放到了org.apache.activemq.book.ch14.jmx包里面,我们在本节的其余部分也会用到这个包.现在可以通过类似于第3章中的方法启动生产者:
mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch3.jobs.Publisher
And the modified consumer can be run as well: 同时修改后的消息消费者也可以用下面的命令来运行:
mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch14.jmx.Consumer
Finally, run the JMX statistics class using the following command: 最后,可以使用下面的命令执行JMX统计数据类:
mvn -e exec:java -Dexec.mainClass=
org.apache.activemq.book.ch14.jmx.Stats
The org.apache.activemq.book.ch14.jmx.Stats class output is shown next: org.apache.activemq.book.ch14.jmx.Stats类的输出信息如下:
Statistics for broker ID:dejanb-52630-1231518649948-0:0 - localhost
-----------------
Total message count: 670
Total number of consumers: 2
Total number of Queues: 2
-----------------
Statistics for queue JOBS.suspend
Size: 208
Number of consumers: 1
-----------------
Statistics for queue JOBS.delete
Size: 444
Number of consumers: 1
Note that the statistics from the Stats class are output to the terminal. There are many more statistics on the  from ActiveMQ. The example shown here is meant only to be an introduction. 注意,Stats类输出的统计信息是输出到控制台的.ActiveMQ的MBeans还有更多的统计信息.上面的示例输出仅作为介绍用.
As you can see, it’s easy to access ActiveMQ using the JMX API. This will allow you to monitor the broker status, which is useful in both development and production environments. But what if you want to restrict access to the JMX capabilities? 你已经看到,使用JMX API访问ActiveMQ是很容易的.并且,你还可用其监控代理的状态,这在开发和生产 环境下都是很有用的.但是,如果你想限制JMX的访问时该怎么做呢?

14.1.4 Advanced JMX configuration

14.1.4 高级JMX配置

In some situations, advanced configuration  of the JMX agent is  necessary. This includes remote access, restricting access  to a specific host, and  restricting access to particular  users via authentication.  Most of these  tasks are fairly easy to  achieve through  the use  of the  JMX agent  properties and by slightly modifying the ActiveMQ startup script. 某些情况下,有必须要使用JMX代理的高级配置.高级配置包括远程访问,限制访问指定的主机以及通过认证限制只有特定用户可以访问.
Again, remember the snippet from the ActiveMQ startup script for Linux/Unix concerning the JMX capabilities: 再次回顾下ActiveMQ启动脚本中(Linux/Unix)关于JMX的部分的代码片段:
if [ -z "$SUNJMX" ] ; then
#SUNJMX="-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false"
SUNJMX="-Dcom.sun.management.jmxremote"
fi
Recall also the same snippet from the ActiveMQ startup script for Windows concerning the SUNJMX variable: 同样也回忆下ActiveMQ Windows启动脚本中的SUNJMX参数相关部分代码片段:
if "%SUNJMX%" == "" set SUNJMX=-Dcom.sun.management.jmxremote
REM set SUNJMX=-Dcom.sun.management.jmxremote.port=1099 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false
Note the portions that are commented out. These three additional properties will be covered in this section, as well as a fourth related property. 注意,被注释掉的部分.本章将关注这三个额外属性,同时还会关注第四个相关属性.
ENABLING REMOTE JMX ACCESS 启用远程JMX访问
Sometimes it’s necessary to allow access  to the JMX agent from a  remote host. Enabling remote access to  the JMX agent is  easy. The default ActiveMQ  startup scripts include a  configuration for remote  access to the  JMX agent using  the com.sun. management.jmxremote.port property, but it’s commented out. By  adding this property to the uncommented  portion of the SUNJMX variable,  remote access will be enabled on the specified port number. 有时,有必要运行从远程主机访问JMX代理.启用JMX代理的远程访问很容易.ActiveMQ默认的
启动脚本中就有一个配置JMX代理远程访问的属性:com.sun. management.jmxremote.port,
但是该属性被注释调了.通过去掉SUNJMX参数中该属性的注释,可以在指定的端口启用JMX远程
访问.
Here’s a snippet from the ActiveMQ startup script for Linux/Unix with the com.sun.management.jmxremote.port property enabled: 下面是Linux/Unix下ActiveMQ启动脚本中启用com.sun.management.jmxremote.port属性的代码片段:
if [ -z "$SUNJMX" ] ; then
SUNJMX="-Dcom.sun.management.jmxremote.port=1234 \
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false"
fi
Here’s the same snippet from the ActiveMQ startup script for Windows with the com.sun.management.jmxremote.port property enabled: 下面是Windows系统下ActiveMQ启动脚本中启用com.sun.management.jmxremote.port属性的代码片段:
if "%SUNJMX%" == "" set SUNJMX=-Dcom.sun.management.jmxremote.port=1234 ^
-Dcom.sun.management.jmxremote.authenticate=false ^
-Dcom.sun.management.jmxremote.ssl=false
Note that the com.sun.management.jmxremote.port property is now enabled and port number 1234 has been specified.  Also, two additional JMX properties  related to JMX security  have been  enabled as  well. Specifically  the com.sun.management. jmxremote.authentication  property  and  the  com.sun.  management.jmxremote.ssl property have both been set to false. These two properties are included and  set to false to disable security because otherwise they’re both true by default for remote monitoring. The JMX  agent in the JVM  where ActiveMQ is started  will be available for access via port number 1234. After enabling remote access, you can test  this  using  JConsole’s  Remote  tab  as  shown  in  figure  14.4.   Upon successfully connecting  to the  remote ActiveMQ  instance, you’ll  be able  to remotely manage and monitor ActiveMQ. 注意,上面代码中已经启用了com.sun.management.jmxremote.port属性,并且指定了1234端口.同样,另外相关相关的属性也被启用了.com.sun.management.jmxremote.authentication属性 和com.sun.management.jmxremote.ssl属性特意设置成了false.这两个属性被设置为false以 便关闭安全特性否则为了远程监控,它们的默认值都是true.做了上述配置后,运行ActiveMQ的 JVM中的JMX代理即可以通过端口1234访问了.开启了远程访问之后,你可以使用JConsole的远程标签页进行测试,如图14.4所示.成功了连接到远程的ActiveMQ实例之后,你就可以远程管理和]监控ActiveMQ了.
NOTE In order for the JMX remote access to work successfully, the /etc/hosts file must be in order. Specifically, the /etc/hosts file must contain more than just the entry for the localhost on 127.0.0.1. The /etc/hosts file must also contain an entry for the real IP address and the hostname for a proper configuration. Here’s an example of a proper configuration: 127.0.0.1 localhost 192.168.0.23 urchin.bsnyder.org urchin 注意,为了是的JMX远程访问正常工作,/etc/hosts文件必须符合要求./etc/hosts文件不仅包含127.0.0.1上的localhost这一条目,还需要包含针对配置的主机名与真实IP地址对应的相关 条目.下面是与配置对应的hosts文件示例:
127.0.0.1 localhost
192.168.0.23 urchin.bsnyder.org urchin
Note the portion of the /etc/hosts file that contains an entry for the localhost and an entry for the proper hostname and IP address. 注意,/etc/hosts文件包含了localhost条目,还包含了适当的主机名和IP地址条目.

14.1.5 Restricting JMX access to a specific host

14.1.5 限制只能通过指定主机访问JMX

Sometimes you need  to restrict the  use of JMX  to a specific  host in a  multi -homed environment, such as  the host on which  ActiveMQ is running. The  fourth related property mentioned earlier will provide this type of restriction via the Java SE, not by ActiveMQ  itself. The java.rmi.server.hostname property is  used to provide just such a restriction. As  defined in the Java SE documents on  the section about RMI properties (http://mng.bz/65hS): 有时,你需要限制只有指定的主机才能那个使用JMX,比如,在多用户环境中就需要这种限制. 上文中提到的第四个相关属性可以实现这种限制,是通过Java SE实现的限制,而不是通过 ActiveMQ本身来限制的.java.rmi.server.hostname属性用于提供这种限制.正如Java SE 文档中RMI属性部分定义的(http://mng.bz/65hS):
The  value of  this property  represents the  host name  string that  should be associated with  remote stubs  for locally  created remote  objects, in order to allow clients to invoke  methods on the remote  object. In 1.1.7 and  later, the default value of this property is the IP address of the local host, in  “dotted -quad” format. 该属性值表示文本格式的主机名,该主机名与远程的stub关联以便创建本地的远程访问对象, 让客户端可以调用远程对象上的方法.在1.1.7及其后续中,该属性的默认值是本地机器的IP 地址,点分四组的格式.
This property  must be  added to  the SUNJMX  variable in  the ActiveMQ  startup script.  Here’s an  example of  adding this  property to  the ActiveMQ  startup script for Linux/Unix: 该属性必须要添加到ActiveMQ启动脚本的SUNJMX变量中.下面是Linux/Unix下添加该属性到 ActiveMQ启动脚本的示例:
if [ -z "$SUNJMX" ] ; then
SUNJMX="-Dcom.sun.management.jmxremote \
-Djava.rmi.server.hostname=192.168.0.23"
fi
And here’s an example of adding this property to the ActiveMQ startup script for Windows: 下面是Windows下添加该属性到ActiveMQ启动脚本的示例:
if "%SUNJMX%" == "" set SUNJMX=-Dcom.sun.management.jmxremote \
-Djava.rmi.server.hostname=192.168.0.23
This slight change to use the java.rmi.server.hostname property simply notes the name of the host to which the access should be restricted. After making this change, the ActiveMQ MBeans can only be accessed from this host. 通过使用java.rmi.server.hostname属性这个微小的改变即可限制指定名称的机器才可访问JMX.修改之后,只有指定名称的主机可访问ActiveMQ的MBeans.

14.1.6 Configuring JMX password authentication

14.1.6 配置JMX密码验证

Password authentication for the JMX agent is controlled by an access file and  a password file. The access file is used to define roles and assign permissions to those  roles. The  password file  is used  to map  roles to  passwords. The  JDK provides examples of each of these files, so the best way to begin is to take  a look at these files. The files are located in the $JAVA_HOME/jre/lib/management/ directory and are  named jmxremote.access and  jmxremote.password.template. Each of these files is  intended to provide a  starting point for you  to define your own values.

Here are the contents of the default jmxremote.access file:

JMX代理的密码验证受到访问文件和密码文件控制.访问文件用于定义角色已经为角色授权.密码文件用来将角色映射到密码.JDK提供了这两种文件的示例,因此开始之前先看看这些示例文件.示例文件位置为$JAVA_HOME/jre/lib/management/目录下,文件命名为jmxremote.access和jmxremote.password.template.每个文件都打算为你定义自己的文件的起点.

下面是默认的jmxremote.access文件内容:

monitorRole readonly
controlRole readwrite
Note that monitorRole is the role name and readonly is the access level. The role name needs to correspond to a role name in the password file.

The contents of the default jmxremote.password.template file is empty but provides the following suggestion:

注意,上述文件中monitorRole是角色名称,readonly是访问级别.角色名称需要在密码文件中找到对应的映射.

默认的jmxremote.password.template文件内容为空,但是提供了下面的建议:

monitorRole QED
controlRole R&D
Note that monitorRole is the role name and QED is the password. This role name corresponds to the role name in the jmxremote.access file. The idea with the jmxremote. password.template file is that it should be used as a template—you should make a copy of the file to use as your password file and make changes specific to your needs. 注意,monitorRole是角色名,QED是密码.这个角色名称与jmxremote.access文件中的角色名称对应.使用jmxremote.password.template这个模版文件的意思是,该文件应当作为一个模版来用,你应该 拷贝这个文件然后使用你自己的密码,根据你的需求做相应修改.
To make a copy of the jmxremote.password.template file for Mac OS X, use the following command: Mac OS X中可以使用下面的命令获得一份jmxremote.password.template文件的拷贝:
$ cp /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ \
management/jmxremote.password.template \
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ \
management/jmxremote.password
To make a copy of the jmxremote.password.template file for Linux/Unix, use the following command: Linux/Unix中可以使用下面的命令获得一份jmxremote.password.template文件的拷贝:
$ cp $JAVA_HOME/jre/lib/management/jmxremote.password.template \
$JAVA_HOME/jre/lib/management/jmxremote.password
To make a copy of the jmxremote.password.template file for Windows, use the following command: Windows中可以使用下面的命令获得一份jmxremote.password.template文件的拷贝:
> copy %JAVA_HOME%\jre\lib\management\jmxremote.password.template \
%JAVA_HOME%\jre\lib\management\jmxremote.password
Edit the new jmxremote.password file so that the contents match the following: 编辑jmxremote.password文件,是的该文件内容如下所示:
myRole foo
yourRole bar
Note that two new roles have been defined with their own passwords. 注意上面两个新角色都定义了各自的密码.
Now edit the jmx.access file to include the two new roles so that the contents match the following: 下面编辑jmx.access文件,使用上述新定义的两个角色名称,是的该文件的内如下所示:
myRole readwrite
yourRole readonly
Note how the roles in the jmxremote.access and jmxremote.password files correspond to one another.

The last requirement is to enable  password authentication on the JMX agent.  To do so,  remove the  com.sun.management.jmxremote.authenticate property  from the SUNJMX variable in the ActiveMQ  startup script. Here’s an example  of removing this property from the ActiveMQ startup script for Linux/Unix:

需要注意jmxremote.access和jmxremote.password是如何根据角色名称关联到对方的.

最后需要在JMX代理上开启密码验证.为此,需要从ActiveMQ启动脚本的SUNJMX参数中移除 com.sun.management.jmxremote.authenticate属性.下面是Linux/Unix中移除ActiveMQ 启动脚本中该属性的示例代码:

if [ -z "$SUNJMX" ] ; then
SUNJMX="-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=1099
-Dcom.sun.management.jmxremote.ssl=false"
fi
And here’s an example of removing this property from the ActiveMQ startup script for Windows: 下面是Windows中移除ActiveMQ启动脚本中该属性的示例代码:
if "%SUNJMX%" == "" set SUNJMX=-Dcom.sun.management.jmxremote ^
-Dcom.sun.management.jmxremote.port=1099 ^
-Dcom.sun.management.jmxremote.ssl=false
After removing the com.sun.management.jmxremote.authenticate property, the last thing to do is make sure that the user running the JVM has access to the jmxremote. password file. 移除了com.sun.management.jmxremote.authenticate属性后,最后需要做的工作是确保运行JVM的用户有jmxremote.password文件的存取权限.
NOTE After copying the jmxremote.password.template file, chances are that you’ll need to change the permissions on that file to disallow read access. If read access is allowed on the jmxremote.password file, the following error will potentially rear its head when starting up ActiveMQ: 注意,拷贝jmxremote.password.template文件为新文件之后,你需要修改新文件的存取权限不允许读取该文件.如果允许读取jmxremote.password文件,那么在启动ActiveMQ时可能会出现下面的错误:
$ ./bin/activemq console
Error: Password file read access must be restricted:
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/lib/ \
management/jmxremote.password
The only thing left to do is start up ActiveMQ and make sure that there are no errors: 最后要做的就是启动ActiveMQ并保证没有任何错误出现:
$ ./bin/activemq console
INFO: Using default configuration
(you can configure options in one of these file:
/etc/default/activemq /Users/bsnyder/.activemqrc)
INFO: Invoke the following command to create a configuration file
./bin/activemq setup [ /etc/default/activemq |
/Users/bsnyder/.activemqrc ]
INFO: Using java
'/System/Library/Frameworks/JavaVM.framework/Home/bin/java'
INFO: Starting in foreground, this is just for debugging purposes
(stop process by pressing CTRL+C)
Java Runtime: Apple Inc. 1.6.0_22
/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
Heap sizes: current=258880k free=253105k max=258880k
JVM args: -Xms256M -Xmx256M
-Dorg.apache.activemq.UseDedicatedTaskRunner=true
-Djava.util.logging.config.file=logging.properties
-Dcom.sun.management.jmxremote
-Dactivemq.classpath=/Users/bsnyder/amq/apache-activemq-5.4.1/conf;
-Dactivemq.home=/Users/bsnyder/amq/apache-activemq-5.4.1
-Dactivemq.base=/Users/bsnyder/amq/apache-activemq-5.4.1
ACTIVEMQ_HOME: /Users/bsnyder/amq/apache-activemq-5.4.1
ACTIVEMQ_BASE: /Users/bsnyder/amq/apache-activemq-5.4.1
Loading message broker from: xbean:activemq.xml
WARN | destroyApplicationContextOnStop parameter is deprecated,
please use shutdown hooks instead
INFO | PListStore:/Users/bsnyder/amq/apache-activemq-5.4.1/data/
localhost/tmp_storage started
INFO | Using Persistence Adapter: KahaDBPersistenceAdapter
[/Users/bsnyder/amq/apache-activemq-5.4.1/data/kahadb]
INFO | ActiveMQ 5.4.1 JMS Message Broker (localhost) is starting
INFO | For help or more information please see:
http://activemq.apache.org/
INFO | Scheduler using directory:
/Users/bsnyder/amq/apache-activemq-5.4.1/data/localhost/scheduler
INFO | JobSchedulerStore:/Users/bsnyder/amq/apache-activemq-5.4.1/data/
localhost/scheduler started
INFO | Listening for connections at: tcp://mongoose.local:61616
INFO | Connector openwire Started
INFO | ActiveMQ JMS Message Broker
(localhost, ID:mongoose.local-50084-1292777410913-0:0) started
INFO | Logging to org.slf4j.impl.JCLLoggerAdapter
(org.eclipse.jetty.util.log) via org.eclipse.jetty.util.log.Slf4jLog
INFO | jetty-7.0.1.v20091125
INFO | ActiveMQ WebConsole initialized.
INFO | Initializing Spring FrameworkServlet 'dispatcher'
INFO | ActiveMQ Console at http://0.0.0.0:8161/admin
INFO | Initializing Spring root WebApplicationContext
INFO | Connector vm://localhost Started
INFO | Camel Console at http://0.0.0.0:8161/camel
INFO | ActiveMQ Web Demos at http://0.0.0.0:8161/demo
INFO | RESTful file access application at http://0.0.0.0:8161/fileserver
INFO | Started SelectChannelConnector@0.0.0.0:8161
Now  start up  JConsole on  a remote  machine and  attempt to  use JConsole  to remotely connect to ActiveMQ. Figure 14.5 shows what will happen when attempting to remotely log in to the JMX  agent using a role name and password  that don’t exist in the jmxremote.access/jmxremote.password file pair. To successfully make a remote connection  to the JMX  agent, you must  use the correct  role name and password as shown in figure 14.6. 现在可以在远程机器上启动JConsole并尝试远程连接到ActiveMQ上.图14.5展示了从远程机器 上尝试使用jmxremote.access/jmxremote.password文件组合中不存在的角色名和密码访问 JMX代理是会出现的问题.你必须使用正确的使用角色名和密码才能成功的连接到JMX代理,如图 14.6所示.
Hopefully these  advanced JMX  configurations will  help you  with your ActiveMQ configurations and  your ability  to properly  configure access.  Beyond the JMX features for  monitoring and  managing ActiveMQ,  there are  additional means of monitoring  the  inner workings  of  ActiveMQ via  what  are known  as  advisory messages. 希望这些高级的JMX配置能够提升你的ActiveMQ配置能力和控制访问ActiveMQ的能力.除了使用 JMX,还有其他的方式可以监控ActiveMQ的内部工作,即使用advisory消息.
赞 赏

   微信赞赏  支付宝赞赏


本文固定链接: https://www.jack-yin.com/coding/translation/activemq-in-action/1814.html | 边城网事

该日志由 边城网事 于2014年01月10日发表在 ActiveMQ in Action 读书笔记 分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
原创文章转载请注明: 14.1 JMX API和ActiveMQ | 边城网事

14.1 JMX API和ActiveMQ 暂无评论

发表评论

快捷键:Ctrl+Enter