Use case : one Java process with one or two C++ processes, always on the same machine. Bidirectional, binary, non-persistent communication is required. One of the C++ process is responsible for instantiating the other processes.
I have given a look around, seeing things like XML/JSON-RPC, Protocol Buffers, Thrift, zeromq, etc.
If possible, portability would be nice, but Windows XP/7 is required.
In general you should separate message transport and message de-/serialization in your design, and keep them as orthogonal as possible. In short, decouple the data (message) flow behavior from your message content.
There are several message oriented transport frameworks, that allow to send and receive neutral payload data (messages) for certain behavioral patterns of client/server communication (request/reply, publish/subscribe, push/pull, ...) between threads, processes and network services as client and server instances.
There are a number frameworks that provide de-/serialization of your payload (message) data in a transport neutral (e.g. providing a wire format for exchanging native integer data independent of machine endianess) manner.
What's the best combination choice for your particular use case, depends on a number of requirements and constraints you have for your design decisions:
Scalability over client/sever processing units as threads, processes or servers/processes
Overall performance and message latency
Processing units resource requirements (e.g. heap memory or code size)
Network resource impact (what's sent via the network interfaces)
etc. ...
Possible Solution:
I think the ZMQ messaging framework in combination with the Google Protobuf message framwework could offer a viable solution for your use case. There are language bindings for c++ and java (see ZMQ Java binding) and you'll have have the optimized implementations for inter-process and inter-thread communications. ZMQ connections are designed in a socket like manner, that support bi-directional (request/reply) communication patterns as well as uni-directional (publish/subscribe, push/pull).
As mentioned, the message content's format is up to you, but Google Protobuf might be appropriate for internally defined message protocols, that are supported for C++ and Java language bindings. Google Protobuf also provides a mechanism to define RPC service interfaces, but you must provide the concrete message transport protocols for client/server implementations. I have never implemented this by means of a ZMQ transport, but it should be possible if necessary.
XML/JSON-RPC might be considered for published (e.g. via REST services) protocols (bridging is considerably easy with ZMQ).
Considering your requirements, I'd guess the latter protocol format options aren't required, but might be useful though, depending on the frameworks you'll intend to use with the Java/C++ participants.
AFAIK ZMQ matches your portability constraints about Windows XP/7 platforms. Not sure, but there might be restrictions for inter-thread communication on Windows systems. But that doesn't seem to apply to the scenario you have described.
Alternate transport frameworks:
ActiveMQ
Boost asio (C++ wrapped native sockets, I don't know about the java side feel free to enhance this info)
Alternate message en-/decoding frameworks:
XML-RPC C++/java (usually assumes HTTP transport)
JSON
According to info from question's comments, I guess protocol buffers is something to consider -- it has binary format on the wire, has simple API and does not provide any redundant stuff, such as persistence.
Related
I have the following situation:
I have 2 JVM processes (really 2 java processes running separately, not 2 threads) running on a local machine. Let's call them ProcessA an ProcessB.
I want them to communicate (exchange data) with one another (e.g. ProcessA sends a message to ProcessB to do something).
Now, I work around this issue by writing a temporary file and these process periodically scan this file to get message. I think this solution is not so good.
What would be a better alternative to achieve what I want?
Multiple options for IPC:
Socket-Based (Bare-Bones) Networking
not necessarily hard, but:
might be verbose for not much,
might offer more surface for bugs, as you write more code.
you could rely on existing frameworks, like Netty
RMI
Technically, that's also network communication, but that's transparent for you.
Fully-fledged Message Passing Architectures
usually built on either RMI or network communications as well, but with support for complicated conversations and workflows
might be too heavy-weight for something simple
frameworks like ActiveMQ or JBoss Messaging
Java Management Extensions (JMX)
more meant for JVM management and monitoring, but could help to implement what you want if you mostly want to have one process query another for data, or send it some request for an action, if they aren't too complex
also works over RMI (amongst other possible protocols)
not so simple to wrap your head around at first, but actually rather simple to use
File-sharing / File-locking
that's what you're doing right now
it's doable, but comes with a lot of problems to handle
Signals
You can simply send signals to your other project
However, it's fairly limited and requires you to implement a translation layer (it is doable, though, but a rather crazy idea to toy with than anything serious.
Without more details, a bare-bone network-based IPC approach seems the best, as it's the:
most extensible (in terms of adding new features and workflows to your
most lightweight (in terms of memory footprint for your app)
most simple (in terms of design)
most educative (in terms of learning how to implement IPC). (as you mentioned "socket is hard" in a comment, and it really is not and should be something you work on)
That being said, based on your example (simply requesting the other process to do an action), JMX could also be good enough for you.
I've added a library on github called Mappedbus (http://github.com/caplogic/mappedbus) which enable two (or many more) Java processes/JVMs to communicate by exchanging messages. The library uses a memory mapped file and makes use of fetch-and-add and volatile read/writes to synchronize the different readers and writers. I've measured the throughput between two processes using this library to 40 million messages/s with an average latency of 25 ns for reading/writing a single message.
What you are looking for is inter-process communication. Java provides a simple IPC framework in the form of Java RMI API. There are several other mechanisms for inter-process communication such as pipes, sockets, message queues (these are all concepts, obviously, so there are frameworks that implement these).
I think in your case Java RMI or a simple custom socket implementation should suffice.
Sockets with DataInput(Output)Stream, to send java objects back and forth. This is easier than using disk file, and much easier than Netty.
I tend to use jGroup to form local clusters between processes. It works for nodes (aka processes) on the same machine, within the same JVM or even across different servers.
Once you understand the basics it is easy working with it and having the options to actually run two or more processes in the same JVM makes it easy to test those processes easily.
The overhead and latency is minimal if both are on the same machine (usually only a TCP rountrip of about >100ns per action).
socket may be a better choice, I think.
Back in 2004 I implement code which do the job with sockets. Until then, many times I search for a better solution, because socket approach triggers firewall and my clients worry. There is no better solution until now. Client must serialize your data, send and server must receive and unserialize.
It is easy.
I'm sketching an architecture for a micro services system, planned to run currently on one machine (maybe distribution in the future).
The system will be composed of services written in both Node.js, GO and might be Java.
Both node.js and Java will need to pass instructions and receive results from the GO server.
Now, I'm trying to decide should I use IPC pipe or ramp up on gRPC and protobuff and use them.
These are on different abstraction levels and have different uses, as such the 'or' in the question is wrong. You will need both types (transport and encoding), even if you reimplement one of them.
IPC like an anonymous or named pipe is usually called a transport, they have no way to encode multiple instructions or results (though they encode a stream of bytes).
gRPC and protobuf need a transport, support multiple transports and add more fine grained encoding (how to represent an integer, a list, etc) and possibly more on top. Technologies that support encoding something can often be nested with a transport or encoding, this is common with technologies that are used together with HTTP, this may make sense but may only add a layer without having a use.
I need to interact with a server over TCP/IP with a basic message/response protocol (so for each request I shall receive a defined response).
In the JVM ecosystem, I think Java Socket was the tool to use 15 years ago, but I'm wondering if there is anything more suitable nowadays in the JDK? For example, with Java Sockets one still needs to manually timeout a request if no answer is received, which feels really old fashioned.
So is there anything new in the JDK or JVM universe?
No, there are much better option nowadays which allow you to implement your client/server asynchronously without additional threading.
Look at SocketChannel from nio or even better AsynchronousSocketChannel from nio2. Check this tutorial
Especially the latter option will allow you to just start the connection listener and register callback which will be called whenever new connection is requested, data arrived, data was written etc.
Also consider looking at some high level solutions like Netty. It will take care of the network core, distribute load evenly to executors. Additionally it provides clears separation of the network layer and processing layer. For the processing layer it will provide you with lot of reusable codecs for common protocols.
You can try RMI which works on top of TCP/IP but hides all the hardwork with a convenient set of APIs.
Follow this tutorial post
Well, there are really a lot of other technologies to use, for example JMS has various implementations which work out of the box.
Sockets are low-level building blocks of network communications, like wires in the electricity network of your house. Yes, they're old fashioned, yes, we likely don't want to see them, but they're there and they will stay there for a good reason.
On top of Sockets, you can e.g. pick the HTTPUrlConnection, which implements most of the HTTP protocol. Still, setting timeout policies are in your hands, which I find quite useful, and extremelly painful at the same time.
http://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/
You are free to move one abstraction level above, and use a ready-made REST library, such as this: http://unirest.io/java.html
The example above connects to a server, configures a HTTP query string, perform the request (timeout, encodings, all the mess under the hood), and finally get the response in Json format in a few lines:
Unirest.post("http://httpbin.org/post")
.queryString("name", "Mark")
.field("last", "Polo")
.asJson();
Nowadays a vast amount of web services are available using REST protocol, which is a simple command-response over HTTP. If you have a chance, I'd suggest using REST, as you can easily find available client and server side implementations, and you don't need to reinvent the wheel on the command-protocol layer either.
On client side, unirest is quite convenient. On the server side, we have had really great experience in the 1.2.xx series of Play! framework. But there are thousands of these things out there, just search for "REST".
Take a look to Netty Project, "Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server."
This framework give us a lot of capabilities that simplify the programming process, allowing a big scalability.
Is used by Twitter and a lot of big companies in the tecnology industry.
This is a nice presentation from Norman Maurer.
Hi guys: I've "simplistic" workflow management tricks (like rotating file queues, controller threads, etc...) work in a wide variety of producer/consumer contexts... Where files are simply renamed, deleted, and created in a systematic manner; or where a "main" thread is calls and coordinates workers.
In contrast, I've also "played" with JMS in some toy applications, and I can see how it might be used to coordinate a complex application workflow.
I was wondering: What do messaging services like JMS offer over standard producer/consumer workflows (of course, if I'm missing something here, or have the wrong idea of when/why JMS is used, feel free to correct me)?
In particular, what type of applications require enterprise-grade messaging frameworks?
What do messaging services like JMS offer over standard producer/consumer workflows?
Scalability, availability, transparency, manageability. In point-to-point communication sender is bound to the receiver and vice versa. You, as the application developer, are responsible for thinking what to do when traffic increases and implement the necessary changes. Your application must be aware of the environment in which it works and must be changed every time the environment changes. You are forced to reinvent the wheel while solving typical messaging problems, for example, temporary congestion (what to do when the consumer can't keep the pace with the producer for a while?). You have to provide your own means of monitoring the current situation, if something does not work as expected. The list goes on...
Now imagine you have to wire 10 different systems this way. Obviously, you'll need to come up with a fairly universal solution so that you don't implement each connection logic from scratch — that would be terribly expensive to produce, not to mention maintaining it. A JMS message broker is one of such possible general solutions.
In particular, what type of applications require enterprise-grade messaging frameworks?
Complicated, in short. I work for a company that has a network of about 70 systems, some of them 30 years old. New systems are added to the network as time passes and the old systems don't need to be changed, neither must new systems be aware of ancient data exchange protocols — a centralized cluster of message brokers can translate a JMS message into some mainframe message format I have no idea about, and same way back with the answer.
I come from a background of MoM. I think I understand ESB conceptually. However, I'm not too sure about the practical differences between the two when it comes to making a choice architecturally.
Here is what I want to know
1) Any good links online which can help me in this regard.
2) Can someone tell me where it makes sense to use one over the other.
Any help would be useful.
Messaging tends to concentrate on the reliable exchange of messages around a network; using queues as a reliable load balancer and topics to implement publish and subscribe.
An ESB typically tends to add different features above and beyond messaging such as orchestration, routing, transformation and mediation.
I'd recommend reading about the Enterprise Integration Patterns which gives an overview of common patterns you'll tend to use in integration problems which are all based above a message bus (though can be used with other networking technologies too).
For example using open source; Apache ActiveMQ provides a loosely coupled reliable exchange of messages. Then you can use Apache Camel to implement the Enterprise Integration Patterns for smart routing, transformation, orchestration, working with other technologies and so forth.
I put MOM solutions and ESB solutions on two distinct planes.
I consider MOM a building block for ESB solutions. In fact, ESB solutions reach their own loose coupling and asynchronous communication capabilities, just using the paradigm offered by the specific MOM implementation.
Therefore, MOMs represent solutions for data/events distribution at customized level of QoSs (according to the specific vendor implementation), instead ESBs represent solutions providing capabilities to realize complex orchestrations in a SOA scenario (where we have multiple providers offering their services, and multiple consumers interested in consuming the services offered by the first ones).
Complex orchestrations imply communication between legacy systems, everyone of these with its own data domain representation (rules and services on specific data) and its own communication paradigm (one consumer interact with the ESB using CORBA, another one using WS, and so on).
It is clear that ESB represents a more complex architectural solution aimed to provide the abstraction of data-bus (such as the electronic buses that everyone have in his own pc), able to connect a plethora of service providers to a not well specified plethora of service consumers, hiding heterogeneity in (i) data representation and (ii) communication.
Sorry for the long post, but the concepts are complex and it is very difficult to be effective and efficient in a short statement.
An ESB is typically a layer that routes, logs, transforms, and performs other 'technical' (i.e. non-business) functions on messages. It could process messages from a messaging system (such as something JMS-based), or it could work with other types of message (such as SOAP-based web services). In that respect, it's more general than MoM.
Disclaimer: I am an IBM WebSphere consultant - although I am not contributing here in an official capacity.
ESB with web services in its true form provides Application loose coupling by sending the data through one the elements of the message.
MOM provides not only Application Loose coupling but process loose coupling along.
ESB comes with additional features supporting Governance centric approach.
Both can be used independently or together depending upon the scenario.
IBM and Oracle have SOA certifications. Since they're the leaders in the marketplace (Gartner Magic Quadrant), I would read about how they define SOA and ESBs (along with methodology and the components needed to support SOA like Governance, Registry, etc etc)
EBS is just yet another buzzword, as is SOA 2.0.
You can have a ESB system easily implemented with normal Web Services with a queue behind them.
You can have message routing and or orchestration with SOA 1.0 (Tibco, BizzTalk), one things does not stop the other really. More importantly, it is the semantics given to the messages exchanged in the system that play an important role, in this case events. Messages as events, are triggers about something that happened in your system, so the context is different.