I am aware that the Tibco EMS provides Fault Tolerance in a hot backup configuration on the server side as detailed in the User's Guide, this answer and here.
But on the client side does Tibco EMS provide out of the box solution for fault-tolerant clients?
An example: on the topic Sports.F1.PitStop two clients (server1, server2) register as publishers. The idea being that should something go wrong on server1 (i.e. publisher on server1 goes down), server2 would seamlessly continue to publish on the topic. So the question is, does Tibco EMS provide such client-side fault-tolerance capability?
No.
EMS (or JMS) does not support a client-side fault tolerance feature. The reason is simple : typically, publishers processes don't know each other.
To elaborate:
Topics usually accepts many publishers (more than two).
In a pub/sub scenario, publishers don't know subscribers, and to an extent they don't typically know the other publishers.
Your solution:
My first question regarding your solution: Why can't both servers publish messages at the same time ?
I assume you have a good reason (like messages from server1 and server2 being redundant). In that case, then you will have to have some kind of communication between your "active" and "passive" server.
Possibility 1 : Server2 is connected to a simple service/rmi/other heartbeat mechanism, and can tell if/when Server1 as stopped publishing.
Possibility 2 : Server2 is itself subscribed to the topic, and can tell when messages have stopped.
Last note:
In case you meant shared "subscriptions" (as in, one durable subscription being shared between two servers): the new JMS 2.0 API is supporting this feature. EMS 8 is the only version of EMS supporting JMS 2.0.
I'm not sure if I fully understand your question. EMS is a message broker. It brokers messages. Thats all it does. If you have multiple servers publishing to the same topic, then that is fine for EMS. If your publishers themselves are in a fail-over configuration, so that only one is actively sending and the other takes over when the first one fails, then EMS doesn't care.
Managing the fail-over mechanism from one publisher to the other, that is something you have to develop yourself. EMS doesn't offer anything to support that. You need some kind of mechanism for server2 to know when server1 is down. There are several ways you can do that:
Use a heartbeat mechanism where the active server sends periodical heartbeat messages (possibly across EMS as well) and the passive server listens to them and when they stop, assume server1 is down.
Use an active open connection between server1 and server2 (open a simple tcp port for example and stop it from closing automatically by periodically sending a dummy message), and have an open read on that port. You'll get a connection error the moment server1 goes down and you don't have to wait for timeouts on heartbeats.
Use a third party monitoring tool, such as openview, tivoli or nagios to detect server1 is down and inform server2.
There is a feature on EMS you can use. EMS has system admin topics that you can subscribe to and that log basically anything that goes on internally. You can subscribe to connect and disconnect events to monitor any component connecting to or disconnecting from EMS. If server1 fails, this will be visible as a disconnect event.
heartbeat mecanism:
https://support.tibco.com/s/article/Tibco-KnowledgeArticle-Article-33918
For example:
client_heartbeat_server=10
client_timeout_server_connection=35
server_heartbeat_client=10
server_timeout_client_connection=35
Related
Previously I have setup a device to connect to Google Cloud IoT Core and when the device would connect it would get a callback from the server to a topic with the device configuration file.
I am currently moving off of that to a local MQTT broker on a Raspberry Pi with Mosquitto running. What I am trying to do is figure out how to replicate the sending of the configuration file when connected.
Is there a way for other clients to know when a new client connects? If so I could then just have a client running on the Pi that would is responsible for sending messages.
The thought was that the Pi would hold the configuration file of the connected device and once it connects it would be sent back over to it via a topic for that device
Or is there another solution that I dont even know about yet that accomplishes this? I have not set up my own end to end MQTT communication before so I dont exactly have a path forward here
Is there a way for other clients to know when a new client connects?
Not as part of the protocol; but it's simple enough to publish a message upon connection. I can see a few ways of accomplishing your aim:
Publish all of the configurations as retained messages. You would require a 'config' topic per device for this (say config/uniquedevicename). When the client starts up it will subscribe to the relevant topic and receive its configuration (the 'server' would need to publish a message to each of the config channels with the retain flag set).
Upon starting the device publishes a message requesting its configuration; the server is subscribed to the relevant topic and responds with the configuration. You can use preset topics for the response or pass the topic in as part of the request.
For one (or a small number of devices) option 1 would be very simple to implement; however option 2 provides more flexibility.
Here is my use case:
I have two endpoints: one with MQ and the second with TCP/IP
I have to replace a legacy server which accepts queries from remote TCP/IP clients. Once the socket is open with the client, data is exchanged in both sides. the server sends asynchronously MQ data through TCP/IP and receive data from clients asynchronously also. Each data message sent has to be acknowledged. The constraint here is that I have to use the same socket.
I created two routes
from("netty4:tcp://ipAddress:port?sync=true").to("wmq:queue:toQueue")
from("wmq:queue:fromQueue").to("netty4:tcp://ipAddress:port?sync=true")
I start the first queue to receive session open request from clients and then I start the second route to start sending data but I cannot use the same channel.
I tried to get the remote port of the first route and used it in the second route but I have a ConnectException because netty4 tries to open a new socket which is already open.
I found that netty4 can be used asynchronously using the AsyncProcessor but I didn't find any example dealing with my use case.
The only idea I found is that I have to create a standalone server which open the sockets with the clients and make it communicate with the two endpoints.
Is there any way to implement this situation using camel only?
any help on this subject is really appreciated.
Your code won't be able to run as it is for your use case. I also suspect you are trying to use Camel as IP server framework and not an integration in this case.
Lets review Apache Camel's concept of producers and consumers. In the integration world we talk about client and servers as consumers and producers. This might seem like a language difference until you realise a consumer(typically a client) can also be a producer(server).
Some helpful definitions:
1. Producer: A producer is an entity capable of creating and sending a message to an endpoint. A typical example would be code like .to("file:data/outbox") as this produces a file.
2. Consumer: A consumer is an entity that receives messages produced by a producer, it wraps these messages in an exchange and sends them to be processed. A typical example would be code like from(jms:topic:xmlOrders)
A rule of thumb is that typically consumers are the source of the messages being routed.
BIG NOTE:
These two definitions are not set in stone a producer can also be an endpoint using the from and a consumer can be an endpoint using the to.
So in your case let's break up the route:
from("netty4:tcp://ipAddress:port?sync=true").to("wmq:queue:toQueue")
In this route you are creating a Netty server that sends a message to a queue. Here your netty endpoint acts as a consumer(yes it is in the from clause) however this creates a Netty4 Server at the IP address and endpoint you specified. This then send a message to another consumer which is the MQ client which act as a consumer again. So two consumers? Where is the producer? The client connecting to the netty server will act as producer.
Let's look at the second piece of the route:
from("wmq:queue:fromQueue").to("netty4:tcp://ipAddress:port?sync=true")
Here you are creating a client/consumer for the MQ services and then creating a client/producer to the netty server. Essentially you are creating a NEW client here that connects to the SERVER you created in the first route.
So in short your route creates a Netty server that send a message to MQ then creates a MQ client that sends a message to a Netty client which connects to the server you have created. It wont work like this.
Go read about message exchange patterns for further reading, but I would suggest that if you are just using Netty and MQ then maybe Camel is a bit overkill as it is a integration platform and not a IP server platform.
I'm using Rebus (https://github.com/rebus-org (v.0.83)) and until now it's been all local to a single machine. Now I need to use a remote queue from my website to an app server. It's not abundantly clear to me how to set this up with Rebus. A few questions
I guess I need MSMQ on both machines (web & app) correct? I've configured the web site to UseMsmqInOneWayClientMode;
or is there a way to specify to send it over http?
My configuration looks like this more or less. I'm guessing that inputQUeue needs to point to the local machine not the remote one right?
<rebus inputQueue="mywebqueue" errorQueue="MyErrorQueue#mymachine" workers="1" maxRetries="5">
<endpoints>
<add messages="MyLibrary.CreateMessage, MyLibrary" endpoint="MyQueue#mymachine"/>
</endpoints>
</rebus>
Help would really be appreciated.
Yes. All machines that need to use MSMQ somehow, need to have MSMQ installed. Even as a one-way client, like your webserver, because MSMQ achieves its high availability by providing outgoing queues when you send to remote machines.
I think so. I've never used MSMQ beyond its basic reliable messaging capabilities. Google around, I bet you can find something ;)
Your configuration looks right. And yes - input queues are always local, whereas queues you send to (error queue and all endpoints specified in the endpoint mappings) can be remote too.
We've developed a MassTransit based demo which is working well as long as all processes run on the same server.
However, as sonn as my receiver wants to subscribe himself at another machine it hangs for a while and afterwards we receive the following exception:
"System.InvalidOperationException: Timeout waiting for subscription service to respond."
Checked already: Firewall rules for MSMQ (inbound and outbound), network, etc.
What could have gone wrong?
Subscription queues on the other machine are private? Is this a problem?
Do we have to change the address format in some special way? msmq://computerName/queueName not ok for remote connections?
Looks like we have forgotten some tiny thing, as nobody else had this problem before...
The most likely thing is MT assumes somethings about remote queues - that they are transactional. Local queues can be queried to discover that, but remote queues you cannot. I would add ?tx=false to the end of your remote queue URI if you aren't using transactional queues for the subscription service.
Next, double check the outgoing queues on the local machine. Are the message stuck there or did they disappear? If you are using transactional queues, can the machines enroll in a DTC transaction together?
Answering your question, all queues are private. This is not a problem, they are still remotely addressable.
I hope this helps get you further. After that, I would consider joining the mailing list and posting your questions there: https://groups.google.com/forum/?fromgroups#!forum/masstransit-discuss
For reference: the problem has been a wrong URL in the receiver queue, the receiver queue always resides on the local system of course. Sorry for any inconvenience.
If I am using MSMQ over the web, what happens if the network connection is lost between client and server?
So can you still add messages to the Queue, and if so where are they stored? In the client app, or in the clients OS etc?
For instance if I have a windows service which is adding items to a queue in a different country. What if the network connection is lost, and the windows service is restarted. Do the messages get lost forever?
The other part of the question relates to the route that a message takes, is it sent directly to the receiving queue, or is it written into a queue on the client side? Does that require MSMQ to be installed on the sending server, and how about licensing for that?
Is there any good documentation to explain the required setup?
Update: Regarding your follow up question. Yes you have to install msmq on the sending server. There aren't any licensing cost, because MSMQ is part of windows and not a separate software (just like the IIS). Here is documentation on "Setting Up a Message Queue" on windwos 2003.
Before Update: Outgoing message are stored in the outgoing queue of the sending server. They are not lost if the sending service is restarted. They will wait in the outgoing queues ( which can be inspected with the msmq manager ) for I don't know how long.
if the msmq service or the sending server are restarted. Then "express" messages will be lost. express or recoverable are properties of non-transcriptional messages.