JMX远程监控ActiveMQ设置

96
程序员小哥哥 Excellent
0.3 2017.07.25 18:04* 字数 974

本地消息队列:我们在下载好的activemq文件夹下的config文件夹下,找到activemq.bat文件运行,浏览器访问 http://activemq-host:8161/admin

activemq-host是启动机器的ip地址,8161是activemq的默认端口号,默认用户名和密码是admin。会进入一下界面:


image

当然,这是本地的消息队列,访问,我们启动之后也可以通过jdk自带的jconsole来监控。这里重点介绍怎样远程监控activemq。

远程监控activemq:这里涉及到JMX的概念,网上我也搜了很多,我也看的不是很明白,这里大家知道由Java开发的程序,一般都是jmx来监控就可以了,当然,activemq也是通过Jmx来监控的。这里首先我们来配置一些东西。

1.在你下载activemq文件夹下的config中,找到activemq.xml,在broker节点增加useJmx="true"

image

2.在managementContext节点更改成下面的截图的样子(这里我直接截图了,增加的东西不多,我就不把能复制的放进来了,自己敲敲,熟悉一下~)


image

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"

截图版:


image

4.在Linux上进入${active_home}/bin中执行chmod 655 activemq用来获取active的权限,我们解压activemq之后,发现在bin的activemq是灰色,不能正常启动就执行activemq restart这条命令。执行完这条命令之后,会变成绿色。

image

然后执行chmod 400 ${activemq_home}/conf/jmx. 意思是设置当前用户只读,其他用户没有权限。

接下来在${activemq_home}/bin下执行activemq start或者activemq restart,一般在前面加sudo,一般用户没权限。
activemq stop来停止或者用ps显示当前运行的activemq的线程号,然后kill即可。

好了,接下来,我们来用jdk自带的jconsole来检测一下。


image

默认用户名:admin
密码:activemq

这里有可能出现还远程不上的情况:这里有我尝试了下有两种解决办法

  • 关闭远程服务器上的防火墙(当然,这个不推荐,容易被黑客攻击)
  • 修改hosts文件,添加远程实际的Ip地址
image

当然,我们在实际项目中可能不单单登录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才可以~~~~

我的编程世界
Web note ad 1