Contexte et motivation
Les logiciels et les systèmes informatiques en général croissent en nombre et en complexité dans des domaines d’application aussi divers que les serveurs d’entreprise ou les systèmes embarquées et contraints. Cette complexité croissante est caractérisée par l’augmentation de la taille des logiciels (un serveur d’application comme JOnAS [JOn] comporte plusieurs millions de lignes de codes), l’hétérogénéité des plateformes à tout niveau (systèmes d’exploitation, intergiciels et applications) et la multiplication des normes et des standards : Java EE [Jav] dans le domaine des serveurs d’applications regroupe ainsi de nombreuses technologies Java (JMS, JCA, etc.). L’administration de ces systèmes est également de plus en plus complexe et nécessite de leur part des capacités d’évolution pour des opérations de maintenance, des besoins de mise à jour ou d’adaptation en fonction de leur contexte d’exécution. L’évolutivité [LP76] est une propriété essentielle qui caractérise la capacité d’un système à être modifié au cours de son cycle de vie. Une évolution (ou modification) peut concerner la correction d’erreurs de conception ( » bugs « ) dans le système, l’ajout de nouvelles fonctionnalités, ou encore l’optimisation de fonctionnalités existantes. La maintenance corrective [Lap92b] est ainsi un bon exemple d’évolution particulière d’un système consistant à le remettre dans un état spécifié. Deux types d’évolutions sont à distinguer suivant l’état du cycle de vie du système considéré : les évolutions statiques qui interviennent quand le système est arrêté sous forme par exemple de » patchs » de code qui nécessitent la recompilation et le redémarrage du système, et les évolutions dynamiques réalisées dans un système en train de s’exécuter, nous parlerons plus spécifiquement de reconfigurations dynamiques dans ce dernier cas. Les reconfigurations dynamiques [KM90, MK96] sont un moyen de faire évoluer les systèmes tout en préservant leur disponibilité. Ce sont en effet des modifications effectuées pendant l’exécution d’un système qui ne nécessitent pas d’arrêt complet ou de recompilation du système modifié et permettent donc de préserver sa continuité de services. La capacité d’évolution est au coeur de la problématique des systèmes adaptatifs et de l’informatique autonomique. Les systèmes adaptatifs [KBC02] évoluent automatiquement en fonction du contexte d’exécution : le changement de contexte entraîne typiquement une reconfiguration dynamique du système pour réaliser l’adaptation. L’informatique autonomique [KC03] est une réponse à la complexité croissante de l’administration des systèmes logiciels en les dotant de la capacité de s’auto-administrer par l’intermédiaire d’une boucle de régulation similaire aux boucles de contrôle dans le domaine de l’automatique. La réaction à l’intérieur de la boucle repose sur la reconfiguration dynamique du système auto-administré. Les reconfigurations dynamiques peuvent être basées sur des modifications d’architecture [ADG98, OMT98] des systèmes. Le composant [Szy02] est un paradigme de programmation en génie logiciel au même titre que l’objet pour construire des systèmes logiciels. Un modèle de composant définit des standards de construction, de composition et d’interaction entre des briques logicielles appelées composants. Les systèmes à base de composants offrent de bonnes propriétés pour être reconfigurés dynamiquement comme l’encapsulation forte (boîte noires ou grises), la modularité, un couplage lâche entre composants, et la séparation des préoccupations [HL95]. En effet, une séparation claire entre le code fonctionnel et le code non-fonctionnel ainsi que la représentation explicite des dépendances entre composants permettent d’utiliser le composant comme granularité des reconfigurations en isolant leurs effets sur le système reconfiguré. Parallèlement au besoin d’évolutivité des systèmes se pose le problème de leur fiabilité, plus particulièrement suite à leurs évolutions. L’administration au sens de l’observation et de la modification des systèmes est en effet, de part sa complexité, sujette à des erreurs qui peuvent en les modifiant rendre les systèmes non ables [Ore98]. La fiabilité [lap92a] est un attribut de la sûreté de fonctionnement qui est la mesure de la délivrance d’un service correct pour un système donné. Autrement dit, un système n’est able que s’il est dans un état correct (ou cohérent) par rapport à une spécification. Dans le cas des architectures à composants, une spécification à considérer est celle du modèle de composants sous-jacent. Une condition nécessaire à la fiabilité de ce type de système est donc sa conformité au modèle de composants. Une reconfiguration dynamique doit être une transformation valide de l’état d’un système pour qu’il reste cohérent. Une reconfiguration sera ainsi invalide (i.e. mènera à un système non fiable) si elle viole la spécification du modèle de composants considéré. Plus généralement, toute faute est susceptible d’entrainer une défaillance qui va venir perturber le fonctionnement d’un système et donc réduire sa fiabilité [Lap92b]. Les fautes considérées sont plus particulièrement les fautes logicielles internes aux applications (bugs, exceptions, etc.) et les fautes dues au système ou au matériel sous-jacent. Les reconfigurations dynamiques peuvent ainsi être exécutées en présence de fautes : une panne franche de machine sur laquelle le système est localisé, entièrement dans un contexte centralisé ou en partie dans un contexte réparti, peut interrompre l’exécution d’une reconfiguration. D’autre part, une reconfiguration, si elle est une transformation invalide, génère une faute à l’origine de l’incohérence de l’état du système reconfiguré comme c’est le cas par exemple avec la violation du modèle de composants. Une reconfiguration doit donc être exécutée malgré des fautes et ne pas créer de nouvelles fautes. Pour faire face aux différentes fautes que peut rencontrer un système au cours de son existence, il existe essentiellement deux méthodes différentes : la prévention de fautes et la tolérance au fautes. La prévention de fautes consiste à éliminer les fautes au plus tôt avant leur occurrence pour éviter qu’elles se produisent pendant l’exécution du système, elle repose essentiellement sur des techniques d’analyse statique. La tolérance aux fautes a pour objectif de laisser les fautes se produire pour les réparer de manière transparente.
Langages de description d’architecture et styles architecturaux
Les langages de description d’architecture. La prise en compte des concepts architecturaux au niveau des langages de programmation permet une traçabilité tout au long de la phase de développement et du déploiement des composants. Les langages de description d’architecture sont des langages généralement déclaratifs dans lesquels le couplage entre spécification architecturale et implémentation est faible. Ces langages dédiés permettent de spécifier des configurations architecturales comme des assemblages de composants et éventuellement de connecteurs. Ils peuvent être classés en deux grandes familles [MT00]. La famille des langages de description à laquelle appartiennent Wright [All97] et Rapide [LKA+95] privilégient la description des éléments de l’architecture et leur assemblage structurel. Ils ont pour but la formalisation, la vérification et la validation d’architecture. Elle est accompagnée d’outils de modélisation et d’analyseur syntaxique. Certains ADL comme Wright (cf. Figure 2.1) permettent de spécifier du comportement dans les définitions de composants : à chaque port est associée une description formelle dans l’algèbre de processus CSP (Communicating Sequential Processes) spécifiant ses interactions avec l’environnement tandis que la partie calcul décrit le comportement interne du composant. La famille de langages de configuration à laquelle appartient Darwin [MK96] se focalisent sur la description de la configuration d’une architecture et sur la dynamique du système. Ils sont accompagnés d’outils de modélisation et de génération de code mais aussi d’une plate-forme d’exécution ou de simulation d’un système, voire de modification dynamique pendant l’exécution.
Systèmes adaptatifs et informatique autonomique
Systèmes adaptatifs. Une adaptation est une modification d’un système en réponse à un changement dans son contexte. L’objectif est que le système résultant soit plus apte fonctionnellement dans son nouveau contexte qu’avant son adaptation. Par conséquent, une adaptation est toujours une modification d’un système mais une modification quelconque n’est pas une adaptation si le système modifié ne peut être considéré comme » meilleur « que l’ancien selon les critères considérés (e.g. performance, fiabilité, qualité de service, etc.) dans ses nouvelles conditions d’exécution. Dès lors, un système sera dit adaptable si une entité externe (logiciel ou humaine) peut le faire évoluer. Il sera dit adaptatif s’il est capable tout seul de s’adapter automatiquement. Un système adaptatif est ainsi à la fois le sujet et l’acteur de l’adaptation [DC01] : il se modifie de façon autonome en fonction de son contexte. Cette modification se fait donc dynamiquement pendant son exécution. Par conséquent, un système adaptatif peut reposer sur des reconfigurations dynamiques de son architecture pour réaliser son adaptation [OGT+99]. Un système adaptatif est caractérisé dans [Dav05] par :
un ensemble d’opérations pour modifier, adapter le système ;
un contexte qui regroupe tous les éléments externes au système et qui influencent son fonctionnement ;
une fonction d’adéquation qui permet à tout moment de savoir dans quelle mesure le système réalise ses objectifs relativement à son contexte ;
une stratégie d’adaptation en charge de la mise en oeuvre du processus d’adaptation dans le système.
Informatique autonomique. Parmi les systèmes adaptatifs, une initiative d’IBM distingue les systèmes dits autonomiques [KC03]. Avec la complexité croissante des systèmes et des applications, le coût d’administration devient de plus en plus considérable et les difficultés commencent à dépasser les compétences des administrateurs. Par conséquent, une nouvelle tendance est apparue qui consiste à automatiser (au moins en partie) les fonctions d’administration. C’est l’un des objectifs de ce qui est appelé l’informatique autonomique (Autonomic Computing). L’informatique autonomique peut reposer sur l’architecture des systèmes pour la mise en oeuvre des algorithmes de contrôle [WHW+04] et plus particulièrement sur les reconfigurations dynamiques dans les architectures à composants [KM07]. Le but de l’Autonomic Computing est d’offrir aux systèmes des capacités d’auto-administration, à travers des capacités d’auto-adaptation face aux changements de contexte. Les systèmes autonomiques sont classés en quatre catégories selon les objectifs de l’adaptation :
L’auto-configuration consiste à déployer et configurer automatiquement le système suivant des règles prédéfinies.
L’auto-optimisation pour le contrôle et l’adaptation du système suivant des changements au niveau fonctionnel ou extérieur au système pour assurer un certain niveau de performance.
L’auto-réparation pour la détection et le diagnostique des pannes et leur correction de manière automatique.
L’auto-protection consiste à prendre des mesures nécessaires pour se protéger des attaques malveillantes et savoir se défendre contre ces attaques.
Boucle de contrôle. L’architecture d’un système autonome a été initialement proposée par IBM [KC03] sous forme d’une boucle de contrôle, concept issu de la théorie du contrôle en automatique. Le gestionnaire autonomique remplit différentes fonctions :
L’observation du système ou monitoring pour la collecte des données qui caractérisent le comportement du système.
L’analyse des informations observées pour interpréter ces données en se basant sur une connaissance du système administré.
La décision en utilisant des algorithmes dont le rôle est de déterminer un plan d’action.
L’exécution pour la mise en oeuvre du plan en envoyant des commandes aux actionneurs de l’élément administré.
Le gestionnaire communique avec l’élément administré grâce aux capteurs et aux actionneurs. Les capteurs et les actionneurs offrent des interfaces principales implantées par le système administré pour observer son état et pour le modifier à des niveaux variables de granularité.
Cas de l’Auto-réparation. Un système est sujet à une défaillance quand il dévie de son comportement attendu. Ceci peut résulter d’une erreur humaine au niveau de l’utilisation de l’application (une valeur d’entrée incorrecte) ou une erreur matérielle (la panne franche). La disponibilité d’un système s’exprime généralement sous forme de taux et est la fraction de temps pendant laquelle le système est à même de délivrer un service correct.
K-Component
Description
Introduction. K-Component [DCC01, DC01] est un modèle de composants supportant les reconfigurations dynamiques grâce à la réflexion architecturale pour construire des systèmes adaptatifs. Le modèle garantit l’intégrité et la sûreté des évolutions des systèmes à l’exécution en modélisant les reconfigurations comme des opérations de transformation de graphes sur les architectures. De plus, des programmes spécifiques appelés contrats d’adaptation permettent de séparer les préoccupations entre le code d’adaptation et le code fonctionnel des composants.
Modèle de composants. L’architecture des systèmes est réifiée sous forme de graphe connecté et typé : les noeuds du graphe représentent les interfaces et sont annotés par les composants qui leur appartiennent et les implémentent, les arcs représentent les connecteurs entre interfaces de composants et sont annotés par des propriétés reconfigurables. Un exemple d’une telle propriété est le protocole de communication mis en oeuvre par un connecteur. Un composant de gestion de configurations ( » configuration manager « ) est en charge de la réification de l’architecture des systèmes et de l’exécution des reconfigurations. Le code des connecteurs est généré à partir des définitions IDL des interfaces et expose des opérations de connexion et de déconnexion de composants. L’implémentation de composants et leur assemblage sont réalisés en C++ sans passer par l’utilisation d’un ADL. Le méta-modèle d’architecture du système est alors extrait et généré sous forme d’un graphe de configuration décrit en XML. Ce descripteur est complété par le programmeur pour y introduire les composants développés. L’architecture peut finalement être instanciée par le gestionnaire de configuration.
Reconfigurations dynamiques. Les reconfigurations dynamiques sont modélisées comme des transformations conditionnelles des graphes de configuration . Une transformation de graphe est une règle qui définit quand et comment le graphe est modifié. Le gestionnaire de reconfiguration exécute les reconfigurations transactionnellement. Cependant, les seules reconfigurations autorisées dans le modèle sont le remplacement de composants et le changement des propriétés des connecteurs. Un protocole de reconfiguration est proposé pour l’atteinte d’un état stable au cours des reconfigurations des composants. Ce protocole permet de figer l’état des composants et des connecteurs impactés par les reconfiguration.
Contrats d’adaptation. Les contrats d’adaptation contiennent des règles conditionnelles pour la transformation des architectures. Ils jouent ainsi le rôle de contraintes architecturales en restreignant les reconfigurations possibles sur une architecture donnée. Les contraintes architecturales sont en effet des propriétés ou des assertions sur les configurations de composants et de connecteurs. Les reconfigurations spécifiées dans les contrats sont déclenchées par des événements d’adaptation issue du système reconfiguré. Ces contrats sont spécifiés dans un langage dédié et associe des événements d’adaptation avec des opérations de reconfiguration. Le gestionnaire de configurations a la charge de l’ordonnancement et de l’exécution des contrats d’adaptation en testant l’occurrence des événements d’adaptation.
Evaluation
K-Component propose un modèle réflexif de composants et de reconfiguration dynamique reposant sur des transformations de graphes. Les garanties apportées par le modèle sont de plusieurs ordres. Un protocole de synchronisation entre reconfigurations et exécution des systèmes appelé protocole de reconfiguration est présenté. Les reconfigurations sont contraintes par l’occurrence d’événements d’adaptation pour vérifier la satisfaction d’assertion dans les architectures. Enfin les reconfigurations sont des transformations de graphes simples réalisées de manière transactionnelle. L’approche comporte cependant plusieurs limitations et suppose des hypothèses contraignantes sur les reconfigurations. D’une part, les reconfigurations possibles sont limitées à deux types de transformation de graphe. D’autre part, les mécanismes de contraintes par des contrats d’adaptation nécessite obligatoirement l’émission d’événements d’adaptation, une reconfiguration ne pouvant être exécutée spontanément de l’extérieur du système. Enfin, si un mécanisme transactionnel est mentionné pour l’exécution des reconfigurations sur les architectures, aucune précision n’est donné sur d’éventuelles garanties d’atomicité, de concurrence et de durabilité.
|
Table des matières
1 Introduction
1.1 Problématique
1.1.1 Contexte et motivation
1.1.2 Enoncé et analyse de la problématique
1.2 Présentation des contributions
1.3 Organisation du document
I Etat de l’art
2 Technologies et concepts associés au sujet
2.1 Programmation par Composants
2.1.1 Modèles de composant
2.1.2 Langages de description d’architecture et styles architecturaux
2.2 Dynamicité des architectures logicielles
2.2.1 Réflexion et architectures réflexives
2.2.2 Reconfigurations dynamiques
2.2.3 Systèmes adaptatifs et informatique autonomique
2.3 Sûreté de fonctionnement
2.3.1 Attributs et méthodes de la sûreté de fonctionnement
2.3.2 Systèmes transactionnels
2.4 Conclusion
3 Etat de l’art sur la fiabilité des reconfigurations dynamiques
3.1 Critères de sélection et d’évaluation des travaux
3.2 Modèles de composants réflexifs
3.2.1 FORMAware
3.2.2 K-Component
3.2.3 OpenRec
3.3 Plateformes construisant un modèle d’architecture
3.3.1 Plastik
3.3.2 Rainbow
3.3.3 ArchStudio
3.3.4 Jade
3.4 Environnements pour la gestion de l’évolution des architectures
3.4.1 Mae
3.4.2 c2sadel
3.5 Synthèse
II Contributions
4 Modélisation des configurations Fractal
4.1 Démarche de vérification de la cohérence des configurations
4.2 Le modèle de composants Fractal
4.2.1 Coeur du modèle
4.2.2 Implémentations et outils associés au modèle
4.3 Spécification et extension du modèle Fractal
4.3.1 Un méta-modèle pour Fractal
4.3.2 Spécification du modèle par des contraintes d’intégrité
4.3.3 Extensions du modèle sous forme de contraintes
4.4 Traduction et vérification de la spécification
4.4.1 Vérification de la cohérence de la spécification
4.4.2 Traduction des contraintes en langage exécutable
4.5 Conclusion
5 Spécification des reconfigurations dynamiques
5.1 Dynamicité des architectures à base de composants
5.1.1 Hypothèses sur les reconfigurations dynamiques
5.1.2 Contraintes d’intégrité liées à la dynamicité des configurations
5.2 Analyse des opérations de reconfiguration dans Fractal
5.2.1 Spécification de la sémantique des opérations primitives
5.2.2 Propriétés des opérations primitives
5.2.3 Traduction des conditions sur les opérations de reconfiguration
5.3 Conclusion
6 Une approche transactionnelle pour fiabiliser les reconfigurations dynamiques
6.1 Définition des reconfigurations transactionnelles
6.1.1 Motivation de l’approche transactionnelle
6.1.2 Modèle des transactions pour les reconfigurations
6.2 Atomicité des reconfigurations pour assurer la tolérance aux fautes
6.2.1 Protocole de validation atomique
6.2.2 Modèle de » undo »
6.3 Cohérence du système définie par des contraintes d’intégrité
6.3.1 Modèle de contraintes
6.3.2 Vérification des contraintes
6.4 Isolation des reconfigurations pour gérer les reconfigurations concurrentes
6.4.1 Stratégie de gestion de la concurrence
6.4.2 Isolation du niveau fonctionnel
6.5 Durabilité des reconfigurations pour permettre la reprise en cas de défaillance
6.5.1 Modèle de défaillances
6.5.2 Reprise sur défaillances
6.6 Conclusion
7 Architecture globale et modulaire des mécanismes de reconfigurations fiables
7.1 Une architecture modulaire à base de composants
7.1.1 Le moniteur transactionnel
7.1.2 Le gestionnaire de ressources
7.1.3 Le gestionnaire de recouvrement
7.1.4 Le gestionnaire de cohérence
7.1.5 Le gestionnaire de concurrence
7.1.6 Le gestionnaire de durabilité
7.2 Des contrôleurs Fractal pour la gestion des transactions
7.2.1 Contrôleurs et propriétés ACID
7.2.2 Interception des invocations d’opérations de reconfiguration
7.3 Extensions de l’ADL Fractal pour les reconfigurations transactionnelles
7.3.1 Les modules de spécification de contraintes
7.3.2 Les modules liés à la persistance des données
7.3.3 Modification de modules existants
7.4 Conclusion
8 Evaluation des contributions
8.1 Mise en oeuvre des recongurations transactionnelles
8.1.1 Un » HelloWorld transactionnel »
8.1.2 Intégration dans une chaîne de validation FScript
8.2 Evaluation de performances
8.2.1 Empreinte mémoire
8.2.2 Temps d’exécution
8.2.3 Comparaison des modes de mise à jour
8.3 Reconfigurations dynamiques fiables pour l’informatique autonomique
8.3.1 Une boucle autonomique générique
8.3.2 Auto-protection mémoire d’un serveur Web
8.3.3 Auto-optimisation d’un cluster de serveur Web
8.3.4 Auto-réparation de panne franche dans un cluster de serveur Web
8.3.5 Auto-réparation d’un server Java EE dans un cluster
8.4 Contrôle d’accès pour les recongurations dynamiques et transactionnelles
8.4.1 Un modèle de sécurité pour les opérations de reconfiguration
8.4.2 Evaluation des reconfigurations transactionnelles et sécurisées
8.5 Conclusion
9 Conclusion
9.1 Synthèse et bilan des contributions
9.2 Perspectives
Télécharger le rapport complet