最近做的项目里面有个需求,一开始的时候不确定有那些队列,根据计算节点的数量创建队列,实现任务更高效的处理.

我们的消息队列用的是HornetQ,是Jboss开源的一个高性能消息队列,遇到了一些问题,这里记录下.

Google了一下,发现也有些人有这样的需求
http://stackoverflow.com/questions/15145247/how-can-i-programmatically-create-jms-topics-and-queues-in-hornetq

答案里面提供了两种方法,一种是使用hornetq的jmx接口来操作,好麻烦的样子,第二种是使用官方提供的ClientSession来创建,第一种方式看了半天,好麻烦,还是直接用官方的api吧.这里说起来用ClientSession处理是简单,但是ClientSession的创建我愣是没在官方的demo里找到.还是最后在stackoverflow找到的.代码如下:

    public void createQueue(String name) throws JMSException {
        try {
            Map<String, Object> connectionParams = new HashMap<String, Object>();
            connectionParams.put(TransportConstants.HOST_PROP_NAME, host);
            TransportConfiguration transportConfiguration = new TransportConfiguration(
                    NettyConnectorFactory.class.getName(), connectionParams);
            ServerLocator serverLocator = HornetQClient
                    .createServerLocatorWithoutHA(transportConfiguration);
            ClientSessionFactory sf = serverLocator.createSessionFactory();

            // Step 4. Create a core queue
            ClientSession coreSession = sf.createSession(true, true);
            coreSession.createQueue("jms.queue." + name, name, true);
        } catch (HornetQException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

上面的host用来指定hornetq的服务器地址.name就是你的queue名称.createQueue方法我们调用的这个有3个参与,第一个是queue的地址,第二个是名称,第三个是是否为持久化队列,如果为false,客户端连接断开之后就会清理掉这个队列.

到这里以为完了,但是执行之后发现,还有问题,抛出异常

javax.jms.JMSSecurityException: HQ119032: User: null doesnt have permission=CREATE_DURABLE_QUEUE on address xxx

意思呢就是用户null没有创建持久队列的权限,hornetq对队列的权限都是可配置的,默认用户为guest,配置在hornetq-users.xml中:

<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd">
   <!-- the default user.  this is used where username is null-->
   <defaultuser name="guest" password="guest">
      <role name="guest"/>
   </defaultuser>
</configuration>

看下guest用户到底有哪些权限呢,在hornetq-configuration.xml中:

   <security-settings>
      <security-setting match="#">
         <permission type="createNonDurableQueue" roles="guest"/>
         <permission type="deleteNonDurableQueue" roles="guest"/>
         <permission type="consume" roles="guest"/>
         <permission type="send" roles="guest"/>
      </security-setting>
   </security-settings>

官方文档中标明了可以配置的一些权限:

HornetQ可以基于地址来给队列定义权限。在定义权限时可以使用通配符'#'和 '*'。

队列的权限有7种,它们是:

createDurableQueue。允许用户在相应的地址上创建持久的队列。

deleteDurableQueue。允许用户在相应的地址上删除相应的持久的队列。

createNonDurableQueue。允许用户在相应地址上创建非持久的队列。

deleteNonDurableQueue。允许用户在相应地址上删除非持久队列。

send。允许用户向相应地址发送消息。

consume。允许用户从相应地址上的队列接收消息。

manage。允许用户调用管理操作,即向管理地址发关管理消息。

更多请参考:
http://hornetq.sourceforge.net/docs/hornetq-2.1.1.Final/user-manual/zh/html_single/index.html#security.settings.roles

but...我添加了对应的权限还是不可以呀...只要下狠手了.官方还有一个配置参数:

<security-enabled>false</security-enabled>

添加到hornetq-configuration.xml即可,功能为直接关闭权限控制,当然这个是有一定风险的,谨慎使用.最保险的就是配置权限和用户,避免匿名用户对队列的操作.

参考:
http://hornetq.sourceforge.net/docs/hornetq-2.1.1.Final/user-manual/zh/html_single/index.html
http://stackoverflow.com/questions/20186643/user-null-doesnt-have-permission-create-durable-queue-on-address
http://stackoverflow.com/questions/15145247/how-can-i-programmatically-create-jms-topics-and-queues-in-hornetq

Comments
Write a Comment