并发JMS消息导致NULL

时间:2014-06-27 15:15:33

标签: java concurrency jms weblogic

我已经测试了串行和并发发送的JMS消息(5个线程同时从生产者发送jms消息)。

当我同时发送100条消息时,接收端的有效负载很少为NULL。串行发送时没有问题。

我是否需要设置会话池或在消费者端使用MDB来同时处理消息? JMS的设置很好,因为我们正在接收消息。我在这里错过了什么吗?

pproject设置的简短描述:

  1. Publisher是无状态会话bean
  2. 通过检索Weblogic 8.1 jms服务器连接工厂和目的地 JNDI
  3. Consumer是一个订阅此服务器JMS队列的java类 并执行任务。 (这不是MDB或Threaded类,侦听队列 异步地)
  4. EDITED

    JmsConsumer
    
    package net;
    
    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.Date;
    import java.util.Hashtable;
    
    import javax.jms.ExceptionListener;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageListener;
    import javax.jms.Queue;
    import javax.jms.QueueConnection;
    import javax.jms.QueueConnectionFactory;
    import javax.jms.QueueReceiver;
    import javax.jms.QueueSession;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    
    public class ReadJMS implements MessageListener, ExceptionListener {
    
        public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
        public final static String PROVIDER_URL = "t3://address:7003";
    
        public final static String JMS_FACTORY = "MSS.QueueConnectionFactory";
        public final static String QUEUE = "jms.queue";
    
        @SuppressWarnings("null")
        public void receiveMessage() throws Exception {
            // System.out.println("receiveMessage()..");
            Hashtable env = new Hashtable();
            env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
            env.put(Context.PROVIDER_URL, PROVIDER_URL);
    
            // Define queue
            QueueReceiver qreceiver = null;
            QueueSession qsession = null;
            QueueConnection qcon = null;
            ReadJMS async = new ReadJMS();
            try {
                InitialContext ctx = new InitialContext(env);
    
                QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx
                        .lookup(JMS_FACTORY);
                qcon = qconFactory.createQueueConnection();
                qcon.setExceptionListener(async);
                qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
                Queue queue = (Queue) ctx.lookup(QUEUE);
                qreceiver = qsession.createReceiver(queue);
                qreceiver.setMessageListener(async);
    
                qcon.start();
                System.out.println("readingMessage()..");
                // TextMessage msg = (TextMessage) qreceiver.receive();
                // System.out.println("Message read from " + QUEUE + " : "
                // + msg.getText());
                // msg.acknowledge();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            // } finally {
            // if (qreceiver != null)
            // qreceiver.close();
            // if (qsession != null)
            // qsession.close();
            // if (qcon != null)
            // qcon.close();
            // }
        }
    
        public static void main(String[] args) throws Exception {
            ReadJMS test = new ReadJMS();
            System.out.println("init");
            test.receiveMessage();
            while (true) {
                Thread.sleep(10000);
            }
        }
    
        public void onException(JMSException arg0) {
            System.err.println("Exception: " + arg0.getLocalizedMessage());
        }
    
        public synchronized void onMessage(Message arg0) {
            try {
                if(((TextMessage)arg0).getText() == null || ((TextMessage)arg0).getText().trim().length()==0){
                    System.out.println(" " + QUEUE + " : "
                            + ((TextMessage) arg0).getText());
                }
                System.out.print(".");
                PrintWriter out = new PrintWriter(new BufferedWriter(
                        new FileWriter("Output.txt", true)));
                Date now = new Date();
                out.println("message: "+now.toString()+ " - "+((TextMessage)arg0).getText()+"");
                out.close();
    
            } catch (JMSException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    

    WriteJms

    package net;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Hashtable;
    
    import javax.jms.Queue;
    import javax.jms.QueueConnection;
    import javax.jms.QueueConnectionFactory;
    import javax.jms.QueueSender;
    import javax.jms.QueueSession;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.naming.Context;
    import javax.naming.InitialContext;
    
    public class WriteJMS {
        public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory";
        public final static String PROVIDER_URL = "t3://url:7003";
        public final static String JMS_FACTORY = "MSS.QueueConnectionFactory";
        public final static String QUEUE = "jms.queue";
    
        @SuppressWarnings("unchecked")
        public void sendMessage() throws Exception {
    
            @SuppressWarnings("rawtypes")
            Hashtable env = new Hashtable();
            env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY);
            env.put(Context.PROVIDER_URL, PROVIDER_URL);
    
            // Define queue
            QueueSender qsender = null;
            QueueSession qsession = null;
            QueueConnection qcon = null;
            try {
                InitialContext ctx = new InitialContext(env);
    
                QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx
                        .lookup(JMS_FACTORY);
                qcon = qconFactory.createQueueConnection();
    
                qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
                Queue queue = (Queue) ctx.lookup(QUEUE);
    
                TextMessage msg = qsession.createTextMessage();
                msg.setText("<eventMessage><eventId>123</eventId><eventName>123</eventName><documentNumber>123</documentNumber><customerId>123</customerId><actDDTaskDate>123</actDDTaskDate><taskStatusErrorMessage>123</taskStatusErrorMessage></eventMessage>");
                qsender = qsession.createSender(queue);
                qsender.send(msg);
                System.out.println("Message [" + msg.getText()
                        + "] sent to Queue: " + QUEUE);
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                if (qsender != null)
                    qsender.close();
                if (qsession != null)
                    qsession.close();
                if (qcon != null)
                    qcon.close();
            }
        }
    
    
    }
    

1 个答案:

答案 0 :(得分:0)

众所周知,禁止在多个线程中重用会话。但你不这样做。您可以为每条消息重新创建所有内容(连接会话和生产者)。这是低效的,但不是不正确的,不应该导致这些错误。你给我们的代码对我来说很好。

我有点惊讶的是发送方没有例外。您能否提供有关JMS实施的更多详细信息?也许消息代理的日志中有更多信息?

您是否计算过邮件并且收到的号码是否与发送的金额相等?其他人可以将消息发送到同一个队列吗?