Objets distribués et middleware¶
L'ere ou l'on a voulu faire communiquer des objets à travers le réseau — et les leçons coûteuses de cette ambition.
L'ambition des objets distribués¶
Au début des années 1990, la programmation orientée objet triomphait. L'idée suivante semblait naturelle : si les objets fonctionnent bien à l'intérieur d'un processus, pourquoi ne pas les faire communiquer à travers le réseau ? Un objet client appellerait des méthodes sur un objet serveur, peu importe ou cet objet se trouve physiquement. La localisation deviendrait transparente.
Trois technologies majeures ont porte cette vision : CORBA (multi-plateforme, multi-langage), DCOM (Microsoft) et RMI (Java). Chacune a pousse l'idée dans une direction différente. Orfali, Harkey et Edwards, dans CORBA : des concepts à la pratique, ont documente cette epoque avec un optimisme qui rend la lecture rétrospective presque douloureuse — on sait comment l'histoire se termine.
Pollet (Architectures logicielles réparties) situe ces technologies dans un cadre plus large, celui du middleware d'intégration, en montrant les compromis entre transparence et performance.
CORBA : le standard universel¶
CORBA (Common Object Request Broker Architecture) est ne de l'OMG (Object Management Group) en 1991. L'ambition etait immense : permettre a des objets écrits dans n'importe quel langage, tournant sur n'importe quelle plateforme, de communiquer entre eux de manière transparente.
Les composants de CORBA¶
L'architecture CORBA repose sur plusieurs couches :
| Composant | Rôle |
|---|---|
| IDL (Interface Définition Language) | Langage neutre pour décrire les interfaces des objets |
| ORB (Object Request Broker) | Bus logiciel qui route les appels entre objets |
| IOR (Interoperable Object Référence) | Référence unique pour localiser un objet distant |
| IIOP (Internet Inter-ORB Protocol) | Protocole réseau entre ORBs de différents éditeurs |
| Stubs / Skeletons | Code généré pour serialiser/deserialiser les appels |
Le flux d'un appel CORBA est le suivant :
sequenceDiagram
participant C as Client (C++)
participant ST as Stub IDL
participant ORB1 as ORB Client
participant ORB2 as ORB Serveur
participant SK as Skeleton IDL
participant S as Serveur (Java)
C->>ST: appel methode locale
ST->>ORB1: marshalling parametres
ORB1->>ORB2: IIOP sur TCP/IP
ORB2->>SK: demarshalling
SK->>S: appel implementation
S-->>SK: resultat
SK-->>ORB2: marshalling reponse
ORB2-->>ORB1: IIOP
ORB1-->>ST: demarshalling
ST-->>C: retour resultat IDL : le contrat d'interface¶
L'IDL etait l'idée la plus elegante de CORBA. On definissait les interfaces dans un langage neutre, puis un compilateur IDL generait automatiquement le code client (stub) et serveur (skeleton) dans le langage cible — C++, Java, Python, COBOL, Ada.
// Exemple IDL CORBA
module banque {
interface Compte {
readonly attribute string titulaire;
readonly attribute float solde;
exception FondsInsuffisants {
float solde_actuel;
float montant_demande;
};
void deposer(in float montant);
void retirer(in float montant)
raises (FondsInsuffisants);
float consulterSolde();
};
interface Agence {
Compte creerCompte(in string nom, in float depot_initial);
Compte trouverCompte(in string numero);
};
};
Les services CORBA¶
CORBA ne se limitait pas aux appels distants. Le standard definissait une collection de services :
- Naming Service : annuaire hierarchique pour localiser des objets par nom
- Trading Service : recherche d'objets par propriétés (équivalent d'un pages jaunes)
- Event Service : communication asynchrone par événements
- Transaction Service (OTS) : transactions distribuées ACID
- Security Service : authentification et autorisation
- Persistence Service : stockage transparent des objets
Note
La liste complète des services CORBA comptait plus de 15 spécifications. La plupart n'ont jamais été implementees correctement par les éditeurs, ce qui a mine l'interopérabilité promise par le standard.
DCOM : la réponse Microsoft¶
DCOM (Distributed Component Object Model) etait la version distribuée de COM, le modèle de composants de Microsoft. La ou CORBA visait l'universalite multi-plateforme, DCOM assumait d'être lie a Windows.
DCOM utilisait le même modèle que CORBA — interfaces, stubs, marshalling — mais avec des outils intégrés à l'écosystème Microsoft : Visual Basic pour les clients, C++ ou VB pour les serveurs, le registre Windows pour la localisation des composants.
Les avantages de DCOM etaient sa simplicité d'utilisation dans l'écosystème Windows et son intégration avec les outils Microsoft. Ses limites etaient son enfermement dans Windows et sa difficulté a traverser les firewalls — DCOM utilisait des ports dynamiques et le protocole ORPC, incompatible avec les proxies HTTP.
DCOM a évolue vers COM+ puis vers .NET Remoting, avant d'être finalement remplacé par WCF (Windows Communication Foundation), puis par les API REST et gRPC.
RMI : les objets distribués en Java¶
RMI (Remote Method Invocation) est la solution Java pour les objets distribués. Plus simple que CORBA, RMI se limite au monde Java — un objet Java appelle des méthodes sur un autre objet Java situe dans une JVM distante.
Mécanisme de RMI¶
// Interface distante
public interface CompteRemote extends Remote {
float getSolde() throws RemoteException;
void deposer(float montant) throws RemoteException;
void retirer(float montant)
throws RemoteException, FondsInsuffisantsException;
}
// Implementation serveur
public class CompteImpl extends UnicastRemoteObject
implements CompteRemote {
private float solde;
public CompteImpl(float soldeInitial) throws RemoteException {
this.solde = soldeInitial;
}
@Override
public synchronized float getSolde() throws RemoteException {
return solde;
}
@Override
public synchronized void deposer(float montant)
throws RemoteException {
solde += montant;
}
@Override
public synchronized void retirer(float montant)
throws RemoteException, FondsInsuffisantsException {
if (montant > solde) {
throw new FondsInsuffisantsException(solde, montant);
}
solde -= montant;
}
}
RMI utilise un registre (rmiregistry) pour localiser les objets distants. Le serveur enregistre ses objets dans le registre sous un nom. Le client interroge le registre pour obtenir une référence (stub) vers l'objet distant.
graph LR
subgraph "JVM Client"
CL["Client"]
STUB["Stub"]
end
subgraph "Registry"
REG["RMI Registry<br/>port 1099"]
end
subgraph "JVM Serveur"
SKEL["Skeleton"]
IMPL["CompteImpl"]
end
CL --"1. lookup('Compte')"--> REG
REG --"2. retourne stub"--> CL
CL --"3. appel methode"--> STUB
STUB --"4. JRMP"--> SKEL
SKEL --"5. appel reel"--> IMPL La serialisation Java permet de transmettre des objets complexes entre JVMs. RMI serialise automatiquement les parametres et les valeurs de retour. C'est elegant mais dangereux : la deserialisation d'objets non fiables est devenue l'une des vulnérabilités les plus exploitees dans l'écosystème Java.
Warning
La deserialisation Java est un vecteur d'attaque majeur. Des frameworks comme Apache Commons Collections ont été exploites via RMI pour exécuter du code arbitraire à distance. C'est l'une des raisons pour lesquelles les objets distribués ont été abandonnes au profit de formats de serialisation explicites (JSON, Protocol Buffers).
Pourquoi les objets distribués ont échoué¶
Les trois technologies — CORBA, DCOM, RMI — partageaient la même vision fondamentale : rendre les appels distants transparents, comme des appels locaux. Cette vision s'est heurtee a des réalités incontournables.
La complexité opérationnelle¶
CORBA necessitait un ORB sur chaque machine, un service de nommage, des fichiers IDL synchronisés entre client et serveur, et une gestion fine du cycle de vie des objets distribués. Le coût d'exploitation etait disproportionne par rapport à la valeur apportee.
L'interopérabilité illusoire¶
CORBA promettait l'interopérabilité entre éditeurs via IIOP. En pratique, les ORBs de différents éditeurs (IONA Orbix, Borland VisiBroker, IBM WebSphere) etaient rarement compatibles. Les extensions propriétaires rendaient le code non portable.
Le problème des firewalls¶
Les objets distribués utilisaient des protocoles binaires sur des ports non-standard. Les firewalls d'entreprise bloquaient ces communications. Le port 80 (HTTP) etait le seul port systematiquement ouvert. Cette réalité a directement favorise l'émergence des Web Services bases sur HTTP.
Les 8 erreurs du calcul distribué¶
Peter Deutsch et James Gosling ont formalisé les hypothèses fausses que font les développeurs de systèmes distribués :
- Le réseau est fiable
- La latence est nulle
- La bande passante est infinie
- Le réseau est sécurisé
- La topologie ne change pas
- Il y a un seul administrateur
- Le coût de transport est nul
- Le réseau est homogène
Les objets distribués violaient systematiquement ces contraintes en masquant le réseau derriere des appels de méthodes apparemment locaux.
Les leçons apprises¶
L'échec des objets distribués n'est pas un échec total. Plusieurs principes durables en ont emerge :
Les contrats d'interface sont essentiels. L'IDL de CORBA etait une excellente idée mal implémentée. On retrouve ce concept dans les schémas OpenAPI, les fichiers .proto de gRPC, et les schémas GraphQL. Définir le contrat avant l'implémentation reste une bonne pratique.
La transparence de localisation est dangereuse. Pretendre qu'un appel distant est identique à un appel local conduit à des systèmes fragiles et lents. Les API modernes rendent la frontiere réseau explicite — on sait qu'on fait un appel HTTP, avec les implications que cela comporte.
Les standards trop ambitieux échouent. CORBA a voulu standardiser trop de choses (16 services, des dizaines de spécifications). Les standards qui reussissent sont minimalistes : HTTP, JSON, SQL. Ils définissent un socle commun et laissent les implémentations innover au-dessus.
Le protocole doit traverser les firewalls. Toute technologie qui ne passe pas le port 80 est condamnee a moyen terme. Les Web Services (SOAP sur HTTP) et REST ont gagne précisément parce qu'ils utilisaient HTTP comme transport.
L'ere des objets distribués a dure une dizaine d'années (1993-2003). Elle a laisse place a SOA et aux Web Services, qui ont repris l'idée de communication inter-applications tout en abandonnant l'illusion de la transparence objet.
Chapitre suivant : SOA et Web Services — l'industrialisation des services, entre promesses d'interopérabilité et réalité de l'ESB.