I'm going to implement a distributed message bus over ZeroMQ and I'm trying to make it as efficient as possible. My requirements are:
multiple processes are connected to a bus, some of them are on the same machine, some not.
processes can subscribe to some topics
unfortunately, no multicast (it is not supported in the production environment - Amazon)
I need multilanguage soultion (at least for C++, Haskell and Python)
Approaches I'm considering are:
1. Directory Service + Mesh topology
there is a single Directory Service which has a list of all connected processes and their addresses.
each process connects to DS on start and asks for addresses of others
each process has a Pub and Sub sockets connected to all other processes (mesh topology)
2. Broker
all processes are connected to a broker which distributes messages using Pub socket.
Are there any other/better architectures to use with ZeroMQ to create such message bus?
I suggest you to have a look to nanomsg, which has a built-in BUS topology and some
other interesting ones like SURVEY. It is a library by Martin Sustrik the original zmq
author.
You can find some discussion about BUS on Martin Sustrik blog: http://250bpm.com/blog:17
Related
we work on a AVL (automatic vehicle location) project.
we will have about 300000 vehicle that send their activity info with GSM (Simcard) modem over TCP protocol.
we have a listener developed by C++ that listens to a specific port.
at the moment, we have about 20000 GPS Devices that communicate data with C++ listener on one specific port.
some times many devices wait until port be free. we should have a scalable listener.
is any better solution for this case. i saw some usages of Node.js for same case.
my questions :
1:what is your idea?is Node.js good approach?
2:how design and implement a listener with node.js?
3:any other solution?
I would look on some actor model framework, this will allow your application to scale much better, and have higher throughput (but maybe lower latency), if you have a listener at specific endpoint, this is also a potentially a SPOF (Single point of failure) and also single point of bottleneck(Potentially). The solution depends on the requirements for HA, HR, Scaling and performance and other metric's.
I have now idea regarding actor toolkit for node, here is a github page:
https://github.com/benlau/nactor
The Akka doc talks about a variety of seemingly inter-related Akka technologies without distinguishing much between them:
Akka Networking
Akka Remoting
Akka Clustering
The Akka ZeroMQ module
My understanding is that "Akka Networking" is simply a module/lib that gives Akka the ability to speak to remote actor systems over TCP. Akka Remoting is another module/lib (not contained in the core Akka JAR) that gives Akka the use of Gossip protocols. And Akka Clustering is yet another module/lib that then uses these Gossip protocols to allow remote actor systems to cluster together and sharestate changes in a viral/"service discovery"-esque manner. And my understanding of Akka ZeroMQ is that it accomplishes the same thing as Akka Clustering, except using ZeroMQ as the basis of the network connections and protocols (instead of Gossip).
So first, if my understanding of these different modules/libs are incorrect, please begin by correcting me!
Assuming I'm more or less on target here, then my main concern is that I might have Remote Actor System 1 (RAS1) using Akka Clustering (and hence Gossip) trying to communicate with Remote Actor System 2 (RAS2) which uses Akka ZeroMQ. In this case, we're using two completely different clustering technologies and protocols, so does this mean these two remote systems can't speak to each other, or does special care need to be taken so that they are compatible with each other?
Akka Remoting is what allows for one actor to speak to another actor on a different machine. For Akka Remoting to work you need to know the specific IP address (or hostname), ActorSystem name, and Actor path of the actor you want to talk to. The ActorSystem name can be different in the 2 machines.
Akka Clustering takes away the problem of having to know the specific machine you are talking to (via Cluster-aware Routing or via a Receptionist that listens for machines joining or leaving the cluster). Cluster-aware Routing also allows for things like having a minimum of X instances of an actor running on any machine in the cluster. Akka Clustering uses the Gossip protocol to maintain the list of cluster members. A cluster-enabled application must know the address of at least one host which must always be running to be able to join the cluster. There might be 2, 3 or more, but the idea is that at least one of them must always be up. Akka Clustering is built on top of Akka Remoting.
Although I haven't worked with Akka ZeroMQ, I assume it works similarly to Akka AMQP. I see it more as an alternative to Remoting, in the sense that it enables actors on different machines to talk to each other, with the advantage that none of the actors need to know any specifics about any other machines where actors are running. However, as with Remoting, you need to manually create the actors that receive the messages, whereas with Clustering the cluster takes care of it (as long as you've configured your Routers correctly).
Regarding your last question. The easiest way I can think about for a Cluster to talk to Akka ZeroMQ would be to have one (or several?) actors in the Cluster that talk to ZeroMQ actors (i.e., you can actually mix and match). Have an actor inside the Cluster that listens on the queue, and have another one that publishes the message to the queue. Sort of an Adapter pattern.
I want to connect a single queue to multiple queue managers
(atleast 2 qmgrs). Lets say I have qmgrA and qmgrB as queue managers and it is connected to queueName. I will put a message "Hello" to queueName connected to qmgrA as well as another message "World" on qmgrB. So suppose to be the queueName contains "Hello" and "World".
The question is how can I get those messages simultaneously? Can you give me an example code fragment/snippet for me to atleast have an overview of how can I start coding with that design.
Note: *I am asking for this because for example the qmgrA got disconnected/down for unknown reason, atleast qmgrB is still active
and will get messages on queueName even though qmgrA is disconnected.
By the way, I'm using Websphere MQ v7 C++.
Thanks in advance! :)
The question appears to be asking how to do something that IBM MQ does not do. QMgrs do not "connect" to queues, they host them. Applications do not "connect" to queues except in the abstract JMS sense. They connect to QMgrs and then open queues. However, the requirement that is described of keeping MQ highly available can be met with MQ Clusters, hardware clusters, Multi-Instance QMgrs, shared queues (on z/OS only), or some combination of these.
The two queue managers in your example each host a local copy of queueName. Here are several scenarios as to how messages are distributed in this situation.
PUTting messages
A message put to queueName by an application connected to qmgrA will by default result in the message landing in the local instance of that queue.
When there is a local instance and an MQ cluster with at least one other instance, the QMgr can be configured to allow messages to go to non-local instances.
When qmgrA, qmgrB, and qmgrC are in a cluster, and qmgrC does not host a local instance of the queue, messages put to that queue name will round-robin between the instances on qmgrA and qmgrB .
GETting messages
A message landing in queueName on qmgrA can only be retrieved from that queue by an application connected to qmgrA.
A message landing in queueName on qmgrB can only be retrieved from that queue by an application connected to qmgrB.
An application connected to qmgrC cannot retrieved messages from the queues hosted on qmgrA or qmgrB.
MQ HA
The requirement to make a queue highly available can be achieved in several ways. Some of these provide recoverability of the service provided by MQ. Some of them provide recoverability of messages that would be stranded in-flight. In addition to reading topology design section in the manuals, please see the MQ HA presentation from IBM Interconnect 2015.
Your question does make very much sense. Go look up MQ Clustering and MQ Multi-Instance in the MQ Knowledge Center. http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.con.doc/q017820_.htm
Currently I am using enet to stream info, updated multiple times per second, to a list of
provided ip addresses / ports. I am creating a client connection for each of these
addresses (and there are server enet host connections running on those computers).
I am wondering if there is a more efficient way to send these messages(or simply a better solution to the problem)? Some way that I do not have to create
a enet host for each connection? I do need reliable delivery.
I am only using enet as it is convenient and already available in the system I am using.
A great solution for this problem is ZeroMQ.
It is a networking library with C++ bindings that specializes in the reliable delivery of messages in a variety of configurations, like the pub/sub model that looks like what you are trying to do.
ZeroMQ would effectively allow you to not even need to list the IPs of the subscribers, since they would indeed subscribe by connecting to your publisher. The publisher then would send data regardless of the number of subscribers (see http://zguide.zeromq.org/page:all#Getting-the-Message-Out).
I have a certain application running on my computer. The same application can run on many computers on a LAN or different places in the world. I want to communicate between them. So I basically want a p2p system. But I will always know which computers(specific IP address) will be peers. I just want peers to have join and leave functionality. The single most important aim will be communication speed and time required. I assume simple UDP multicast (if anything like that exists) between peers will be fastest possible solution. I dont want to retransmit messages even if lost. Should I use an existing p2p library e.g. libjingle,etc. or just create some basic framework from scratch as my needs are pretty basic?
I think you're missing the point of UDP. It's not saving any time in a sense that a message gets faster to the destination, it's just you're posting the message and don't care if it arrives safely to the other side. On WAN - it will probably not arrive on the other side. UDP accross networks is problematic, as it can be thrown out by any router on the way which is tight on bandwidth - there's no guarantee of delivery for it.
I wouldn't suggest using UDP out of the topology under your control.
As to P2P vs directed sockets - the question is what it is that you need to move around. Do you need bi/multidirectional communication between all the peers, or you're talking to a single server from all the nodes?
You mentioned multicast - that would mean that you have some centralized source of data that transmits information and all the rest listen - in this case there's no benefit for P2P, and multicast, as a UDP protocol, may not work well accross multiple networks. But you can use TCP connections to each of the nodes, and "multicast" on your own, and not through IGMP. You can (and should) use threading and non-blocking sockets if you're concerned about sending blocking you, and of course you can use the QoS settings to "ask" routers to rush your sockets through.
You can use zeromq for support all network communication:
zeromq is a simple library encapsulate TCP and UDP for high level communication.
For P2P you can use the different mode of 0mq :
mode PGM/EPGM for discover member of P2P on your LAN (it use multicast)
mode REQ/REP for ask a question to one member
mode PULL/PUSH for duplicate one resource on the net
mode Publish/subscribe for transmission a file to all requester
Warning, zeromq is hard to install on windows...
And for HMI, use green-shoes ?
i think you should succeed using multicast,
unfortunately i do not know any library,
but still in case you have to do it from scratch
take a look at this:
http://www.tldp.org/HOWTO/Multicast-HOWTO.html
good luck :-)