Improve Performance With In-Process Integration
Learn what makes in-process integration so attractive in comparison to other approaches.
by Alexander Krapf
July 15, 2005
As architects we are used to looking at the big picture, and as architects of enterprise-level applications we're usually looking at a very large picture indeed. When we hear the term "integration," we think of business applications communicating through message queues, Web services, CORBA, or one of a host of other middleware technologies.
We tend to forget that there are many integration problems for which such middleware-based integration approaches are not only overkill, but downright counterproductive.
Once upon a time, I worked on a large electronic commerce project that consisted of many CORBA servers, most written in C++ but some written in Java. The project had started out in C++ and had a relatively mature C++ infrastructure, consisting of several shared libraries for database access, logging, security, and some other assorted services. The C++ servers simply linked with these libraries and called into them directly, but it was a different picture for the newer Java servers. What were we to do: rewrite the shared C++ libraries in Java, wrap them in an "integration server" to expose the shared services to the Java servers, or use the Java Native Interface (JNI) to call into the libraries directly?
None of these alternatives was appealing, and had it not been for the exclusive availability of a third-party component in Java, we might have ditched Java entirely and kept the server side in C++. Alas, we did not have the luxury of maintaining a homogenous implementation and had to come up with an integration plan in a hurry. We ruled out a rewrite of the libraries in Java as too expensive in terms of time and money. We also ruled out a CORBA-based "integration server" mostly for performance reasons: Many of these modules were written with the assumption of in-process execution and did not have acceptable performance when a server-to-server call was involved.
The winner on technical points was clearly the JNI-based integration solution. JNI allows a Java application to call a specially declared C function in a shared library, so in theory it would have allowed us to call directly into our libraries. But a proof of concept quickly showed that writing JNI code by hand was going to be almost as expensive as rewriting the libraries in Java.
Not surprisingly, we ended up with a hack, as so often happens when implementation design is an afterthought. Nevertheless, this experience helped me understand that there are certain use cases that lend themselves extremely well to an in-process integration approach, as long as there are tools to support you.
What are the characteristics that can make in-process integration so attractive in comparison to other (out-of-process) integration approaches? Well, it's quite simple: Think of a simple in-process integration as a virtual function call to a dynamically loaded library. Consider the implications:
- Extremely high performance. You clearly have a winner if you can call from one solution into another solution at roughly the cost of a virtual function call.
- Extremely reliable integration. A library might load successfully or not, but there are not many realistic failure modes that are introduced by this type of integration, and there is no partial failure mode. Compare that to any kind of sockets-based communication between applications (network saturation, connection timeouts, and so on).
- Extremely low security implications. The integrated solution has an attack profile that is just about equal to the sum of its parts. There are no exposed communication channels, no man-in-the-middle attacks, no authentication or encryption requirements, and no denial-of-service attacks because everything happens within the process.
Back to top