Chapter 8 Deploying CORBA Applications
8.1 Deploying CORBA Clients
The details of deploying a CORBA client application vary slightly from one CORBA product to another. However, the principles are straightforward. In particular, you will need to do the following:
- Install a subset of the CORBA product (such as a configuration file, a .jar file or shared libraries/DLLs) on the deployment machine. Obviously, you will not need to install the development parts of the CORBA product, such as the IDL compiler. Some CORBA vendors provide a “install runtime only” and “install runtime and development tools” options for their product installation utility. If such an option is not available then it is usually easy to identify and copy the “runtime” subset from a full CORBA installation on a development machine to a deployment machine.
- Install the client executable on the deployment machine, along with required application-specific infrastructure, such as a configuration file and/or a directory for storing log files.
When you run the client application, you might need to provide it with some CORBA-related command-line arguments:
- You might need a command-line argument to tell the application where it can find the CORBA product’s configuration file. Alternatively, this information might be communicated in a different manner, such as a system property for Java applications or through an environment variable for non-Java applications.
- If the diagnostics level specified in the configuration file for the CORBA product is not to your liking then you might specify a command-line option that specifies a different diagnostics level. Likewise, if the CORBA configuration file does not specify how to contact, say, the appropriate Naming Service then you might use -ORBDefaultInitRef or -ORBInitRef command-line arguments (discussed in Section 12.5).
- Java provides an implementation of CORBA in its standard class library. If your application uses a different CORBA implementation then you may need to use command-line arguments to define some Java system properties that indicate which implementation of CORBA should be used.
If you run a client application with many command-line arguments then it becomes difficult to remember all the command-line arguments that must be typed. A simple way around this problem is to write a “wrapper” UNIX shell script or Windows batch file that runs the application with the appropriate command-line arguments.
The above requirements for deploying a CORBA client are so simple that the manuals for many CORBA products neglect to mention them and, ironically, this lack of documentation makes deployment seem more complex than it is. If your CORBA vendor does not provide documentation on deploying applications then sending an email to the vendor’s technical support department should enable you to receive helpful guidance.
The deployment issues discussed in this section apply not just to clients, but also to server applications. However, there are some additional issues surrounding the deployment of servers, as I discuss in the next section.
8.2 Deploying CORBA Servers
Several concepts—POA policies (Chapter 6), the IMR (Chapter 7) and object references (Chapter 10)—interact with each other and influence how you can deploy a CORBA server. Most CORBA applications are deployed on a TCP/IP network, so the discussion in this section assumes use of TCP-based communication. Section 8.2.1 gives a brief overview of some issues in deploying a (non-CORBA) TCP server. Then Section 8.2.2 explains deployment options for a CORBA server through analogy with the deployment of a TCP server.
8.2.1 Overview of TCP Concepts
- The server can tell the operating system that it wants to listen on a specific (or fixed) port.
- The server can tell the operating system that it wants to listen on port 0 (zero). The operating system understands this to mean that the server is happy to listen on any port, and so the operating system allocates an arbitrary port to the server. This arbitrary port is often called a random, transient (meaning temporary) or ephemeral (meaning short-lived) port.
If a TCP server is coded or configured to listen on a fixed port then it will listen on the same port whenever it is killed and restarted. Conversely, if a server is coded or configured to listen on a random port then it is likely to listen on a different port each time it is killed and restarted.
By convention, some TCP-based applications listen on well-known, fixed ports. For example, the default port for a web server is port 80. So when you type the URL www.amazon.com into your web browser, your web browser connects to port 80 on the specified host. This convention makes it easier to remember URLs, because you typically have to remember only the hostname on which a web server runs, rather than having to remember the hostname and port. For the same reason, other well-known TCP-based applications, such as POP3 mail servers (port 110), ftp servers (port 21), telnet servers (port 23) and so on also have well-known, fixed ports reserved for their use.
If a TCP server listens on a random port then it needs some way to communicate this random port to potential clients so that the client applications can connect to it. A simple way to do this is for the server to advertise its port by writing it to a text file, and then for clients to read this file. Of course, this solution requires that the server and clients have a shared file system, so this is not a geographically-scalable solution. A more complex, but more scalable, solution is for there to be an “advertisement server” that listens on a well-known, fixed port and maintains a list of server-name → port mappings. Whenever a “normal” server starts up and listens on a random port, it contacts the advertisement server to register its name and current port. Client applications connect to the advertisement server and request the port associated with the desired server name.
One benefit of the hypothetical “advertisement server” is that you need to allocate only one fixed port. This fixed port is for the advertisement server itself; all the other servers that advertise themselves through it can listen on random ports. This then reduces the administration overhead of having to choose fixed ports that are reserved for use by TCP servers.
8.2.2 Deployment Models for CORBA Servers
Most CORBA applications are deployed on a TCP/IP network, so CORBA servers are TCP servers that listen on a port. The CORBA concepts of the implementation repository (Chapter 7) and the Naming Service (Chapter 4) are both analogous to the TCP “advertisement server” described in Section 8.2.1. The Naming Service provides name → IOR mappings, while the IMR provides IOR → IOR mappings.1 This functionality of the IMR seems strange, until you realize that the details that vary between the original and mapped IORs are the host and port embedded in the IOR. Because of this, the IMR provides a mapping from an IOR that contains the IMR’s well-known host and port to an IOR that contains the host and (usually random) port of a server process.
Most CORBA products can be configured (or programmed using proprietary APIs) to be deployed in some or all of the following four ways:
- The server listens on a random port and is deployed without an IMR. This approach is ideal if a server has only transient objects, that is, all objects are in POAs that have the TRANSIENT policy. However, this deployment model is unsuitable for servers that have some objects in PERSISTENT POAs. This is because the port embedded in the IORs of the persistent objects is a random port and the server is likely to use a different random port if it is killed and restarted. In effect, this deployment model has the undesirable side effect of turning persistent IORs into transient IORs.
- The server listens on a random port and is deployed with an IMR. In this case, the server embeds its own host and (random) port into IORs of transient objects, but it embeds the host and fixed port of the IMR into the IORs of persistent objects. When a client sends its first request to a persistent IOR, the request goes to the IMR. As discussed in Section 7.2, the IMR uses the object key information in the header of the request to identify the intended server. The IMR (re)starts the server process if it is not currently running and then redirects the client to the host and (random) port of the intended server process. This redirection through the IMR occurs only for the first request from the client to an IOR. Further requests from the client to the same IOR go directly to the server.
- The server listens on a fixed port and is deployed without an IMR. In this case, the server’s own host and port are embedded in both transient and persistent IORs. The embedding of a fixed port (as opposed to a random port) in persistent IORs ensures that the IORs are valid across restarts of the server.
- The server listens on a fixed port and is deployed with an IMR. In this case, the server embeds its own host and (fixed) port into IORs of transient objects, but it embeds the host and fixed port of the IMR into the IORs of persistent objects. When a client sends its first request to a persistent IOR, the request goes to the IMR. As discussed in Section 7.2, the IMR uses the object key information in the header of the request to identify the intended server. The IMR (re)starts the server process if it is not currently running and then redirects the client to the host and (fixed) port of the intended server process. This redirection through the IMR occurs only for the first request from the client to an IOR. Further requests from the client to the same IOR go directly to the server.
There are a few points worth noting about the above deployment options.
First, the server’s own host and (random or fixed) port is always embedded in transient IORs. This means that transient objects never make use of the IMR. Some people make the mistake of assuming that if an IMR is running then servers automatically make use of it. However, if a server has only transient POAs then the server will just ignore the IMR. There is nothing preventing a CORBA vendor from designing a product in which transient IORs do contain the host and port of the IMR, but it would not bring any benefits. The author is not aware of any CORBA products that do this.
Second, there are some potential benefits to be had from deploying a server on a fixed port (deployment models 3 and 4 in the above list):
- Some organizations use a hardware router to load-balance client connections across a replicated server that is running on several machines. This approach to load balancing may require that server applications listen on fixed ports.
- The use of fixed ports is “firewall friendly”. 2
- In general, the fewer components there are in a computer
system, the more reliable the computer system will be. For this
reason, some organizations prefer to deploy CORBA servers
without an IMR. The use of fixed ports makes it feasible to deploy a server without an IMR,
even if the server has persistent objects (deployment model 3
in the previous list).
A counter argument to consider is that if the IMR is very stable then the use of an IMR can actually improve reliability because it can be used to automatically restart failed servers. Also, some CORBA products provide a fault-tolerance infrastructure through the IMR. This fault tolerance can be used to replicate the IMR and/or server processes, and so eliminate single points of failure within the computer system.
Third, some CORBA products make it easy to choose between all four of the deployment models discussed above. Other CORBA products provide easy-to-use support for a subset of the deployment models, but require use of proprietary APIs or complex configuration for the other deployment models. This is unfortunate because it often results in developers hard-coding logic into an application that, in effect, decides how a CORBA server will be deployed; it is preferable if deployment choices can be made at deployment time rather than having to be decided at development time. Furthermore, the use of proprietary APIs hinders portability. the Creation of POA Hierarchies Made Simple chapter of the CORBA Utilities package [McH] discusses how to work around portability issues associated with different server deployment models. Some CORBA products support only a subset of the deployment models. For example, the omniORB CORBA implementation does not contain an IMR and so cannot support deployment models 2 or 4.
Finally, as previously mentioned, some CORBA products provide a fault-tolerance infrastructure that is built into the IMR. In brief, when a client’s first request on a persistent IOR goes to the IMR, the IMR can redirect the client to one of several replicas of a server process. This type of fault-tolerance infrastructure (which can also provide per-client load balancing) works only for persistent objects. It does not work for transient objects, because communication with transient objects never involves the IMR.
8.3 The Naming Service and the IMR
In Section 8.2.2, I mentioned that the Naming Service provides name → IOR mappings, while the IMR provides IOR → IOR mappings. The fact that the Naming Service and the IMR both contain mapping functionality is often confusing to people new to CORBA. However, the purpose of the mapping provided by the Naming Service is different to the purpose of the mapping provided by the IMR.
A stringified object reference (Section 3.4.2) is in the
digits>"so it is easy to store in a text file or database, but it is not easy for humans to remember. The Naming Service provides the ability to associate an easy-for-humans-to-remember name with an IOR. This makes it easier for humans to keep track of IORs. Of course, a person could decide to store stringified IORs in text files, with a separate file for each IOR. If the files have easy-to-remember names then this technique would serve a purpose similar to that of a Naming Service, except that it would not be geographically scalable, because it is rare for a file system to be accessible to computers that are geographically distant.
- Regardless of whether a client application obtains an IOR from a file or from the Naming Service, the host and port embedded in the IOR might be for the target server or for the server’s IMR. If the host and port are for an IMR then the IMR redirects the client to the actual host and port of the desired server process. The purpose of this redirection is to allow some or all of the following benefits: (1) the IMR always listens on a fixed port, but servers deployed through the IMR can listen on random ports, so the administration overhead of allocating fixed ports for servers is reduced; (2) the IMR can (re)start a server process that is not running; and (3) some IMRs have built-in load-balancing and fault-tolerance infrastructure that allow them to redirect a client to one of several replicas of a server process.
Another point of confusion with the Naming Service and the IMR is that the Naming Service is itself a CORBA Server that is often deployed through the IMR. Because of this, there can be repeated redirection through the IMR when a client application obtains an IOR from the Naming Service and uses this to communicate with a persistent object in a server that is also also deployed through the IMR.
- When the client passes "NameService" as a parameter to resolve_initial_references() (discussed in Section 3.4.1), it obtains an IOR for the Naming Service (this IOR is typically obtained from a configuration file). When the client invokes upon this IOR to communicate with the Naming Service, the client’s first request will go to the IMR and the IMR will redirect the client to the Naming Service.
- Then when the client obtains an IOR from the Naming Service and invokes upon this IOR, the client will be redirected via the IMR to the desired server process.