You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by smt <sm...@yandex.ru> on 2009/05/04 10:40:09 UTC

No way to use activeMQ via http. TCP works fine, but not http. Please help.

I developed simplest application where
client sends array of Integers as ObjectMessage to Server.
Server application calculates sum of this values and return the result as
ObjectMessage back to Client.
Other words, it is simplest example ever.

When I use tcp protocol (tcp://loc
http://www.nabble.com/file/p23364910/task_jms_issue.zip task_jms_issue.zip
alhost:61616) everything works fine.

However after setting http
http://www.nabble.com/file/p23364910/task_jms_issue.zip task_jms_issue.zip 
http://www.nabble.com/file/p23364910/task_jms_issue.zip task_jms_issue.zip 

(just added
<transportConnector name="http" uri="http://localhost:8080"/>
to activemq.xml)

I see really bad performance.
Sometimes Server handle 20 clients and blocked, sometime it's able to server
50 clients then blocked.
If I stop client application, then start it again there can be delay of 20
seconds!!! until it create the jms connection.
I face some IOException like SocketTimeOutException.

But with tcp EVERYTHING WORKS fine even with thousands of clients.
Unfortunately we may not use tcp cause we have to support
proxy servers and http tunneling in the production.

Below I attach maven project for the issue. It contains 3 files.
ServerThread.java, ClientThread.java and Constants.java
It's enough to change BROKER_URL val in Constants.java to switch http and
tcp mode communication.

1) ServerThread.java

public class ServerThread extends Thread {
    private MessageProducer replyProducer;

    public ServerThread() throws JMSException {
        ConnectionFactory factory = new
ActiveMQConnectionFactory(Constants.BROKER_URL);
        Connection jmsConnection = factory.createConnection();
        jmsConnection.start();
        QueueSession session = ((QueueConnection)
jmsConnection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
        Destination adminQueue = session.createQueue(Constants.QUEUE_NAME);
        replyProducer = session.createProducer(null);
        replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        MessageConsumer consumer = session.createConsumer(adminQueue);
        consumer.setMessageListener(new MessageListener() {
            public void onMessage(Message message) {
                new Thread(new OnMessageRunnable(message)).start();
            }
        });
    }

    @Override
    public void run() {

    }

    private class OnMessageRunnable implements Runnable {
        private Message message;

        public OnMessageRunnable(Message message) {
            this.message = message;
        }

        public void run() {
            try {
                ObjectMessage incomingMessage = (ObjectMessage) message;
                Integer[] vals = (Integer[]) incomingMessage.getObject();
                Integer result = 0;
                for (Integer val : vals) {
                    result += val;
                }

                Destination outgoingDestination = message.getJMSReplyTo();

                ObjectMessage outgoingMessage = new ActiveMQObjectMessage();
                outgoingMessage.setObject(result);

                replyProducer.send(outgoingDestination, outgoingMessage);
            }
            catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        try {

            new ServerThread().start();
        } catch (JMSException e) {
            e.printStackTrace();  //To change body of catch statement use
File | Settings | File Templates.
        }
    }

}

2) ClientThread.java

public class ClientThread extends Thread {
    private QueueSession queueSession;
    private static Object LOCK_OBJECT = new Object();
    private static Integer finished = 0;


    public ClientThread() throws JMSException {
        ConnectionFactory factory = new
ActiveMQConnectionFactory(Constants.BROKER_URL);
        Connection jmsConnection = factory.createConnection();
        jmsConnection.start();
        System.out.println("Connection started");
        queueSession = ((QueueConnection)
jmsConnection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    }

    @Override
    public void run() {
        try {
            Queue outgoingQueue =
queueSession.createQueue(Constants.QUEUE_NAME);
            ObjectMessage outgoingMessage = new ActiveMQObjectMessage();

            TemporaryQueue incomingQueue =
queueSession.createTemporaryQueue();
            MessageConsumer consumer =
queueSession.createConsumer(incomingQueue);

            outgoingMessage.setJMSReplyTo(incomingQueue);
            outgoingMessage.setObject(new Integer[]{1, 2, 3});
            MessageProducer producer =
queueSession.createProducer(outgoingQueue);
            producer.send(outgoingQueue, outgoingMessage);

            Message message = consumer.receive();
            ObjectMessage objectMessage = (ObjectMessage) message;
            System.out.println("" + objectMessage.getObject());
            incFinishedCount();
        } catch (JMSException e) {
            e.printStackTrace();  //To change body of catch statement use
File | Settings | File Templates.
        }
    }

    private static void incFinishedCount(){
        synchronized (LOCK_OBJECT){
            ++finished;
        }
    }

    public static void main(String[] args) {
        try {
            System.out.println("Connection started");
            int clientsCount = 100;
            for (int i = 0; i < clientsCount; i++) {
                new ClientThread().start();
            }
            while (clientsCount > finished ){
                //do nothing
            }
            System.out.println("Finished");
        } catch (JMSException e) {
            e.printStackTrace();  //To change body of catch statement use
File | Settings | File Templates.
        }
    }
}

3) Constants.java



public interface Constants {
    String QUEUE_NAME = "QUEUE";

    // to check tcp
    String BROKER_URL = "tcp://localhost:61616";

    // to check http
    //String BROKER_URL = "http://localhost:8080";
}


I'll be really thankful for your help in this issue.
Thank you, guys.
-- 
View this message in context: http://www.nabble.com/No-way-to-use-activeMQ-via-http.-TCP-works-fine%2C-but-not-http.-Please-help.-tp23364910p23364910.html
Sent from the ActiveMQ - User mailing list archive at Nabble.com.


Re: No way to use activeMQ via http. TCP works fine, but not http. Please help.

Posted by Dejan Bosanac <de...@nighttale.net>.
Hi,

there's currently an effort to improve http transport for 5.3 release

https://issues.apache.org/activemq/browse/AMQ-2238

Please post all your comments there and I'll try to resolve them.

Cheers
--
Dejan Bosanac

Open Source Integration - http://fusesource.com/
ActiveMQ in Action - http://www.manning.com/snyder/
Blog - http://www.nighttale.net

On Mon, May 4, 2009 at 9:43 PM, Jose Luna <j-...@rocketmail.com> wrote:

>
>
> > Jose Luna-2 wrote:
> > >
> > > I don't have any recommendation regarding activemq and HTTP but you may
> > > consider tunneling openwire through SSL
> > > (http://activemq.apache.org/ssl-transport-reference.html).    If you
> set
> > > your broker up to use port 443, proxies won't be able to distinguish
> > > between this traffic and HTTPS, so the traffic will be allowed to pass
> > > through.   Actually, you would be able to get away with running the
> > > traffic over port 443 without using the SSL transport, but that somehow
> > > seems more deceptive ;) .   For more info, see
> > > http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 .
> > >
> > >
> > >
> > >
> > Thank you for your reply, sir.
> > Other words, you telling I may use 443 port via tcp. An my clients will
> be
> > able to connect to server through this port even if they under the proxy.
> > Correct?
> >
> > Any way, guys, could you provide me other solutions, please.
> >
> > Thank you.
>
>
> Yes.  It's just a suggestion that I thought you might find useful.  You
> will need to be able to do the HTTPS handshake (see the ietf.org link I
> sent in my previous email).  You will also need to be able handle proxy
> authentication for users that requrie it, but that's something you would
> have to handle anyway if you are dealing with proxies.
>
>
>
>
>

Re: No way to use activeMQ via http. TCP works fine, but not http. Please help.

Posted by Jose Luna <j-...@rocketmail.com>.

> Jose Luna-2 wrote:
> > 
> > I don't have any recommendation regarding activemq and HTTP but you may
> > consider tunneling openwire through SSL
> > (http://activemq.apache.org/ssl-transport-reference.html).    If you set
> > your broker up to use port 443, proxies won't be able to distinguish
> > between this traffic and HTTPS, so the traffic will be allowed to pass
> > through.   Actually, you would be able to get away with running the
> > traffic over port 443 without using the SSL transport, but that somehow
> > seems more deceptive ;) .   For more info, see
> > http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 .
> > 
> >    
> > 
> > 
> Thank you for your reply, sir.
> Other words, you telling I may use 443 port via tcp. An my clients will be
> able to connect to server through this port even if they under the proxy.
> Correct?
> 
> Any way, guys, could you provide me other solutions, please.
> 
> Thank you.


Yes.  It's just a suggestion that I thought you might find useful.  You will need to be able to do the HTTPS handshake (see the ietf.org link I sent in my previous email).  You will also need to be able handle proxy authentication for users that requrie it, but that's something you would have to handle anyway if you are dealing with proxies.



      

Re: No way to use activeMQ via http. TCP works fine, but not http. Please help.

Posted by smt <sm...@yandex.ru>.


Jose Luna-2 wrote:
> 
> I don't have any recommendation regarding activemq and HTTP but you may
> consider tunneling openwire through SSL
> (http://activemq.apache.org/ssl-transport-reference.html).    If you set
> your broker up to use port 443, proxies won't be able to distinguish
> between this traffic and HTTPS, so the traffic will be allowed to pass
> through.   Actually, you would be able to get away with running the
> traffic over port 443 without using the SSL transport, but that somehow
> seems more deceptive ;) .   For more info, see
> http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 .
> 
>    
> 
> 

Other words, you telling I may use 443 port via tcp. An my clients will be
able to connect to server through this port even if they under the proxy.
Correct?

Any way, guys, could you provide me other solutions, please.

Thank you.

-- 
View this message in context: http://www.nabble.com/No-way-to-use-activeMQ-via-http.-TCP-works-fine%2C-but-not-http.-Please-help.-tp23364910p23374981.html
Sent from the ActiveMQ - User mailing list archive at Nabble.com.


Re: No way to use activeMQ via http. TCP works fine, but not http. Please help.

Posted by Jose Luna <j-...@rocketmail.com>.
> I developed simplest application where
> client sends array of Integers as ObjectMessage to Server.
> Server application calculates sum of this values and return the result as
> ObjectMessage back to Client.
> Other words, it is simplest example ever.
> 
> When I use tcp protocol (tcp://loc
> http://www.nabble.com/file/p23364910/task_jms_issue.zip task_jms_issue.zip
> alhost:61616) everything works fine.
> 
> However after setting http
> http://www.nabble.com/file/p23364910/task_jms_issue.zip task_jms_issue.zip 
> http://www.nabble.com/file/p23364910/task_jms_issue.zip task_jms_issue.zip 
> 
> (just added
> 
> to activemq.xml)
> 
> I see really bad performance.
> Sometimes Server handle 20 clients and blocked, sometime it's able to server
> 50 clients then blocked.
> If I stop client application, then start it again there can be delay of 20
> seconds!!! until it create the jms connection.
> I face some IOException like SocketTimeOutException.
> 
> But with tcp EVERYTHING WORKS fine even with thousands of clients.
> Unfortunately we may not use tcp cause we have to support
> proxy servers and http tunneling in the production.
> 
> Below I attach maven project for the issue. It contains 3 files.
> ServerThread.java, ClientThread.java and Constants.java
> It's enough to change BROKER_URL val in Constants.java to switch http and
> tcp mode communication.
> 
> 1) ServerThread.java
> 
> public class ServerThread extends Thread {
>     private MessageProducer replyProducer;
> 
>     public ServerThread() throws JMSException {
>         ConnectionFactory factory = new
> ActiveMQConnectionFactory(Constants.BROKER_URL);
>         Connection jmsConnection = factory.createConnection();
>         jmsConnection.start();
>         QueueSession session = ((QueueConnection)
> jmsConnection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
>         Destination adminQueue = session.createQueue(Constants.QUEUE_NAME);
>         replyProducer = session.createProducer(null);
>         replyProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
>         MessageConsumer consumer = session.createConsumer(adminQueue);
>         consumer.setMessageListener(new MessageListener() {
>             public void onMessage(Message message) {
>                 new Thread(new OnMessageRunnable(message)).start();
>             }
>         });
>     }
> 
>     @Override
>     public void run() {
> 
>     }
> 
>     private class OnMessageRunnable implements Runnable {
>         private Message message;
> 
>         public OnMessageRunnable(Message message) {
>             this.message = message;
>         }
> 
>         public void run() {
>             try {
>                 ObjectMessage incomingMessage = (ObjectMessage) message;
>                 Integer[] vals = (Integer[]) incomingMessage.getObject();
>                 Integer result = 0;
>                 for (Integer val : vals) {
>                     result += val;
>                 }
> 
>                 Destination outgoingDestination = message.getJMSReplyTo();
> 
>                 ObjectMessage outgoingMessage = new ActiveMQObjectMessage();
>                 outgoingMessage.setObject(result);
> 
>                 replyProducer.send(outgoingDestination, outgoingMessage);
>             }
>             catch (Exception e) {
>                 e.printStackTrace();
>             }
>         }
>     }
> 
>     public static void main(String[] args) {
>         try {
> 
>             new ServerThread().start();
>         } catch (JMSException e) {
>             e.printStackTrace();  //To change body of catch statement use
> File | Settings | File Templates.
>         }
>     }
> 
> }
> 
> 2) ClientThread.java
> 
> public class ClientThread extends Thread {
>     private QueueSession queueSession;
>     private static Object LOCK_OBJECT = new Object();
>     private static Integer finished = 0;
> 
> 
>     public ClientThread() throws JMSException {
>         ConnectionFactory factory = new
> ActiveMQConnectionFactory(Constants.BROKER_URL);
>         Connection jmsConnection = factory.createConnection();
>         jmsConnection.start();
>         System.out.println("Connection started");
>         queueSession = ((QueueConnection)
> jmsConnection).createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
>     }
> 
>     @Override
>     public void run() {
>         try {
>             Queue outgoingQueue =
> queueSession.createQueue(Constants.QUEUE_NAME);
>             ObjectMessage outgoingMessage = new ActiveMQObjectMessage();
> 
>             TemporaryQueue incomingQueue =
> queueSession.createTemporaryQueue();
>             MessageConsumer consumer =
> queueSession.createConsumer(incomingQueue);
> 
>             outgoingMessage.setJMSReplyTo(incomingQueue);
>             outgoingMessage.setObject(new Integer[]{1, 2, 3});
>             MessageProducer producer =
> queueSession.createProducer(outgoingQueue);
>             producer.send(outgoingQueue, outgoingMessage);
> 
>             Message message = consumer.receive();
>             ObjectMessage objectMessage = (ObjectMessage) message;
>             System.out.println("" + objectMessage.getObject());
>             incFinishedCount();
>         } catch (JMSException e) {
>             e.printStackTrace();  //To change body of catch statement use
> File | Settings | File Templates.
>         }
>     }
> 
>     private static void incFinishedCount(){
>         synchronized (LOCK_OBJECT){
>             ++finished;
>         }
>     }
> 
>     public static void main(String[] args) {
>         try {
>             System.out.println("Connection started");
>             int clientsCount = 100;
>             for (int i = 0; i < clientsCount; i++) {
>                 new ClientThread().start();
>             }
>             while (clientsCount > finished ){
>                 //do nothing
>             }
>             System.out.println("Finished");
>         } catch (JMSException e) {
>             e.printStackTrace();  //To change body of catch statement use
> File | Settings | File Templates.
>         }
>     }
> }
> 
> 3) Constants.java
> 
> 
> 
> public interface Constants {
>     String QUEUE_NAME = "QUEUE";
> 
>     // to check tcp
>     String BROKER_URL = "tcp://localhost:61616";
> 
>     // to check http
>     //String BROKER_URL = "http://localhost:8080";
> }
> 
> 
> I'll be really thankful for your help in this issue.
> Thank you, guys.

I don't have any recommendation regarding activemq and HTTP but you may consider tunneling openwire through SSL (http://activemq.apache.org/ssl-transport-reference.html).    If you set your broker up to use port 443, proxies won't be able to distinguish between this traffic and HTTPS, so the traffic will be allowed to pass through.   Actually, you would be able to get away with running the traffic over port 443 without using the SSL transport, but that somehow seems more deceptive ;) .   For more info, see http://tools.ietf.org/html/draft-luotonen-web-proxy-tunneling-01 .