I have a java web application which uses some form of custom message queuing via a database table (EmailQueue) to queue delivery of emails. The application is deployed on Tomcat and uses Quartz jobs which polls for new entries in the EmailQueue table to send.
I now need to add queuing of a few other types of jobs and messages (notifications, sms, etc.) and am therefore looking into using a proper message queue (RabbitMQ, ActiveMQ, etc.) instead of the database. This is motivated by a few articles on the matter which argue a database should not be used as a queue.
I haven't completely gotten my mind wrapped around the whole ecosystem however and would appreciate some guidance. Specifically:
In the context of web applications, does the message queue broker usually run as its own process, like the database does? I need the messages to be persistent in case of server restarts.
Should the message queue consumers be deployed as servlets in Tomcat or as standalone java applications? I'm especially interested in the manageability of it all (i.e. start/stop instances, configuration, monitoring) Related question and email thread.
1. In the context of web applications, does the message queue broker usually run as its own process, like the database does? I need the messages to be persistent in case of server restarts.
The message queue broker typically runs as its own process. With RabbitMQ, your producers can define the messages to be persistent.
2. Should the message queue consumers be deployed as servlets in Tomcat or as standalone java applications? I'm especially interested in the manageability of it all (i.e. start/stop instances, configuration, monitoring) Related question and email thread.
Regarding my question on a similar topic here, I ultimately deployed my consumers as Tomcat applications, which did provide me with the manageability that I too was looking for. This allowed me to write servlets for monitoring and managing the queues.
This solution works for scalability, also, which is important with messaging & queuing. I was also able to easily scale the number of consumers on the fly by taking a snapshot of the server running Tomcat (I was using Amazon EC2 instances) and deploying that snapshot onto a new instance. I had configured Tomcat to start automatically as a service so that when the new instance started, the consumer .war files would deploy and automatically start consuming.
Be careful with the threading, however, as discussed in my question. I had initially run into problems with stopping Tomcat.
You can also achieve manageability with consumers as standalone Java applications using JMX, however. Using JConsole, you can remote into your Java applications and query/update parameters during runtime. Many monitoring programs, such as Zabbix, can connect to applications using JMX.
If you enjoy web development and building your own web applications, I would go the Tomcat route. Hope that helps.
A good choice! Message oriented middleware is already written and will save you some trouble - instead of reinventing the wheel.
In full profile Java EE servers, the messaging system is usually an integrated part.
For tomcat, look at TomEE+ or similar for an idea of how ActiveMQ and Tomcat is working together.
ActiveMQ can easily be deployed either as an embedded broker inside your servlet or as a standalone process. It's just a matter of manageability and what you prefer. I would consider a standalone ActiveMQ, since you might want to add more Tomcat servers in some scenario, and point both to the same ActiveMQ server. RabbitMQ is not running on Java, but an Erlang platform - so that is something different.
That is up to your architecture and what you feel is more comfortable to manage. Deployed as servlets seems like a reasonable approach as you might have monitoring and other things in place already.
You could as well run the mailing service inside ActiveMQ itself. You can easily embed spring beans in the ActiveMQ configuration - or, preferably, run Camel Routes with mail functionality that does these kind of things with simple XML configuration. If you have a lot of logic in the mailing consumer, it should probably be kept as a part of the servlet application.
Related
Hey guys I am trying to display a maintenance message on my web page while I wanna deploy an updated war, so the original war must go offline first and at the same time, client will get 404 not found error page...My question is, what is the most common way for website maintenance? Thanks!
PS: I am not specifying which server is being used, so it could be tomcat, jboss, websphere and etc.
Ideally, you'll want some kind of hot-deployment support so that your users won't ever notice a service interruption. Common methods of achieving this are:
Having multiple instances of the web application behind some kind of load balancer which directs incoming requests to a running instance. If you'd perform a deployment, you wouldn't take all instances offline at once, but sequentially take one instance offline, redeploy, restart, and repeat this sequentially for all other instances.
Code-based hot-swapping while the software is running. The Oracle's JVM has limited support for this (HowSwap). A popular commercial tool which enables redeployments (using more sophisticated mechanisms than HotSwap) of Java web apps is LiveRebel.
I do understand that using the same tomcat instance for a number of web applications has some risks (e.g. if one web application crashes tomcat it will terminate the other web applications as well.). The benefit is of course cost effectiveness since one server is enough and having all the web applications in one place makes it very easy to administrate.
Are there any industry guidelines on how a good setup with multiple web applications on tomcat should look like?
Pros
One JVM to monitor
Common libraries can be shared (sometimes risky)
Cons
Common HTTP thread pool all applications are using (you can, however, configure several connectors with different thread pools)
One malfunctioning application can take down the whole server
Restarting one application requires restarting all of them (if not using hot-deployment)
You are right that hosting of multiple we applications on one application server / web container (either Tomcat or other) has benefits.
You mentioned the robustness issue when one application may cause failure of another. But let's simplify this: even if you have only one application you still want 24*7 availability. To achieve this goal people typically run more than one instance of application server with identical application on each one and load balancer in the enterence to the site. The same is relevant for several web applications. Just run N (2 as minimum) application servers with identical set of web applications deployed and load balancer. You will probably need a kind of watchdog that restarts server if it failed or if it stopped responding etc.
In some cases kind of clustering is required. But it is other story.
I have a system that consists of several thick client apps that communicate with each other. The apps currently communicate directly with each other over rmi but I a exploring options for using a messaging framework, specifically camel.
I know camel can be run in standalone (often when we do testing) but is often deployed in a container or esb. Is it appropriate to run camel in standalone mode if the only apps communicating with it are desktop (swing) apps?
Well yes and no. Camel is a message router, it helps you defining routes for your calls. However it will not help you choosing communication protocol. It just makes the integration quicker and faster (for example use JMS to communicate App1 <-> App2, RMI for App2 <-> App3 and some other protocol for App2 <-> App3).
Yes, Camel might be deployed in Standalone version. Here is link how to do this. I would advice to create separate application (I would also use Shade Maven plugin here to embed all dependencies).
You might also consider using some ESB, for example Servicemix or Fuse. However this is pretty big environment...
Actually, a vanilla installation (unzip that is) of ActiveMQ (5.5.1 for instance) will come bundled with Camel. Simply edit conf/activemq.xml and insert somewhere. Configure camel at conf/camel.xml. ActiveMQ does not come with all Camel components, so simply drop any additional camel jar file into /lib. You can easy just drop any of your own .jar files that for instance definies a RouteBuilder etc. in /lib to.
To communicate between applications I would use a standalone ActiveMQ broker (typically two instances for failover) and embed camel into the thick client applications. You can then use the pojo messaging features in camel to achieve almost transparent communication.
See my blog for an example http://www.liquid-reality.de/x/NoBe
We have a java server application which runs certain batch jobs. It's core function is not as a web application and there's no reason for it to be that. But we would like to add an option to check what the app is doing from a web page. And we thought this could be nicely done with the Google Web Toolkit.
In any previous experiences we have with GWT we have deployed it on Tomcat. But in this case it seems like overkill. The web part is more of a side function to what the application is actually doing.
I'm thinking of a solution where the web server is integrated into the jar file - perhaps Jetty? So that the full java application can be deployed to a single jar file together with the web/GWT part.
There may be performance aspects to this but the web side of things will have very few users. Are there any other reasons not to do it this way?
And, can you give some advice on how to configure Eclipse / Ant / Jetty / GWT for this?
we had the similar experience at our previous project. There was an eclipse-rcp application, with embedded Jetty server (it was started programmatically when application was starting). GWT application was deployed into the Jetty as usually. Also there was a OSGI-service as a controller to provide communication between GWT-server and other parts of application. GWT server was usual RCP server, which is described in the most of examples. It had a reference to the controller. Moreover, it was an event listener, to support bot-side communication.
The main problem for us I think, was synchronization problem. Since there were a lot of messages between eclipse-rcp application an GWT-part (every let say 100 ms the message was received) and GWT had an asynchronous way of communication between client part and its server part, then some mechanism had to be created to synchronize those messages. Otherwise there were no performance problems (except IE 6. which had to be supported:S :D).
Hope this will somehow help.
Upd: As far as I remember, the controller was registered as OSGI service only to be able to communicate with other services of Eclipse-RCP part. In order to communicate with GWT controller was implementing special interface, which was known to the GWT-server (Controller was registered as an implementer through instantiation and the server was regsitered in the controller as IMessageListener). This interface was lying in separate project, which could was also built into the .war file. This project also contained number of event to support backward communication from controller to GWT-server through IMessageListener interface.
It's kind of confusing probably, sorry. May be I should draw a diagram..
I'd like to use the Java Message Service but it says it's for the Java EE Platform. Is there a way to port it to a regular Java application (which I'm working on in Eclipse)?
JMS is part of the Java EE spec, but you can use it from any Java application. Depending on your needs, you may have to run a standalone broker, but this is just like running a regular daemon (or Windows service).
Yes, you absolutely can use JMS from a J2SE application. In fact, you can access a JMS broker from programs not written in Java at all. The ActiveMQ JMS server includes several transport connectors. The connectors allow clients to interact with ActiveMQ using different communication protocols. Most Java clients use the openwire connector. I've written a PHP client that used the STOMP protocol with great success. It consumed messages sent to a JMS Queue by a Java application running in the Tomcat Servlet Container.
This is a much more complicated question than the answer would indicate. Jms is a spec. Really just a set of interfaces. You can absolutley use those interfaces from a standalone java process. Hell you could write your own jms compliant messaging implementation. Questions you should be asking yourself is what messaging implementation will i be using and does it support jms? Even after answering that there are numerous caveats to take into account when connecting to brokers outside of a container including but not limited to transactionality, load balancing, connection pooling, and high availability. You should be very clear about what your trying to do and what messaging vendor you are working with before you can answer this completely
Many Messaging servers also provides their java api for the communication like MQ, open source Apache ActiveMQ. In that case you don't realy need to worry about JMS. You simply need to understand and use that API.