Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Advanced CORBA Programming wit C++ - M. Henning, S. Vinoski.pdf
Скачиваний:
65
Добавлен:
24.05.2014
Размер:
5 Mб
Скачать

IT-SC book: Advanced CORBA® Programming with C++

the lowest load, or it can simply randomize the list of available machines as a crude form of load balancing. Starting a server on different machines depending on load makes sense only for a server that does not depend on the local filesystem for its object state. Otherwise, starting the server on a different machine would cut it off from its files.

14.5 Migration, Reliability, Performance, and Scalability

It is instructive to consider the architectural consequences of the repository design we discuss in Section 14.4.5

The design uses a single repository address for each IOR. As a consequence, failure of the repository prevents clients from binding to objects in all servers in the repository's location domain. This makes the repository a single point of failure.

State is distributed between the implementation repository and servers so that it is unlikely to pile up in any one place. The repository knows only about the POA names used by servers and knows nothing about the individual objects implemented by each server. Conversely, each server need know only about its own objects and a single implementation repository. This design can support systems that scale to very large numbers of objects without performance problems.

The design in Section 14.4.5 is only one of many possible designs. Each design has its own advantages and disadvantages, and each involves trade-offs among object migration, reliability, performance, and scalability. Note that most ORBs do not provide all the options we mention here. Instead, an ORB's repository typically offers only a small number of options that are tailored to the ORB's intended environment.

14.5.1 Small Location Domains

We can make location domains smaller by placing fewer machines in each location domain. In the extreme case, every machine in the system runs a separate implementation repository that is responsible only for servers on the local machine. This option provides high performance because the server and the repository can communicate via the system bus instead of over the network. It also improves resilience against failure. If a repository crashes, it affects only servers running on the local machine; clients using servers on other machines can still bind to objects in these servers.

14.5.2 Large Location Domains

If we make large location domains that contain many machines each, performance will suffer somewhat because servers must access the repository via the network, which is slower than local communication. In addition, the repository can become a bottleneck during binding if it is responsible for very many servers. On the other hand, large location domains offer maximum freedom for server migration: we can move a server from one machine to another as long as we do not cross a location domain boundary. Server migration is impossible if we run separate repositories on every machine because after a

563

IT-SC book: Advanced CORBA® Programming with C++

server is moved, existing references would point at the old repository at the previous server location instead of the new one.

14.5.3 Redundant Implementation Repositories

To improve resilience to failure, an ORB can run multiple redundant repositories at different locations and create multiple profiles for persistent IORs. Each profile contains the address of one of the redundant repositories.

This approach improves fault tolerance because a single IOR can be bound by more than one repository. However, performance suffers for two reasons. For one thing, IORs get larger the more information they carry, so the overhead of using and transmitting object references becomes larger. Second, CORBA does not specify in which order a client should use the different profiles in an IOR, so a naive client could always try the profiles in order. If the repository addressed by the first profile is down, such a client will always fail trying to bind via the first profile and then succeed via the second profile.

A more intelligent client could monitor the status of different destinations in a multiprofile IOR and avoid using a non-functional address for some period of time before trying that address again. Such a client would make more efficient use of the multiple profiles in an IOR and would improve binding performance. On the downside, the more intelligent the client-side run time, the more CPU cycles and memory it consumes, and that has a negative influence on performance.

14.5.4 Granularity of Object Migration

The repository design in Section 14.4.5 strikes a compromise between object migration and scalability. With this design, we can migrate a subset of the objects in a server without breaking existing references. For example, the CCS server uses separate POAs for the controller, thermometers, and thermostats. We can move all thermometers to a server on a different machine in the same location domain by changing the repository registration for the thermometer POA to a new machine. (If we do this, the target machine still requires access to the instrument control protocol used to communicate with thermometers. For servers that store persistent object state in a database, the target machine must be able to access the database; otherwise, the moved objects are cut off from their persistent state.)

The basic rule governing granularity of migration is that whenever an object moves, the implementation repository must know about that move so that it can return the correct LOCATION_FORWARD replies to clients. For the design in Section 14.4.5, this means that if an object moves, all other objects using the same POA must move with it.[4]

[4] This is also why many ORBs cannot implement the CosLifeCycle::move operation. Usually, the implementation repository keeps track of POAs instead of individual objects, so it is impossible to move a single object at a time.

564

IT-SC book: Advanced CORBA® Programming with C++

We can get a finer grain of object migration by reducing the number of objects per POA. In the extreme, we can use a separate POA for each individual object. This approach gives us maximum flexibility for object migration (we can move a single object), but it causes other problems.

Adding a new POA name to the server table in the repository usually requires the use of an administrative tool. If the number of objects is large or if objects are created and destroyed frequently, this becomes infeasible because a human administrator must be involved.

Even if the ORB provides a programmatic interface to add new POA names to the implementation repository, we still have a problem. By giving each object its own POA, we force the implementation repository to store information about each individual object instead of storing information about only a few POAs, each of which implements a large group of objects. In other words, finer grain of object migration externalizes more state in the repository. This externalization can lead to performance problems in the repository. In addition, external state can be dangerous: if the repository's view of which objects exist ever gets out of sync with the server's view, we have a serious problem.

14.5.5 Migration across Location Domain Boundaries

It is possible to migrate servers or objects across location domain boundaries, but it reduces performance and scalability. There are two approaches.

When a server migrates to a new domain, it registers itself with its new implementation repository as well as all repositories it has used in the past.

The idea is that all repositories ever used by a server know the current location of the server and therefore can continue to bind requests arriving via an IOR generated at a previous location. This approach works but has the drawback that, over time, more and more server registrations accumulate in repositories. This accumulation compromises scalability because it increases the amount of externalized state and makes it more likely for server registrations to become inconsistent.

When a server migrates to a new domain, an administrator must update the server's registration in the old repository to generate LOCATION_FORWARD replies that point at the new repository.

The idea is to leave a "footprint" in the old repository that forwards binding requests to the new repository, which in turn knows about the location of the server. Again, the problem with this approach is that the forwarding footprints accumulate over time. In addition, a request from a client via an IOR created at a previous location must be forwarded from repository to repository until it finally arrives at the server. The binding chain gets longer with every migration, so this approach does not scale in performance if servers migrate more than a few times. Moreover, it creates additional failure points because intermediate nodes in the chain may fail.

565

IT-SC book: Advanced CORBA® Programming with C++

Hybrids of these two basic ideas are possible. For example, repositories could be arranged into domain hierarchies to reduce the length of forwarding chains (from O(n) to O(log n)), and repositories could be combined into redundant groups to gain performance and fault tolerance. However, all approaches are subject to the basic trade-offs between granularity of migration, reliability, performance, and scalability.

Note that the LOCATION_FORWARD_PERM reply status added with GIOP 1.2 mitigates the migration problem somewhat. LOCATION_FORWARD_PERM indicates to the client that an object has permanently moved to a new location, so the client can permanently replace the original object reference with one for the newlocation. However, LOCATION_FORWARD_PERM does not solve the problem completely because the ORB cannot automatically update references obtained from persistent storage, such as a Naming or Trading Service (see Chapters 18 and 19).

14.6 Activation Modes

An implementation repository can provide more than one server activation mode. Activation modes were part of the original BOA specification but were removed with the 2.2 revision of CORBA because the POA specification created a much cleaner delineation between object adapters and implementation repositories. In CORBA 2.2, only the object adapter is specified; implementation repository features, such as activation modes, are not mentioned (they are considered the domain of each ORB vendor).

However, you will find mention of activation modes in older CORBA literature, and your vendor may offer different activation modes with its implementation repository. Here are a few possible modes that may be supported.

Shared activation

All requests for objects in the same server are directed toward the same single server process. Many ORBs provide only shared activation mode because it is sufficient for the majority of applications.

Per-client activation

The repository creates as many server processes as there are distinct client processes. In other words, for every new client process, the repository creates a new server process. Each server has exactly one incoming connection from a single client process and terminates when that connection is closed by the client.

Per-user activation

The repository creates a new server process for each distinct user that contacts the server. This means that if a single user runs three client processes that communicate with objects in the same server, the repository starts only a single server process for all three clients. However, if another client process starts up on behalf of a different user, the repository directs requests from that client to a second instance of the server. Clearly, per-user

566