I'm designing a replacement for a custom messaging system that is currently used to notify a JavaScript web application about changed content from the server side (Java). This legacy messaging system works through Flash XMLSocket by use of custom text based protocol and plain Java sockets.
The replacement will be used not only by the web application (through web sockets instead of Flash) but by an additional desktop client application written in C# too.
My requirements are:
user authentication
transport encryption (SSL/TLS)
bidirectional message exchange
some sort of (automatic) publish/subscribe so that users get only the messages they are allowed to receive
message exchange based on an established protocol (so that we may use existing libraries where possible)
cluster-able server components
At this time the messaging system will only be used to publish updates down to the clients. The clients will react to these messages and acquire further information directly from the server (not via the messaging system). If this new messaging system is established successfully it may be used for more advanced use cases in the future. Some possibilities may include users chatting, file exchange and remote control of the server components.
I did a little research about viable technology to implement these requirements and I think my choices boil down to either using ejabberd (XMPP) or RabbitMQ (AMQP). What are the main pros and cons of these two systems regarding my requirements? We already use RabbitMQ for other parts of our system infrastructure so it was my natural choice. I'm just not sure if it would be a good idea to have client applications connect directly to such an critical main component. This may be mitigated though by just using a different RabbitMQ installation for the client notifications.
Well you could use both protocols to fulfill your needs, xmpp is an extensible protocol so no doubt the things that you're looking for does allready exist as a plugin or whatever is the correct term for a protocol. However some, me included, might actually see this as a downside, and they add extra complexity to the protocol. Another thing to keep in mind is that xmpp was primarily designed to be a instant messaging protocol. For example publish/subscribe is an extension of xmpp and not part of the protocol itself.
That being said xmpp is backed by organisations such as Google, which means that there are some major players using this protocol, so no doubt some of the extensions are really good and well written/thought out.
On the other hand you have AMQP, a protocol almost specifically designed for what you're after. It is backed by such organisations as JP Morgan, Cisco, Credit Suisse etc. so no doubt AMQP is a protocol to be counted on, even though early versions of it has been critized
When it comes to using RabbitMQ there seem to be some issues with memory, however I cannot speak much of that since I was only notified about this issue, and never really got into actually fix it or even understand it. However there seem to be quite a few people experiencing this on different versions of RMQ.
But for me RabbitMQ has never crashed (hey if erlang is known for one thing, it's stability), it has been a joy to setup and it is really easy to setup in a cluster, and you can have your queues easily mirrored on several instances of RMQ and you can have an extra layer of security by having one or more instances write messages to disk.
So I'd say go with RabbitMQ and AMQP, I believe it's a protocol well suited for your needs, but having said that xmpp could probably do the work just fine aswell.
I've read this book, which is a nice introduction to AMQP and RabbitMQ but I find it lacking in the technical aspect, it's basically a good tutorial.
PS: I feel I should be honest and say that I'm not really sure what bidirectional message exchange entails, but if it means sending and receiving messages, you're in the clear on that point also with AMQP. :)
I hope this helped shed some light on which protocol to choose.
Edit
RabbitMQ has something called virtual hosts which acts like an own instance of RabbitMQ so you don't have to start with setting up a cluster just to handle separate responsibilities. Depending on how you set up your queues and exchanges I don't see a problem with clients connecting to the RabbitMQ server, but clustering is without a doubt a good idea. It also seems that setting up RabbitMQ with HAProxy is very easy, but yet again that is something I have no experience of.
Related
I am working with several different services which have been written in Python and Java. I have now come to the point where I need to have these services communicate with each other and ActiveMQ seems to be a sensible choice.
However, I am not sure I quite follow the concept of the different protocols available for ActiveMQ. The main question being, do I have to implement all my services to use the same protocol for accessing the bus?
Is it possible to run the same bus with multiple different connection protocols concurrently?
If yes to 1. Is it just connection to the bus which is governed by a Protocol or does the protocol choice also influence the type of the actual message content. I.e. will it be possible to post a message from Java JMS to a topic and have a Python STOMP client read that message correctly?
Inter language interopability can be made by different clients using the same protocol, such as JMS for Java, CMS for C++ and NMS for .NET (when it comes to OpenWire). I don't think there is a great OpenWire Python client out there, except some CMS wrappers.
On the other hand, ActiveMQ does a great job to bridge between different protocols so that they can share the same queues/topics. It works really well to read stomp, MQTT and AMQP messages sent from OpenWire/JMS. Please be aware that you may want to avoid advanced features of say JMS like MapMessage, rely on specific JMS headers and stick to simple text messages or byte messages. The bridge is not 100% transparent, but as I said, does a great job.
So, you can go with stomp or even AMQP 1.0, some instruction from Microsoft here.
This question arises as I came across some mentions (such as this), about using a Messaging software such as ZeroMQ alongwith Redis, but I keep hearing about Redis itself used a messaging-system. So, if Redis is used along with other messaging systems, does it mean Redis has some serious deficiencies when used as a messaging system by itself ?
While the use of Redis for caching and pub/sub is clear to me, it is not clear if Redis can be used in place of a full-fledged messaging system such as JMS, AMQP or ZeroMQ.
Leaving alone the standards-compliance aspect and only concentrating on the functionality/features, does Redis provide support for all the messaging patterns/models required of a messaging system ?
The messaging patterns I am talking about are :
RPC/Request-reply (an
example
using ActiveMQ/JMS and another using RabbitMQ/AMQP)
Pipeline/Work queues (once and atmost once consumption of each message)
Broadcast (everyone subscribed to the channel)
Multicast (filtering of messages at server based on consumers' selectors)
Any other messaging pattern ?
If yes, then Redis seems to solve two (possibly more) aspects at once: Caching and Messaging.
I am looking at this in the context of a web-application backed by a Java/Java EE server.
And I am looking at this not from a proof-of-concept point-of-view but from a large-scale software development angle.
Edit1:
user:791406 asked a valid question:
"Who cares if redis supports those patterns; will redis meet your SLA
and QoS needs?"
I thought it is better to give this detail as part of the question instead of in the comments section.
My current needs are less to do with SLA and QOS and more to do with choosing a tool for my job (messaging) that I can use even when my requirements grow (reasonably) in future.
I am starting with simplistic requirements at first and we all know requirements tend to grow.
And NO, I am not looking for a one tool that does it all.
I just want to know if Redis fulfills the usual requirements expected out of a messaging system, like ActiveMQ/RabbitMQ does. Ofcourse, if my SLA/QOS needs are extreme/eccentric, I would need to get a special tool for satisfying that. For ex: In some cases ZeroMQ could be chosen over RabbitMQ due to specific SLA requirements. I am not talking about such special requirements. I am focusing on average enterprise requirements.
I was afraid (based on my little understanding) that eventhough redis could be used as a basic tool for my messaging needs of today, it might be the wrong tool for a real messaging job in future. I have experiences with messaging systems like ActiveMQ/RabbitMQ and know that they could be used for simple to (reasonably) complex messaging needs.
Edit2:
The redis website mentions "Redis is often used as a messaging server" but how to achieve the messaging patterns is not clear.
Salvatore sanfilippo mentions Redis users tend to use it as a database, as a messaging bus, or as a cache. To what extent can it serve as a "messaging bus" is not clear.
When I was trying to find out what messaging requirements of JMS that redis doesnt support, I came across something that Redis supports but JMS doesnt: Pattern-matching subscriptions i.e Clients may subscribe to glob-style patterns in order to receive all the messages sent to channel names matching a given pattern.
Conclusion:
I have decided to use JMS for my messaging needs and use Redis for Caching.
What are you needs?
I think the question you should be asking yourself is "what quality of messaging do I need to support my application?" before deciding on a messaging platform. Who cares if redis supports those patterns; will redis meet your SLA and QoS needs? Focus on that first, then make your technology decision based on that assessment.
Having said that, I'll offer my input on how you can make that decision...
Highly-Reliable/Persistent/Durable Messaging
Let's take an extreme case: say you're building a trading or financial application. Such applications demand strict SLA's where message persistence, reliability, exactly-once delivery and durability are paramount. Using redis as the messaging backbone for this case is probably a bad choice, lots of reasons why...
message redelivery (when the sh*t hits the fan)
message store replication when redis goes down
message transactions (redis can't do XA)
producer/subscriber fault tolerance and disconnection resilience
message order sequencing
sending messages when broker is down (store-and-forward)
single-threaded redis may become bottleneck
If your system has strict SLA's, some or all of these issues will most definitely arise, so how will you handle these limitations? You can implement custom code around redis to address some issues, but why bother when mature messaging platforms like ActiveMq, WebsphereMQ, and WebLogic JMS offer persistence, reliability, and fault tolerance? You said you're on a Java/Java EE stack, so you're in a position to use some of the most robust messaging frameworks available, either open source or commercial. If you're doing financial transactions, then you need to consider these options.
High Performance/Large Distributed Systems Messaging
If you're building a social network or gaming platform where you want performance over reliability, ZeroMq is probably a good fit. It's a socket communication library wrapped in a messaging-like API. It's decentralized (no broker), very fast, and highly resilient and fault tolerant. If you need to do things like N-to-N pub/sub with broker intermediaries, flow control, message persistence, or point-to-point synchronization, ZeroMq offers the necessary facilities and code samples to do it all with minimal code while avoiding building solutions from the ground up. It's written in C but has client libraries for nearly every popular language.
Hope that helps...
I'm looking for a full duplex streaming solution with Java EE.
The situation: client applications (JavaFX) read data from a peripheral device. This data needs to be transferred in near real-time to a server for processing and also get the response back asynchronously, all while it keeps sending new data for processing.
Communication with the server needs to have an overhead as low as possible. Data coming in is basically some sensor data and after processing it is turned in what can be described as a set of commands.
What I've looked into:
A TCP/IP server (this is a non-Java EE approach).This would be the obvious solution. Two connections opened in parallel from each client app: one for upstream data and one for downstream data.
Remote & stateless EJBs. This would mean that there's no streaming involved and that I pack sensor data in smaller windows (1-2 seconds worth of sensor data) which I then send to the server for processing and get the processing result as a response. For this approach, while it is scalable, I am not sure how fast it will be considering I have to make a request each 1-2 seconds. I still need to test this but I have my doubts.
RMI. Is this any different than EJBs, technically?
Two servlets (up/down) with long polling. I've not done this before, so it's something to be tested.
For now I would like to test the performance for my approach #2. The first solution will work for sure, but I'm not too fond of having a separate server (next to Tomcat, where I already have something running).
However, meanwhile, it would be worth knowing if there are any other Java specific (EE or not) technologies that could easily solve this. If anyone has an idea, then please share it.
This looks like a good place for using JMS. Instead of stateless EJBs, you will probably be using Message-Driven Beans.
This gives you an approach similar to your first solution, using two message queues instead of TCP/IP connections. JMS makes your communications fully asynchronous and is low-overhead in the sense that your clients can send messages as fast as they can regardless of how fast your server can consume them. You also get delivery guarantees and other JMS goodness.
Tomcat does not come with JMS, however. You might try TomEE or integrate your existing Tomcat with a JMS implementation like ActiveMQ.
There are numerous options you could try. Appropriate solutions depend on the nature of your application, communication protocol, data transfer type, control you have over the client and server and firewall restrictions on client server routes.
There's not much info on this in your question, but given what you have provided, you may like to look at netty as it is quite general purpose and flexible and seems to fit your requirements. Netty also includes a duplex websocket implementation. Note that a netty based solution may be more complex to implement and require more background study than some other solutions (such as jms).
Yet another possible solution in GraniteDS, which advertises a JavaFX client integration and multiple server integrations for full duplex client/server communication, though I have not used it. GraniteDS uses comet (your two asynchronous servlets with long polling model) with the Active Message Format for data which you may be familiar with from Flex/Flash.
Have you looked at websockets as a solution? They are known to keep persistent connections and hence the asynchronous response will be quick.
I've seen a bunch of screencasts demonstrating the integration between blazeds and flex, also some lcds tutorials, model driven or not.
I've seen that some of them the presenter opens 2 browsers and once you change one value in a grid, it propagates to all other grids that presents the data.
I am wondering how the heck this is done, and how to reproduce.
Does this feature depends of the Edge / LCDS solution? I don't think so, but I've never seen some code explaining about it.
I feel it may or may not rely on JMS / MQ / messaging protocols or if this is some sort of 2 way sync and propagation of collection between instances of the same service result.
Thanks for any inputs.
Cheers,
Ernani
You can implement this feature both with BlazeDS and LiveCycle Data Services. BlazeDS provides remote and messaging features (the messaging features is the one allowing you to synchronize the data between the clients), LCDS extends BlazeDS adding new features like data management (productivity improvements), PDF generation, EDGE server for dealing with DMZ zones), MDA development, portal integration etc. It also adds some advanced messaging features like message conflation, throttling, reliability.
BlazeDS is free and open source and in my opinion a robust solution, you can use it if you want to synchronize the data between clients. LCDS adds a lot of things, but the LCDS customers should have a large budget.
How does it work? There is no JMS behind for this feature (however BlazeDS can integrate with a JMS provider so you can have one client in broswser and the second one running a SWING application). Instead there are some message queues on the server and a publisher - subscriber graph. In order to push the data from the clients to the server there are several choices, the more advanced are available only on LCDS: HTTP polling, HTTP long polling, HTTP streaming, RTMP sockets (LCDS only). All of them are described in details on Damon blog.
If you want to see some code go and download BlazeDS and take a look on the samples, there are several ones showing the messaging features. Also there a tomcat server is bundled in the download, and the samples are already deployed in it.
To do this you need to keep an open socket connection between the client and the server so that the server can push data back to the client.
I believe that the RTMP protocol was used for this two-way communication.
I understand that this is the primary reason to use LiveCycle Data Services over BlazeDS. WebORB also has push functionality, as does GraniteDS. I've also seen demos where this is done with ColdFusion.
If none of those options are available to you, you're stuck doing some kind of polling to the remote server.
Unfortunately, I do not have specific code samples to share.
A simple sample showing how to do this using WebORB can be found here:
http://www.kensodev.com/2009/11/01/synchronize-client-application-using-flexweborb-net/
That sample is based on WebORB 3 for .NET; WebORB 4 is now available, for both .NET and Java.
Point being: This is brain-dead simple using WebORB, which is FREE (although a paid Enterprise version is also available). God forbid that anyone should shell out $30K for LCDS just to get this feature.
--- Jim Plamondon, Midnight Coders (makers of WebORB)
I'm in the process of writing a client/server application which should work message based. I would like re-use as much as possible instead of writing another implementation and curious what others are using.
Features the library should offer:
client and server side functionality
should work message based
support multi-threading
should work behind load balancer / firewalls
I did several tests with HTTPCore, but the bottom line is that one has to implement both client and server, only the transport layer would be covered. RMI is not an option either due to the network related requirements.
Any ideas are highly appreciated.
Details
My idea is to implement a client/server wrapper which handles the client communication (including user/password validation) and writes incoming requests to a JMS queue:
#1 User --> Wrapper (Check for user/password) --> JMS --> "Server"
#2 User polls Wrapper which polls JMS
Separate processes will handle the requests and can reply via wrapper to the clients. I'd like to use JMS because:
it handles persistence quite well
load balancing - it's easy to handle peaks by adding additional servers as consumer
JMSTimeToLive comes in handy too
Unfortunately I don't see a way to use JMS on it's own, because clients should only have access to their messages and the setup of different users on JMS side doesn't sound feasible either.
Well, HTTP is probably the best supported in terms of client and server code implementing it - but it may well be completely inappropriate based on your requirements. We'll need to actually see some requirements (or at least a vague idea of what the application is like) before we can really advise you properly.
RMI works nicely for us. There are limitations, such as not being able to call back to the client unless you can connect directly to that computer (does not work if client is behind a firewall). You can also easily wrap your communication in SSL or tunnel it over HTTP which can be wrapped in SSL.
If you do end up using this remember to always set the serial version of a class that is distributed to the client. You can set it to 1L when you create it, or if the client already has the class use serialver.exe to discover the existing class's serial. Otherwise as soon as you change or add a public method or variable compatibility with existing clients will break.
static final long serialVersionUID = 1L
EDIT: Each RMI request that comes into the server gets its own thread. You don't have to handle this yourself.
EDIT: I think some details were added later in the question. You can tunnel RMI over HTTP, then you could use a load balancer with it.
I've recently started playing with Hessian and it shows a lot of promise. It natively uses HTTP which makes it simpler than RMI over HTTP and it's a binary protocol which means it's faster than all the XML-based protocols. It's very easy to get Hessian going. I recently did this by embedding Jetty in our app, configuring the Hessian Servlet and making it implement our API interface. The great thing about Hessian is it's simplicity... nothing like JMS or RMI over HTTP. There are also libraries for Hessian in other languages.
I'd say the best-supported, if not best-implemented, client/server communications package for Java is Sun's RMI (Remote Method Invocation). It's included with the standard Java class library, and gets the job done, even if it's not the fastest option out there. And, of course, it's supported by Sun. I implemented a turn-based gaming framework with it several years ago, and it was quite stable.
It is difficult to make a suggestion based on the information given but possibly the use of TemporaryQueues e.g. dynamically created PTP destinations on a per client basis might fit the problem?
Here is a reasonable overview.
Did you tried RMI or CORBA? With both of them you can distribute your logic and create Sessions
Use Spring....Then pick and choose the protocol.
We're standardizing on Adobe's AMF as we're using Adobe Flex/AIR in the client-tier and Java6/Tomcat6/BlazeDS/Spring-Framework2.5/iBATIS2.3.4/ActiveMQ-JMS5.2 in our middle-tier stack (Oracle 10g back-end).
Because we're standardizing on Flex client-side development, AMF and BlazeDS (now better coupled to Spring thanks to Adobe and SpringSource cooperating on the integration), are the most efficient and convenient means we can employ to interact with the server-side.
We also heavily build on JMS messaging in the data center - BlazeDS enables us to bridge our Flex clients as JMS topic subscribers. That is extremely powerful and effective.
Our Flex .swf and Java .class code is bundled into the same .jar file for deployment. That way the correct version of the client code will be deployed to interact with the corresponding middle-tier java code that will process client service calls (or messaging operations). That has always been a bane of client-server computing - making sure the correct versions of the respective tiers are hooked up to each other. We've effectively solved that age-old problem with our particular approach to packaging and deployment.
All of our client-server interactions work over HTTP/HTTPS ports 80 and 443. Even the server-side messaging push we do with BlazeDS bridged to our ActiveMQ JMS message broker.