Development of a distributed application, some of whose components are behind the firewall

Having got into a new project and having worked there for some time, I realized that in a distributed application, the components of which must constantly interact with each other, the appearance of such a thing as firewall becomes a very significant fact in the development of the system. Immediately there are problems that need to be addressed, which personally always makes me happy. In this topic I will describe what you need to keep in mind when developing this kind of system.
A firewall usually appears between applications outside the corporate network and inside it, as well as at the boundaries of the DMZ, which usually take place in the infrastructure in which the system is designed for external users and the server is located in the intranet. Moreover, the message from the client can pass through several DMZ, penetrating more than one firewall.
Firewall adds the following features to keep in mind:
- A connection that does not forward any data closes after a certain period of time.
- A connection that does not send any data can turn into a black hole, which manifests itself in such a way that you send messages, they successfully leave, but do not reach the recipient.
- All ports through which communication will go must be known in advance and registered in the firewall, so technologies that open arbitrary ports do not work in such an environment.
Let’s now see what specifically needs to be done so that the difficulties described above do not cause problems. I will give examples in java, although most should be similar for other platforms, with the exception of RMI.
In order for your connection to not be closed by the firewall when idle, you must not let it stand idle. Usually this is achieved by introducing special service message types, such as ping or heartbeat, which are sent over the network in both directions with a given period of time. The time interval, obviously, is chosen so that in the interval after which the firewall closes the idle connection, several service messages are sent. If we consider the database connection pool as an example, then a validation query can serve as such a service message. I already wrote more about this here .
The second way to solve the problem of closing an idle connection is to recreate them from time to time. For example, this feature is provided in most database connection pools.
To deal with black holes, to be sure that your message has reached the addressee, you can use the request-response strategy, i.e. wait for a short reply for each sent message and only then release the control. Or again, just do not let the connection stand idle, as described above. More details on how to guarantee delivery of messages through the firewall and beyond, I described in detail here .
The most common technology using arbitrary ports in java is probably RMI. One might argue that this is a fairly ancient technology, not widely used. Here are just JMX, which is now used almost everywhere, using RMI as the most common communication protocol. And if you prefer to use JConsole, then most likely you will need this very protocol. However, not everything is so bad, because RMI allows you to fix the port. How to do this, I described in detail here. True, if you want to not just pull methods, but also receive asynchronous notifications (callback) from the server on the client, then you will not succeed here, at least I did not immediately find how to fix the port for this. However, in JMX I never use this functionality, and if necessary, you can always implement it through polling.
I also want to note that if you have a firewall in production, it is very important to have a firewall with the same settings in the UAT environment. If this is impossible for some reason, then you must at least emulate it by installing all the connections between the components not directly, but through a special proxy that breaks your connection or turns it into a black hole after a certain interval, during which the connection does not no data was sent.