You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@activemq.apache.org by Ilya Kazakevich <Il...@JetBrains.com> on 2014/01/16 18:30:56 UTC

Connect ApacheMQ with web application using JMS

Hello,

There is a servlet container with many concurrent users. Each user request
works in its own thread from pool (tomcat is used)
There is also ApacheMQ server that routes messages for users via JMS.

To send message to user Mary you need to use topic "users.Mary".
So, web server subscribes to this topic when user logs in and unsubscribes
when user logs out.
There are too many users and only few of them are logged into server, so we
can't simply subscribe to "users.*": that would lead to millions of useless
messages travelling over network.

Each time user refreshes page, we need to display her all messages she got
from last time page was refreshed.

We have 2 ideas:

* Use one Connection and one Session for the whole web-app, create consumer
for each user and store it in user session. Each time user opens page we do
receiveNoWait and obtain all messages she got.

* Fetch all messages from all consumers on background thread and store them
in collection, so each request would get them.

I like the first one, but I am not sure accessing one Session from different
threads is good idea.
What do you think?


Ilya Kazakevich


Re: Connect ApacheMQ with web application using JMS

Posted by Jose María Zaragoza <de...@gmail.com>.
2014/1/16 Ilya Kazakevich <Il...@jetbrains.com>:
> Hello,
>
>>-----Original Message-----
>>From: Jose María Zaragoza [mailto:demablogia@gmail.com]
>>Sent: Thursday, January 16, 2014 11:30 PM
>>To: users
>>Subject: Re: Connect ApacheMQ with web application using JMS
> ....
>>A Connection is thread safe, but Sessions, MessageProducers, and
>>MessageConsumers are not. The recommended strategy is to use one Session
> per
>>application thread.
>
> Thank you.
> So, I can store session and consumer in HTTP session and synchronize access
> to it (to prevent access from several browser tabs), right?
> Would not it be too heavy to have 200 sessions and 400 consumers (for 200
> users)?
>
> Or should I get all messages in one thread and then pass them to user
> threads?
>
> Ilya.
>


I think that browser tabs share HTTP session

Anyway, I think that if you 've got 200 concurrent users , you can
create 200 JMS sessions.Why not ? Is it so much 200 threads ? Tomcat
does it to manages HTTP requests
And AMQ PooledConnectionFactory has got several caches . For example,
cache by sessions per connection.

You could be create a shared consumer (singleton) and this consumer
would notify to every session when a message arrives.
And then, every session should check either this message is for it or
not. I think that this could be slow if there are a lot of messages

IMHO, I would get a connection from PooledConnectionFactory and I
would create new consumer per user-session.
And every consumer could subscribe with a selector ( ie, username='Mary' )
And in this case, you could use only one topic . If you want to send a
message to some user, create a message with this selector and send it
to the topic

So, each onMessage() of every consumer (  remember, one per
user-session ) would receive its messages

It's up to you

Regards

RE: Connect ApacheMQ with web application using JMS

Posted by Ilya Kazakevich <Il...@JetBrains.com>.
Hello, 

>-----Original Message-----
>From: Jose María Zaragoza [mailto:demablogia@gmail.com]
>Sent: Thursday, January 16, 2014 11:30 PM
>To: users
>Subject: Re: Connect ApacheMQ with web application using JMS
....
>A Connection is thread safe, but Sessions, MessageProducers, and
>MessageConsumers are not. The recommended strategy is to use one Session
per
>application thread.

Thank you.
So, I can store session and consumer in HTTP session and synchronize access
to it (to prevent access from several browser tabs), right?
Would not it be too heavy to have 200 sessions and 400 consumers (for 200
users)?

Or should I get all messages in one thread and then pass them to user
threads?

Ilya.


Re: Connect ApacheMQ with web application using JMS

Posted by Jose María Zaragoza <de...@gmail.com>.
2014/1/16 Ilya Kazakevich <Il...@jetbrains.com>:
> We have 2 ideas:
>
> * Use one Connection and one Session for the whole web-app, create consumer
> for each user and store it in user session. Each time user opens page we do
> receiveNoWait and obtain all messages she got.
>
> * Fetch all messages from all consumers on background thread and store them
> in collection, so each request would get them.
>
> I like the first one, but I am not sure accessing one Session from different
> threads is good idea.
> What do you think?

A Connection is thread safe, but Sessions, MessageProducers, and
MessageConsumers are not. The recommended strategy is to use one
Session per application thread.

Re: Connect ApacheMQ with web application using JMS

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
On Thu, Jan 16, 2014 at 12:30 PM, Ilya Kazakevich <
Ilya.Kazakevich@jetbrains.com> wrote:

>
> There is a servlet container with many concurrent users. Each user request
> works in its own thread from pool (tomcat is used)
> There is also ApacheMQ server that routes messages for users via JMS.
>

TomEE = Tomcat7 + ApacheMQ + other stuff in the stack for web app, ...


>
> To send message to user Mary you need to use topic "users.Mary".
> So, web server subscribes to this topic when user logs in and unsubscribes
> when user logs out.
> There are too many users and only few of them are logged into server, so we
> can't simply subscribe to "users.*": that would lead to millions of useless
> messages travelling over network.
>

Have you considered PrimeFaces Push (which is PrimeFaces + Atmosphere) or
even just Atmosphere (without PrimeFaces Push)? I am doing something
similar to what you are doing via PrimeFaces Push with not much code, and
performs very well.


> Each time user refreshes page, we need to display her all messages she got
> from last time page was refreshed.
>

PrimeFaces Push and/or Atmosphere will push messages via websocket or long
polling and there are PrimeFaces have ways you can render the messages on
the page for target user...without requiring user to do page refresh.

See PrimeFaces Push FacesMessage example[1]

[1] http://www.primefaces.org/showcase/push/facesmessage.jsf

Re: Connect ApacheMQ with web application using JMS

Posted by artnaseef <ar...@artnaseef.com>.
Have you considered durable subscribers?  That sounds like what you're trying
to accomplish.

Keep in mind, though, that ActiveMQ is not a message store.  If the
subscription consumption is based on user logins and logouts, you are
probably trying to do too much without a separate store of some type.

Perhaps a database into which messages are stored?

The best starting point is to define the following:

* the maximum numbers of messages
* duration of messages pending
* reliability of messaging needed

Keep in mind that (a) Topics don't store messages themselves (subscriptions
do), and (b) that only durable subscriptions ever persist messages.  In
other words, non-durable Topic subscriptions will lose messages on broker
restarts.



--
View this message in context: http://activemq.2283324.n4.nabble.com/Connect-ApacheMQ-with-web-application-using-JMS-tp4676387p4676418.html
Sent from the ActiveMQ - User mailing list archive at Nabble.com.