jboss中如何使用jms

Jboss中实现了HornetQ,这个应该是jms消息中间件


在 standalone-all.xml,我们能看到其默认的配置

<subsystemxmlns="urn:jboss:domain:messaging:1.2">

            <hornetq-server>

               <persistence-enabled>true</persistence-enabled>

               <journal-file-size>102400</journal-file-size>

               <journal-min-files>2</journal-min-files>

                <connectors>(hornetq有connector和acceptor概念,connector和acceptor都有两种in-vm 和netty,只有同一种类型的connetor和acceptor才能联合使用,in-vm表明connetor和acceptor在同一个java虚拟机中,netty表示不在一个vm中)

                    …..

                </connectors>

                <acceptors>

                      ….

                </acceptors>

                <security-settings>

                                     …

                </security-settings>

                <address-settings>

                    <!--default for catchall-->

                    <address-settingmatch="#">(匹配任意队列)

                       <dead-letter-address>jms.queue.DLQ</dead-letter-address>(如果消息的重试处理次数超过了最大尝试次数,会被移入这个队列)

                       <expiry-address>jms.queue.ExpiryQueue</expiry-address>(如果消息过期了,会被移入这个队列)

                        <redelivery-delay>0</redelivery-delay>(重试处理的时间间隔,如果是0,就是立即重试)

                       <max-size-bytes>10485760</max-size-bytes>(队列最多可以存多少字节的数据)

                       <address-full-policy>BLOCK</address-full-policy>(如果队列满了,对新加入消息的处理策略)

                       <message-counter-history-day-limit>10</message-counter-history-day-limit>

                    </address-setting>

                </address-settings>

               <jms-connection-factories>

                    <connection-factoryname="InVmConnectionFactory">

                        <connectors>

                            <connector-refconnector-name="in-vm"/>

                        </connectors>

                        <entries>

                            <entryname="java:/ConnectionFactory"/>

                        </entries>

                    </connection-factory>

                    <connection-factoryname="RemoteConnectionFactory">

                        <connectors>

                            <connector-refconnector-name="netty"/>

                        </connectors>

                        <entries>

                            <entryname="java:jboss/exported/jms/RemoteConnectionFactory"/>

                        </entries>

                    </connection-factory>

                   <pooled-connection-factory name="hornetq-ra">(定义其resource adapter)

                        <transactionmode="xa"/>

                        <connectors>

                            <connector-refconnector-name="in-vm"/>

                        </connectors>

                        <entries>

                            <entryname="java:/JmsXA"/>

                        </entries>

                   </pooled-connection-factory>

               </jms-connection-factories>

            </hornetq-server>

        </subsystem>

 

我们使用jms,只要在standalone.xml的hornetq-server定义中修改参数或者增加消息队列地址

然后实现相关发送消息和处理消息的代码就可以了

实例:

新增一个队列,实现一个ejb,调用这个ejb的notifyEvent 方法可以向这个队列增加信息,实现一个mdb可以消费这个队列上的消息,每处理一个消息,记录一个log
开发时使用slf4j来记录log,所以开发时需要导入这些jar包:jboss-client.jar,slf4j-api-*.jar,部署时不需要这些包,因为jboss server都提供了

步骤如下

1.     新增一个队列地址为MyEventQueue

在standalone.xml 增加定义

a.     指定使用messaging module

<extensionmodule="org.jboss.as.messaging"/>

b.     增加hornetq-server定义,可以将standalone-full.xml中关于org.jboss.as.messaging subsystem 的定义拷贝过来

c.     增加队列定义

hornetq-server定义增加以下元素,因为前面hornetq-server中使用了dead letter 队列以及expire queue,所以在这里

也定义了这两个队列,我们实际使用的和业务相关的队列是MyEventsQueue

          <jms-destinations>

                    <jms-queuename="DLQ">

                        <entryname="/queue/DLQ"/>

                    </jms-queue>

                    <jms-queuename="ExpiryQueue">

                        <entryname="/queue/ExpiryQueue"/>

                    </jms-queue>

                    <jms-queuename="MyEventsQueue">

                        <entryname="/queue/MyEventsQueue"/>

                    </jms-queue>

                </jms-destinations>

d.     因为后续我们使用mdb来处理消息队列的消息,所以我们在<subsystem xmlns="urn:jboss:domain:ejb3:1.3">中增加如下的定义

指定其相关的resource adapter为hornetq-ra

<mdb>

                <resource-adapter-refresource-adapter-name="hornetq-ra"/>

                <bean-instance-pool-refpool-name="mdb-strict-max-pool"/>

 </mdb>

这样mdb可以处理hornetq server发出的消息

e.     因为我们在hornetq server中指定了一些socket-binding,所以在<socket-binding-group>中我们得增加相关的定义

        <socket-bindingname="messaging" port="5445"/>

        <socket-bindingname="messaging-throughput" port="5455"/>

2. 定义一种event,这个event是普通类,需要扩展Serializable接口,表明其可以序列化

  public class MyEvent implements Serializable {

    private static final long serialVersionUID =-8851617570957121969L;

    private String messageBody;

     public MyEvent(Stringbody){

         this.messageBody = body;

     }

    public String getMessageBody() {

        return messageBody;

    }

    public voidsetMessageBody(String messageBody) {

        this.messageBody = messageBody;

   }

}

3.     实现一个ejb,调用这个ejb的notify方法,会给这个消息队列发送

public interface EventSender{

     void notifyEvent();

}

@Stateless

@Remote(EventSender.class)

public class EventSenderBean implements EventSender {

   private static String destination = "java:/queue/MyEventsQueue";

   private static final Logger logger = LoggerFactory.getLogger("EventLog");

   @Override

   public void notifyEvent() {

       QueueConnection queueConnection = null;

       QueueSession queueSession = null;

       Queue queue = null;

       QueueSender publisher = null;

       

       try

       {

       //TODO Auto-generatedmethod stub

       

       InitialContext ctx = null;

       ctx = new InitialContext();

       //获得消息队列的connection factory

       QueueConnectionFactory cf = (QueueConnectionFactory) ctx.lookup("java:/ConnectionFactory");

       //获得对应消息队列

       queue = (Queue) ctx.lookup(destination);

       //使用connection 工厂创建connection,并启动

       queueConnection = cf.createQueueConnection();

       queueConnection.start();

      //创建会话

       queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);

       //创建sender

       publisher = queueSession.createSender(queue);

       publisher.setDeliveryMode(DeliveryMode.NON_PERSISTENT);

       //发送消息,发送消息应该不用每次都创建connection,会话和sender,应该可以使用已创建的这些对象

       for(int i = 0 ; i < 10;i++){

            MyEvent event = new MyEvent("event " + i );

            logger.info("send message: "+event.getMessageBody());

            final ObjectMessagemessage = queueSession.createObjectMessage(event); 

            publisher.send(message);

           

       }

       }catch(Exception e){

            logger.error(e.getLocalizedMessage());

            logger.info("errormessage",e.getStackTrace());

       }finally{

            if(queueConnection!=null){

                try {

                    queueConnection.close();

                } catch (JMSException e) {

                    // TODO Auto-generatedcatch block

                    logger.info("shutdownconnection error",e.getStackTrace());

                }  }}  }}

 

4. 实现mdb,消费这个队列上的消息

 

import javax.ejb.MessageDriven;

import javax.ejb.ActivationConfigProperty;

import javax.jms.Message;

import javax.jms.MessageListener;

import javax.jms.ObjectMessage;

import org.slf4j.*;

 

@MessageDriven(activationConfig = {

        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),

        @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/queue/MyEventsQueue") })

public class EventConsumerMDB  implements MessageListener{

   private static final Logger logger = LoggerFactory.getLogger("EventLog");

  

    @Override

    public void onMessage(Messagemessage) {

        if(message instanceof ObjectMessage){

            try{

            ObjectMessage receiveMessage =(ObjectMessage)message;

            Object body =receiveMessage.getObject();

            if(body instanceof MyEvent){

                logger.info("receivemessage: " + ((MyEvent)body).getMessageBody());

            }

            }catch(Exception e){

                logger.error(e.getMessage());

                logger.info("consumemessage" , e);

            }}}}

5.客户端调用ejb的notifyEvent方法发送消息

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值