N-Tier Architecture, Distributed Objects, .. The Kitchen Sink ..
In this course we have:
- Reviewed concepts of Operating Systems, in particular
Concurrency, threads, and Performance.
- Introduced Computer Networks and their protocols.
- Introduced Distributed Systems by examining:
- Some of the issues that are at the foundation of Distributed Systems: Time,
Mutual Exclusion, Elections, Atomic Transactions, Deadlocks, Security.
We have not had time to talk
of other such issues, such as Resource Management/Scheduling and
Fault Tolerance.
- Some of the mechanisms for interprocess communication
in Distributed Systems: the socket interface and Remote Procedure Calls.
In addition we could examine:
- What are usual architectures of distributed applications, in particular
n-tier architectures.
- Examples of technical frameworks suggested for Distributed Systems.
In particular:
- OMG's CORBA/OMA (OMG = Object Management Group, CORBA = Common Object Request Broker, OMA = Object management Architecture)
- Microsoft's DCOM (Distributed Component Object Model)
- Java's RMI (Remote Method Invocation), JavaBeans, Enterprise JavaBeans
- More middleware that facilitate the development of distributed systems,
in particular middleware that support interprocess communication.
For example, message queues, like IBM's MQSeries or Microsoft's MSMQ.
- Specific examples of distributed system components and techniques. Things
like interfaces to database management systems, distributed file systems, web servers, web cache systems, mail systems, group cooperation systems, examples of e-commerce applications...
N-Tier Architecture
A common structure of distributed systems is organized on three tiers (3-tier architecture):
+------------+ +-----------+ +--------+
|Presentation| |Application| |Database|
User <--->| |<--->| |<--->| |
| Server | | Server | | Servers|
+------------+ +-----------+ +--------+
GUI Workflow Backend:
Thin Client Controller, Transaction
Business Logic Servers
This is an evolution from the 2-tier architecture:
+------+ +--------+
| 4GL | |Database|
User <--->| |<--->| |
|Client| | Servers|
+------+ +--------+
Fat Client Backend:
Transaction
Servers
There are a number of reasons for preferring the 3-tier over the 2-tier model. Among them:
- Software distribution and management issues. In the 2-tier model most of the business
logic (i.e. the rules of the specific application) has to be implemented mostly in the client
(that is why it is called a fat client). This requires that a lot of computing resources be available at each client. Also, that changes and updates in the software be distributed to all the clients.
- In the 2-tier architecture we need a very high number of sessions between the clients and the database servers. Suppose that we have N clients and each client interacts with 4 DB
servers, then we need 4*N sessions. If instead we have an application server(s), the clients just connect to one application server, and the application server(s) to the DB
servers, for a total of N+M sessions (M is the number of DB servers).
We also often see 4-tier architectures
+------------+ +------+ +-----------+ +--------+
|Presentation| | WWW | |Application| |Database|
User <--->| |<--->| |<--->| |<--->| |
| Server | |Server| | Server | | Servers|
+------------+ +------+ +-----------+ +--------+
GUI Workflow Backend:
Thin Client Controller, Transaction
Business Logic Servers
where we distinguish between the WWW server, where typical web services are provided (like
security and mail), an the application server, where the actual logic of the application is carried out and enforced. Notice that for this architecture militate organizational necessities. For example, the WWW Server is likely to be administered by an enterprise wide office, while the Application Server is likely to be administered by a specific department or group. The two organizations will prefer to administer each its own computer system without too intimate interactions with the other.
All n-tier architectures follow the client-server paradigm, in which one component,
the client, requests and obtains from another component, the server, a service. This
is a Pull model, in that the clients takes the initiative and
pulls the information out of the server.
Another paradigm is called peer-to-peer in that the initiative may be taken by any of the peer systems, either pulling the information from a peer, or pushing it to a peer.
Distributed Objects - OMG/OMA/CORBA
Some Distributed Object Systems:
- OMG's CORBA/OMA (OMG = Object Management Group, CORBA = Common Object Request Broker, OMA = Object management Architecture)
- Microsoft's DCOM
- Java's RMI, JavaBeans, Java Enterprise Beans
We focus on OMG's CORBA/OMA.
OMG sees Distributed Computing in the context of its use and calls it Enterprise
Computing. Here is OMG's view of Enterprise Computing.
+---+--------------------------------------------+---+
| M | CORBA Domain | CORBA Domain | CORBA Domain | |
| E +--------------------------------------------+ |
| T | Common Business Objects* | |
| A +--------------------------------------------+ |
| | Business Object Facility* | |
| O +--------------------------------------------+ S |
| B | CORBA Facilities | E |
| J +--------------------------------------------+ C | UML
| | CORBA Services | U | MODELING
| F +--------------------------------------------+ R |
| A | Interoperability: IIOP, Asynch* | I |
| C +--------------------------------------------+ T |
| I | Real Time*, Embedded* options | Y |
| L +--------------------------------------------+ |
| I | Components*, Scripting* | |
| T +--------------------------------------------+ |
| Y | IDL Interfaces, Mappings, and ORB | |
+---+--------------------------------------------+---+
(from: J.Siegel, J.ACM, Oct. 1998)
[the * next to a topic means that the topic is being standardized]
OMG seems to make a distinction between Interfaces, Components, Application Objects, and Business objects.
Interfaces, or just Objects, correspond closely to C++ classes. Components, which are currently being
defined, will include one or possibly more interfaces. Application Objects are objects designed to operate
using all available services and facilities of CORBA/OMA. Business Objects are Application Objects
that carry out specific busines functions, things like Order Entry and Shipping.
Here is how Application Objects are supposed to interact in OMA:
+-------------+ +------------------+ +------------------+
| Application | | Vertical (Domain)| | Horizontal |
| Objects | | CORBA Facilities | | CORBA Facilities |
+--------+----+ +--------+---------+ +--------+---------+
| | |
| | |
+ | | | +
/ +-----+----------------+---------------------+---------+ \
+ Object Request Broker +
\ +-------------------------+----------------------------+ /
+ | +
|
+--------------------+-------------------+
| |
| CORBA SERVICES |
| |
+----------------------------------------+
Interaction of Objects in their environment (OMA)
CORBA objects can:
- Be located anywhere on a network.
- Interoperate with objects on other computer architectures
and operating systems.
- Be written in any programming language for
which there is a mapping from OMG IDL (Interface Definition Language) to that
language. (Mappings currently specified include Java, C++, C, Smalltalk,
COBOL, and Ada.)
- Run on any operating system (at present at least Win32, NT, Unix, MVS).
- Communicate using many protocols (TCP/IP, ATM, Ethernet, ..).
It is believed by some that in time many devices will be placed on the internet and seen
and used by their neighbors as Corba objects. A similar route is being taken
in the Java/Sun world with the
Jini system.
JavaBeans can:
- Be located anywhere on a network.
- Interoperate with other JavaBeans on other computer
architectures and operating systems (after all, they
run on a virtual machine).
- Be written only in Java. They can be bridged to
be used as DCOM objects or CORBA objects.
DCOM objects can:
- Be located anywhere on a network.
- Interoperate with other DCOM objects on other computer
architectures as long as we are in a Windows system.
- Be written in a number of languages, like C, C++, Java,
Visual Basic. They can be bridged to
interoperate with CORBA objects and to use JavaBeans.
These different distributed object models are being developed
with mutually communicating gateways
Here is a diagram that represents the basic elements of CORBA's model:
+-----------+ +---------+ +---------------+
| Interface | | IDL | | Implementation|
| Repository| | Compiler| | Repository |
+-----------+ +---------+ +---------------+
+-------+ +--------+
| Client|--------+ +-| Servant|-------+
+-------+ \ / +--------+ |
| \ \ / | \ |
v \ \ / v \ |
+-----+ +-----+ +---------+ +--------+ +-----+ |
| DII | | IDL | | ORB | | IDL | | DSI | |
+-----+ |Stubs| |Interface| |Skeleton| +-----+ v
+-----+ +---------+ +--------+ +---------+
+----------+ Object |
| Adapter |
+--------------------+
+------------------------------------------------------+
| ORB Core |
| using GIOP -IIOP |
+------------------------------------------------------+
where:
- DII = Dynamic Interface Invocation
- DSI = Dynamic Skeleton Invocation
- ORB = Object Request broker
- GIOP = General Inter Orb Protocol
- IIOP = Internet Inter Orb Protocol = GIOP over TCP/IP
It is convenient to distinguish between the object being accessed,
and the code that implements that object.
This implementation code is called a servant. The object is what
executes, including the connections to its environment.
The servant is just the code that implements the behavior of the object.
Here are the programming steps typically required to compile and
use a new object:
- Define the object interfaces in the Interface Definition Language (IDL).
The definition
takes the form of an interface, the IDL equivalent of classes.
- Implement these interfaces with C++ classes (assuming you are using C++,
or Java, or C, or SmallTalk, or ..).
- Write a server mainprogram which can create instances of the servant.
- Register the server with some sort of service (something like PORTMAP
of ONC RPC).
- Write a client to bind to and use the server's objects.
It is now possible on some systems to skip the implementation of the server
and have the ORB activate the servant code thorugh the use of
Object Adapters.
Method Invocation Modes:
In a Distributed Object System a call to a method of a remote object
takes place through a local Proxy (also known as a Stub) which
communicates with the object on the remote system through a Skeleton
also on that system.
The call can be:
Parameter Passing Modes: When a method of a remote object
is invoked, the parameters of the call are sent across from the client
to the server.
If a parameter has a traditional data type, i.e. not an object,
it is passed by value. If it is an object, in CORBA until very recently
it could only be passed by reference. Now it can be passed by reference
or by value; in RMI and DCOM it can be passed
either by reference or by value. The mode in which a parameter
is passed has a great impact on performance.
When an object is passed by reference the server to which it is passed
will call the methods of the object remotely for execution
wherever that object is.
If instead the object is passed by value, a copy of the object is serialized
over to the server and used there locally. Of course this requires that
the methods of the transferred object be able to execute
on the receiving system. This is easy if the code is Java (or we remain
within a WINTEL world), less so in other
languages. When the parameter is passed by value, any changes made in the
transferred object are not seen in the system where the object was
copied from. Dynamic Class Download is what allows the passing
of objects by value.
Linking Mode: The methods of an object can be called
statically or dynamically. Statically is the usual way:
we know at compile time what is the object, say foo, what is the
method, say moo, and what are the parameters, thus we call explicitly
foo.moo(...).
But in some cases when we write our program we may not know what objects
will be available in its environment at run time. We want to be able at
run time to invoke a service (see below) and find
out what objects are available, calling then what is appropriate.
This can be done through the Dynamic Interface Invocation.
Similarly on the server side the invocation of the servant code can be
done statically, through the IDL skeleton, or dynamically through
the Dynamic Skeleton Interface.
- Interface Definition Language (IDL)
- This is the mechanism for defining interfaces, particularly in the
inter-language systems of CORBA and DCOM.
Java was designed to separate Interface definition from
Implementation definition, and thus the interface definition
constructs are utilized.
Here is an example of an IDL file (from "Corba Distributed Objects using Orbix", by S. Baker,
Addison-Wesley 1997);
// front.idl
typedef float Price;
struct Place {
char row;
unsigned long seat;
};
interface FrontOffice {
readonly attribute string name;
readonly attribute unsigned long numberOfSeats;
Price getPrice (in Place chosenPlace);
boolean bookSingleSeat (in Place chosenPlace, in string creditCard);
};
and here is the corresponding .h file generated by the IDL compiler:
// front.h
#include <CORBA.h>
typedef CORBA::Float Price;
struct Place (
CORBA::Char row;
CORBA::ULong seat;
};
// .. some other declarations that we skip, and then
class FrontOffice: public virtual CORBA::Object {
public:
virtual char* name() throw CORBA::SystemException);
virtual CORBA::uLong numberOfSeats()
throw (CORBA::SystemException);
virtual Price getPrice(const Place& chosenPlace)
throw (CORBA::SystemException);
virtual CORBA::Boolean bookSingleSeat (
const Place& chosenPlace,
const char* creditCard)
throw (CORBA::SystemException);
};
- Object Request Broker (ORB)
-
A system that uses objects (the client), or a system that makes available
objects (the servers), must have an Object Request Broker (ORB).
The ORB is the basic mechanism
for making requests to an object and for receiving the responses.
If the client and server
are in different systems, their ORBs (even if by different manufacturers)
must be able to interoperate. They can communicate
using a connection-oriented protocol called GIOP (General InterOrb Protocol),
or, if the transport layer is TCP/IP, using IIOP (Internet InterOrb Protocol).
Basic message codes
are Request, Reply, CancelRequest, LocateRequest, LocateReply,
CloseConnection, MessageError.
Usually the ORB does not take the form of a separate
process, instead it is a library linked with the user process. For example,
the Netscape browser comes with an included ORB.
- Interoperable Object References (IORs)
-
References to objects are called Interoperable Object
References (IORs). A IOR consists of three kinds of information:
- A Repository Id, which is an index in the Interface Repository for the
the IDL interface of the object.
- Protocol and Address information, namely,
in IIOP, the host name and port of the system where the object resides.
- An Object Key, which identifies the object at a system and consists of the
identifier of an Object Adapter, and an identifier of the object as known by
that adapter.
Binding is the process by which we arrive at a servant
given a IOR.
- Object Adapters (OA)
-
Object Adapters mediate between ORBs, Corba object references,
and the code written in some programming language that implements them,
the servants.
Object Adapters are responsible for
- Registration of implementations
- Generating and interpreting object references
- Mapping object references to implementations
- Activating and deactivating object implementations
- Invoking an object's method, via a skeleton, or via the Dynamic
Skeleton Interface.
Since an object may not be currently running, and it must run
in the context of a server process, an Object Adapter must if necessary
activate a process or a thread and execute the servant code.
A Basic Object Adapter (BOA) is available for this purpose.
It takes the form of a process distinct from
the ORB's. BOA implementations have tended to be proprietary so that
servant code is less portable than desireable.
Currently Portable Object Adapters (POA) are becoming available
that obviate this problem. As indicated in the following diagram,
a system may have multiple POA which in turn
can be each responsible for many objects.
Server System
+----------------------------+
| ->servant |
| +---+ / |
Call | +---+-->|POA|-->-->servant |
-------->| |ORB| +---+ |
| +---+-->+---+----->servant |
| |POA|----->servant |
| +---+ |
+----------------------------+
A servant is executed within a thread of a POA or as a process
forked by the POA.
A POA may follow a number of object activation
policies in forking processes:
- Shared Server Policy: A server process activated by the BOA will support
multiple objects.
- Persistent Server Policy: The server process, as in the shared policy,
is now registered and remains running independent of the activity status
of its objects.
- Unshared Server Policy: The server process now supports a single object.
- Server-per-method Policy: A server process is launched for each method
invocation, and terminated when the method terminates.
A POA may follow a number of multithreading policies in creating
threads. These policies to an extent mirror the activation
policies seen above:
- single-thread: a single thread is available to execute
sequentially all calls on methods of objects managed by this POA.
- thread-per-request: a separate thread is created
for each method invocation and deleted when the request is completed.
- thread-per-connection: now a separate thread is created
for each connection from a client and used to answer requests from that
client. It is deleted when the client disconnects.
- thread-per-servant: we have a separate thread for each
servant. So calls to distinct servants can be concurrent but calls to one
servant are sequential.
- worker-thread-pool: we have a pool of worker threads
and calls from clients are placed in a protected buffer whence they are
removed and processed by the worker threads.
- leader-follower: we have a pool of threads. They take turns
accepting IO requests from the clients. Each thread carries out the
request that it collected from the input.
- Registry
- This is a feature of the name service. Corba supports a registry
with ongoing persistence, while RMI's registry is restarted everytime the
server is restarted.
DCOM utilizes the NT's registry for finding objects/interfaces by
their GUID (Globally Unique Identifier - 16 bytes).
Corba's registry is distinguished in a
Interface Repository, where are kept the IDL definitions for all
the objects, and a Implementation Repository, where are kept the
executables for all the objects.
- Interface Multiple Inheritance
- In the definition DCOM, Microsoft dealt with the fragile base
class problem by
eliminating multiple inheritance when defining interfaces. Microsoft provides
similar functionality through aggregation and containment, containing the
objects you might otherwise inherit from and either expose there interfaces
as your own, or wrapping the object. All other systems appear to
provide multiple inheritance for interfaces, easing the programmer's workload.
- Maintain state between connections
- Because DCOM has a more procedural basis to its system than other
distributed objects systems, in can suffer when an unplanned disconnect
occurs. If the programmer has not saved the state of the DCOM object
before losing a connection, the objects state will be lost.
Because the other systems are based on a 'true' OOP model, the object
does not need to be explicitly saved, and a connection loss will
not result in the loss of the objects state. This also means that DCOM
relies on the client to provide the information necessary to restore
an object from storage when it has been saved.
- Through Firewalls
- Firewalls can pose problems to distributed object systems, since many
DO systems are based on
tcp/ip connections that for safety's sake
are often filtered out of a company's Internet feed at its entry firewall.
Several mechanism have been put in place to remedy this,
including tunneling in HTTP connections (inefficient), using proxies such
as SOCKS, or replacing the standard firewall with a firewall that
is friendly to Distributed Object System.
Iona appears to have done just that with its WonderWall firewall software.
- Multicast
- Systems supporting this feature allow simultaneous broadcast to
multiple clients.
While DCOM documentation mentions it's feasibility, RMI has stated plans
to implement this feature.
- Distributed Garbage Collection
- It deals with the question of how remote objects
are managed when they are no longer needed.
This is a problematic issue
and it seems that no perfect solutions exists.
In RMI this is handled by remote reference counting, which means that
if a client
disconnects for a period of time, the object they were connected to could
be garbage
collected (although an exception does notify the program when this occurs).
In Corba systems this is addressed in the Life Cycle Management Services.
It is again done by keeping count of
the number of connections to an object, saving and/or
deleting the object when the number of connections falls to zero.
In Java DCOM implementations, it is left to the OS to do garbage collection
at program shutdown time.
Obviously this won't work for ongoing servers, and it is
likely a temporary solution since C++ DCOM utilizes another mechanism
whereby an object keeps track of the events occurring
when another object claims
to be using it and/or finished with it.
This system too would seem to be frought with problems,
since it makes an object
dependent on the good behavior of other objects (ie. on their programmers )
so that they will release it when they are done with it.
In addition to
supporting calls to methods of remote objects Distributed Object Systems
provide a variety of Services and Facilities that make easier the development
of reliable distributed applications.
- Life Cycle Service
- Object Operations for:
- creating
- copying
- moving
- deleting
- Persistence Service
- A single interface for storing components persistently on a variety of
storage servers, such as:
- Object Databases (ODBMSs)
- Relational Databases (RDBMSs)
- Simple files
Java has begun supporting this internally through the java.io.
Serialization and Externalization mechanisms.
- Naming Service
-
Allows components on the bus to locate other components by name, including
federated naming contexts. The service allow object to be bound to existing
network directories or naming contexts - including:
- ISO's X.500
- OSF's DCE
- Sun's NIS
- LDAP
Corba supports this feature with persistence saving changes to the registry. Corba, given the name of an object, returns
an object reference to that object.
RMI does have a Naming Service, but it lacks persistence. DCOM does have a
registry to lookup objects by their GUID (Globally Unique Identifier).
- Event Service
- Allows Components on the bus to dynamically register or unregister their
interest in specific events. The service defines a well known object
called an event channel that collects and distributes events among
components that know nothing of each other, from the servers to the clients.
This is supported by CORBA, and JDK 1.1 new event model certainly goes
a long way towards making this feasible in pure-Java systems.
- Concurrency Control Service
- Provides a lock manager that can obtain locks on behalf of either
transactions or threads and make concurrent access to objects safe.
- Transaction Service
- Provides two-phase commit coordination among recoverable components using
either flat or nested transactions.
- Relationship Service
- Provides a way to create dynamic associations (or links) between
components that know nothing of each other.
Provides mechanisms for traversing the links that group these components.
Use this service to:
- Enforce referential integrity constraints
- Track containment relationships
- In fact, for any type of linkage among components.
- Externalization Service
-
Provides a standard way to get data into and out of a component using a
stream-like mechanism. This supports objects migration.
- Query Service
- Provides query operations for objects via a superset of:
SQL3 and...
ODMG's OQL (Object Database Management Groups's Object
Query Language)
- Licensing Service
- Provides operations for metering the use of components to
ensure fair
compensation for their use. The service supports any model of
usage control at any point in a components life cycle.
It supports charging by:
- per session
- per node
- per instance creation
- per site
CORBA provides this facility.
DCOM provides a licensing system that looks to a local file to
see if a file exists that contains the license number to enable
a user to
run a program. DCOM also enable a per component licensing model via
a licensing key in the registry.
- Properties Service
- Provides operations to let you associate named values (properties) with
any component. Using this service you dynamically associate properties
with a component's state, such as a title or date.
It would seem this is simple enough to do in Java, by having your object
contain an java.util.property object.
- Security Service
-
- Authentication: Are you who you claim to be?
- Authorization: Are you allowed to use this resource?
- Audit Trails: Where have you been?
- Non-Repudiation: Was this message tampered with?
- Other:
- Inter-Orb security
- Federated security domains
- Trusted domains
- Protection boundaries
DCOM supports many of these features, and according to some newsgroup
arguments, implements them better than Corba does.
- Time Service
- Maintains a single notion of time across different machines. One can also
request alarms, that is events to occur at specified times.
- Trader Service
- 'Matchmaking' services
Provides a yellow pages like service, advertising attributes of object
offered.
Federations of traders advertise services, while each individually manages
policies and services.
- Collections Service
- Provides operations to manipulate objects in a group
Examples: Queues, Stacks, Lists, Arrays, Trees, Sets, Bags
A third-party library jgl offers many of these features to Java.
- Change Management Service
- Provides facilities to track different component versions, both interface
and implementation. Maintains evolution history
Ensure an object uses a consistent implemention version
Version encoded into object references
Find object versions by name
Contexts, such as example, demo, test & release
Check-out/Check-in
DCOM provides a Versioning service
Where Services are utilities for objects, Facilities are utilities
for applications. Facilities are separated into:
- Horizontal Common Facilities which are shared by most systems.
There are four major kinds of such facilities:
- User Interface: makes an information system accessible to its users
and responsive to their needs. An example is the Compound Presentation
Facility, desktop management, scripting, rendering, ..
- Information Management: definition, storage, retrieval, management,
and interchange of information, plus calendar support.
- Systems Management: management of complex, multi-vendor information systems
by service providers. It includes management tools and use monitoring and
collection facilities.
- Task Management: automation of work including work flow, agents,
rule management.
At present OMG's work on horizontal facilities is on hold, deferring to further
evolution of object services.
- Vertical Market Facilities,
that are specific to particular kinds
of applications, for example, business, healthcare, manufacturing, accounting,
financial/insurance, electronic commerce, transportation.
Facilities will be implemented taking advantage of existing services.
Objects will be able to utilize, by inheritance or aggregation, both
services and facilities.
Here is a very simple example that runs with the Orbix ORB.