JMX远程监控ActiveMQ设置
本地消息队列:我们在下载好的activemq文件夹下的config文件夹下,找到activemq.bat文件运行,浏览器访问http://activemq-host:8161/admin。
activemq-host是启动机器的ip地址,8161是activemq的默认端口号,默认用户名和密码是admin。会进入一下界面:
20161107162440331.png当然,这是本地的消息队列,访问,我们启动之后也可以通过jdk自带的jconsole来监控。这里重点介绍怎样远程监控activemq。
远程监控activemq:这里涉及到JMX的概念,网上我也搜了很多,但是特别官网,我也看的不是很明白,这里大家知道由Java开发的程序,一般都是jmx来监控就可以了,当然,activemq也是通过Jmx来监控的。这里首先我们来配置一些东西。
1.在你下载activemq文件夹下的config中,找到activemq.xml,在broker节点增加useJmx="true"
20161107164841436.png2.在managementContext节点更改成下面的截图的样子(这里我直接截图了,增加的东西不多,我就不把能复制的放进来了,自己敲敲,熟悉一下~) 20161107165108593.png
3.在你activemq文件夹下的bin找到activemq(${active_home}/bin/activemq),找到下面截图中出出现的代码,应该是注释掉的,解除注释就行了,我下载的版本是5.13.4,有的没有下面的代码,不知道是什么原因,这个弄明白之后,会再更新。
代码版(这个可以直接粘贴过去):
ACTIVEMQ_SUNJMX_START="-Dcom.sun.management.jmxremote.port=11099"
ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote.password.file=${ACTIVEMQ_CONF}/jmx.password"
ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote.access.file=${ACTIVEMQ_CONF}/jmx.access"
ACTIVEMQ_SUNJMX_START="$ACTIVEMQ_SUNJMX_START -Dcom.sun.management.jmxremote.ssl=false"
截图版:
20161107170019130.png4.在Linux上进入${active_home}/bin中执行chmod 655 activemq用来获取active的权限,我们解压activemq之后,发现在bin的activemq是灰色,不能正常启动就执行activemq restart这条命令。执行完这条命令之后,会变成绿色。
20161107170804155.png然后执行chmod 400 ${activemq_home}/conf/jmx. 意思是设置当前用户只读,其他用户没有权限。
5.接下来在${activemq_home}/bin下执行activemq start或者activemq restart,一般在前面加sudo,一般用户没权限。
activemq stop来停止或者用ps显示当前运行的activemq的线程号,然后kill即可。
好了,接下来,我们来用jdk自带的jconsole来检测一下。
用户名:admin
密码:activemq
这里有可能出现还远程不上的情况:这里有我尝试了下有两种解决办法
- 关闭远程服务器上的防火墙(当然,这个不推荐,容易被黑客攻击)
- 修改hosts文件,添加远程实际的Ip地址
当然,我们在实际项目中可能不单单登录activemq的web console或者jconsole来实现监控,我在项目中就是用java程序来实现跟web console一样的页面展示的形式。接下来引用我实际项目中的代码。
controller
String surl = Constant.MQ_URL;
String userName = Constant.MQ_USERNAME;
String userPwd = Constant.MQ_USERPWD;
Map<String, String[]> env = new HashMap<>();
String[] credentials = {userName, userPwd};
env.put(JMXConnector.CREDENTIALS, credentials);
JMXServiceURL url = new JMXServiceURL(surl);
JMXConnector jmxc = JMXConnectorFactory.connect(url, env);
// JMXConnector jmxc = JMXConnectorFactory.connect(url, null);
MBeanServerConnection mbsc = jmxc.getMBeanServerConnection();
ObjectName mbeanName = new ObjectName("org.apache.activemq:brokerName=localhost,type=Broker");
//MBeanInfo info = mbsc.getMBeanInfo(mbeanName);
BrokerViewMBean mbean =(BrokerViewMBean) MBeanServerInvocationHandler.newProxyInstance(mbsc, mbeanName, BrokerViewMBean.class, true);
List<MqModel> mqList = new ArrayList<MqModel>();
OrganizationService organizationService = (OrganizationService) SpringBeanUtil.getBean("organizationService");
for (ObjectName na : mbean.getQueues()) {
QueueViewMBean queueBean = (QueueViewMBean)MBeanServerInvocationHandler.newProxyInstance(mbsc, na, QueueViewMBean.class, true);
MqModel mq = new MqModel();
Organization organ = organizationService.getOrganization(queueBean.getName());
if(organ!=null){
mq.setName(organ.getOrgName());
}else{
mq.setName(queueBean.getName());
}
mq.setQueueSize(queueBean.getQueueSize());
mq.setConsumerCount(queueBean.getConsumerCount());
mq.setDequeueCount(queueBean.getDequeueCount());
mq.setEnqueueCount(queueBean.getEnqueueCount());
queueBean.getEnqueueCount();
mqList.add(mq);
}
(上面的代码中获取实际数据通过queueBean.__来获取,这里我用一个model来接收了。下面会引入model的代码)
Constant:
public static final String MQ_URL = properties.getProperty("mq.url");//获取mq远程链接地址
public static final String MQ_USERNAME = properties.getProperty("mq.userName");//mq用户名
public static final String MQ_USERPWD = properties.getProperty("mq.userPwd");//mq密码
Model:
/**
* 这里自定义一个Model来接收队列的信息
* @author LY
* @date 2016-08-10 11:11
*/
public class MqModel {
private String name;//队列的名称
private Long queueSize;//队列中剩余的消息数
private Long consumerCount;//消费者数
private Long enqueueCount;//进入队列的总数量
private Long dequeueCount;//出队列的数量
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getQueueSize() {
return queueSize;
}
public void setQueueSize(Long queueSize) {
this.queueSize = queueSize;
}
public Long getConsumerCount() {
return consumerCount;
}
public void setConsumerCount(Long consumerCount) {
this.consumerCount = consumerCount;
}
public Long getDequeueCount() {
return dequeueCount;
}
public void setDequeueCount(Long dequeueCount) {
this.dequeueCount = dequeueCount;
}
public Long getEnqueueCount() {
return enqueueCount;
}
public void setEnqueueCount(Long enqueueCount) {
this.enqueueCount = enqueueCount;
}
}
application.properties:
#消息队列服务配置
my.url = service:jmx:rmi:///jndi/rmi://198.9.4.167:11099/jmxrmi
mq.userName = admin
mq.userPwd = activemq
我遇到的问题:在刚接到这个需求的时候,我搜了很多,把activemq的远程配置第一步完成之后,发现用代码在java程序中控制台总是报权限的错误,不知道为什么,配置也配置好了,后来在stackoverflow看到其他程序猿也遇到这个问题,我看他们怎么实现,修改了下我的代码,就可以了。controller注释的部分是我以前的代码。
Map<String, String[]> env = new HashMap<>();
String[] credentials = {userName, userPwd};
env.put(JMXConnector.CREDENTIALS, credentials);
我发现必须把activemq远程的用户名和密码放在map才可以~~~~