Archives du mot-clé Complexité

Introduction à la performance des systèmes d’information

Cet article a pour objectif de poser quelques définitions de base qui seront reprises dans une suite d’articles à venir sur la gestion des performances des Systèmes d’Information, qui traiteront différents points de vue : pilotage du niveau de service, optimisation du temps de réponse des applications, plan de capacité, déploiement de grands systèmes applicatifs, optimisation des ressources, etc.

La gestion des performances d’un SI est un problème délicat pour deux raisons :
parce que les SI sont de plus en plus complexes d’une part et parce que d’autre part la performance d’un SI ou d’une application est une notion relativement complexe en soit. La performance, à l’image d’autres notions transversales du SI comme l’urbanisme ou la
sécurité, est en effet une notion vaste qui exige différents points de vue pour être correctement traitée.

Beaucoup de SI rencontrent de fait des problèmes de performance qui se traduisent
par des symptômes assez différents comme des écroulements sous des pics de charge (par exemple dans des périodes de solde ou de clôture comptable), des changements d’échelle douloureux voire impossible quand l’activité d’une application ou d’un système s’accroît fortement, des coûts techniques qui dérivent de manière non
proportionnelle avec l’activité, des niveaux de service qui se dégradent et pénalisent les utilisateurs métier, des instabilités techniques récurrentes, etc.

Notre conviction est que certains problèmes de performance sont des problèmes complexes et qu’à ce titre, ils exigent une démarche particulière, et une vision relativement globale et structurée de la problématique. Le développement de la complexité des systèmes d’information ne fait qu’accroître ces cas où de nouvelles approches, ou au moins des approches utilisées dans d’autres domaines que celui de
l’informatique de gestion, deviennent nécessaires.

Quelques exemples de problèmes de performance
complexes

Tous les problèmes de performance ne sont pas complexes, fort heureusement. Quand il s’agit seulement de corriger une anomalie dans un programme, d’optimiser un
traitement ou une requête dans une base de données, d’accroître la puissance d’un serveur, les processus naturels et standards du développement et de l’exploitation des SI sont suffisants pour résoudre les problèmes qui peuvent apparaître et qui sont de fait
plus des incidents que de vrais problèmes au sens ITIL du terme.

Mais il y a certains cas où le problème ne se trouve pas facilement isolé sur un
point d’expertise où la bonne compétence dans la DSI apportera naturellement et facilement une solution. Il y a des cas, où même en « payant » et en ajoutant des
ressources le problème n’est pas résolu pour autant et des cas où, si le problème reste mal posé, il n’a pas de solution.

Voici quelques exemples où une approche plus globale est nécessaire :

  • Améliorer la performance d’une fonction critique complexe : certaines
    fonctionnalités sont difficiles à mettre en œuvre et la tenue des exigences de performances peut être structurellement délicate, par la complexité des traitements, la multiplicité des applications à faire collaborer ou les contraintes de temps pour traiter les volumes. Quelques exemples :

    • Assurer une vision « temps réel » des stocks pour une entreprise
      de distribution multi-canal avec des stocks distribués (fournisseurs, entrepôts, magasins, partenaires logistiques).
    • Assurer les pics de transactions de sites internets pendant des périodes de
      promotion ou des ventes flash, en garantissant la disponibilité
      des stocks.
    • Assurer un calcul d’optimisation logistique ou d’approvisionnement dans un temps limité pour tenir les délais et contraintes des partenaires
      logistiques.
  • Dimensionner une infrastructure pour une cible de déploiement : dans le cadre
    du déploiement d’une solution à l’échelle d’un grand groupe ou d’une montée en charge associée à une évolution forte d’une activité métier, il est souvent nécessaire d’anticiper la capacité de la solution à prendre en charge la montée en charge
    et d’avoir un « coup d’avance ». L’enjeu est de garantir le niveau de service et la capacité à aligner les infrastructures requises, sans « sur-investir » ni mettre en péril
    l’activité métier.
  • Améliorer les performances d’une solution applicative globalement médiocre :
    certaines applications issues de développements lourds et longs sont mises en service sous une forte pression de délais, au détriment d’un temps de qualification et d’optimisation suffisant. En conséquence, les problèmes de performances surgissent au fil du déploiement, avec l’augmentation de l’activité et l’accroissement
    du volume de données d’historique. Traités trop tardivement ces problèmes peuvent bloquer le déploiement, voire créer des incidents opérationnels graves en nuisant à des processus métier critiques pour l’entreprise.
  • Identifier et traiter une contention de ressources qui impacte toutes ou plusieurs
    fonctions : certains problèmes de performances n’ont pas de cause manifeste aisée à cerner. Les contentions peuvent être liées à l’architecture de la solution et à des contentions indirectes ou subtiles entre différentes ressources.
  • Réguler et absorber un pic d’activité : le dimensionnement d’une
    infrastructure pour supporter l’intégralité d’un pic de charge est souvent trop coûteux, surtout s’il n’y a pas d’enjeux incontournables métier à tenir un délai de traitement strict. La mise en place de mécanisme de délestage est pour autant souvent subtile à mettre en place, et en particulier doit favoriser les
    processus ou clients/usagers les plus critiques du service (favoriser les transactions d’achat par rapport aux transactions d’information par exemple). Cette régulation demande une coordination très forte entre vision fonctionnelle (des besoins et
    priorités) et vision technique (des contraintes de ressources).
  • Maîtriser la durée d’un plan batch : garantir qu’un plan batch de nuit ne
    dépassera pas la fenêtre allouée est sans doute l’exemple le plus complexe des problèmes de performances. Beaucoup de facteurs influencent cette performance : la complexité et la structure des traitements, leur capacité ou non à être parallélisés (eux mêmes ou entre eux), les dépendances fonctionnelles qui en
    contraignent l’ordonnancement, les contraintes induites par d’autres applications ou partenaires externes, les grands volumes à traiter, la fluctuation de l’activité au cours du temps, etc.

Quels sont les principaux facteurs de complexité ?

Il est probablement impossible de dresser la liste des facteurs qui peuvent influer sur la complexité des performances d’un SI ou d’une application, mais les suivants sont certainement les principaux :

  • La complexité des solutions et technologies : le premier facteur est clairement celui de la complexité des solutions et technologies. La fragmentation des tiers, l’interdépendance des applications, la complexité des technologies sous-jacentes, la rapidité de leur évolution et de leur obsolescence, la multiplication des progiciels, l’introduction de services en mode SaaS, la virtualisation des ressources… Tous ces éléments rendent la compréhension des problèmes de performance plus délicate. Cette complexité est un fait qui ne changera pas et risque au contraire de continuer à s’accélérer.
  • La multiplication et la dispersion des expertises : cette complexité s’accompagne d’une fragmentation des expertises, tant sur les solutions fonctionnelles, applicatives que techniques. Dans des DSI où ces mêmes experts sont souvent déjà fortement sollicités, il est difficile de les faire travailler efficacement ensemble.
  • Le manque de points de mesures : on pense trop rarement dans ces solutions complexes à les doter de moyens de mesures efficaces (au delà des fondamentaux du socle d’infrastructure de base) permettant d’en comprendre finement le comportement et les dysfonctionnements éventuels.
  • L’absence de repères : cette complexité et ces multiples expertises font perdre les repères sur ce qui est « normal » versus ce qui ne l’est pas. Dans un contexte où le plus souvent, les technologies « masquent » une partie de la complexité, il n’est plus très facile pour un administrateur SAN d’identifier le comportement anormal en IO d’une application, pour un administrateur de base de données d’identifier des requêtes en anomalie ou une mauvaise conception des données, pour un développeur de comprendre les conséquences d’un de ses choix d’architecture logicielle, etc.
  • Les effets d’échelle : le comportement des technologies n’est pas similaire à toutes les échelles, une base de données qui traite un volume de données de quelque Go de données utiles, ne se comporte pas comme une base qui en traite des To. Une application Java pour 50 utilisateurs internes ne se comporte pas comme un site
    internet soumis à des pics d’activité de milliers d’utilisateurs par nature incontrôlables. Pour autant, les technologies, les experts et les développeurs sont souvent les mêmes.
  • La progressivité de la dégradation : les problèmes de performance sont rarement détectés « au bon moment » et apparaissent souvent de manière progressive ou à l’occasion de périodes exceptionnelles où la solution est sollicitée de manière anormale. Cet enlisement progressif dans les sables mouvants de la dégradation des performances endort les acteurs et lorsque le problème se révèle vraiment, il peut être trop tard pour agir…
  • La difficulté d’anticipation et d’extrapolation : il est structurellement difficile de prévoir le comportement d’un système complexe. C’est d’ailleurs un des facteurs de caractérisation d’un système complexe : son comportement ne peut plus se prévoir
    simplement par celui de ses parties.
  • La négociation des solutions : les problèmes de performance réellement complexes s’accordent rarement d’une solution technico/technique « locale » et nécessitent plutôt un compromis entre contraintes technologiques, complexité
    et délai de développement et besoin métier. Cette « négociation » est rarement perçue comme telle par tous les acteurs mais donne souvent au contraire lieu à des affrontements stériles entre études et production, ou DSI et utilisateurs.

Trois points de vue indissociables…

La notion de performance n’a pas de sens dans l’absolu. Il n’est pas pertinent de parler d’une application ou d’un SI performant ou non performant sans mettre en relation trois axes majeurs qui caractérisent vraiment et pleinement la performance. Ces trois axes principaux sont :

  • le travail à effectuer, où en termes informatiques le volume et la complexité des traitements à effectuer sur les informations. Autrement dit : quelle complexité intrinsèque de traitement, indépendamment de l’implémentation qui peut en être faite. Ce travail à effectuer est à mesurer sur plusieurs plans :
    • le volume des données effectivement à traiter, en discernant ce qui doit lu, mis à jour, créé ou supprimé par le traitement,la complexité algorithmique du traitement en termes d’accès aux données, de calculs et de mise à jour de données.
    • le modèle de charge du travail qui définit le profil de la charge : est-il
      étalé ou au contraire astreint à des pics ou périodes particulières ?
  • le temps imparti pour effectuer ce travail : cette dimension temps de
    traitement est déterminante pour caractériser la performance. Ce temps de travail peut selon les cas se mesurer en millisecondes (pour la proposition de mots clés dans un moteur de recherche au fil des saisies), en secondes (pour les temps d’attente d’un utilisateur dans le cadre d’une transaction interactive), en minutes (pour l’attente d’un traitement de restitution) ou en heures (pour des traitements lourds de type batch). La relation au temps est
    éminemment subjective et doit être autant que possible mise en perspective des enjeux opérationnels et du coût associé au temps pour le métier. La mesure du temps pour une solution d’enchère en ligne n’est pas la même que pour un traitement de facturation mensuel.
  • les ressources utilisées pour effectuer ce travail : il s’agit là d’identifier toutes les ressources employées. Les plus évidentes sont les capacités de traitement (secondes CPU) du ou des serveurs assurant le traitement ou le volume des données
    stockées sur disque. Mais il y a d’autres ressources employées qui sont à prendre en compte : comme la mémoire, le nombre et le volume des entrées / sorties (lié en partie à la mémoire), le nombre et le volume d’échanges réseau, etc.

La difficulté de ces trois points de vue est qu’il ne sont pas maîtrisés par les mêmes
acteurs de l’entreprise, ni en termes de causes réelles, ni en termes de conséquences. Et à l’évidence, ils s’opposent. On comprend bien qu’il est plus difficile de traiter vite un travail
plus difficile ou plus volumineux, ou que traiter plus vite est susceptible de consommer plus de ressources. Tant que ces points de vue peuvent être conciliés, il n’y a pas de soucis particuliers : par exemple si les utilisateurs acceptent le « surcoût » de davantage de ressources ou l’impact de temps de traitements allongés. En revanche, si ce n’est pas le cas, il faut arbitrer ces trois points de vue et trouver les meilleurs compromis.

Conclusion

Ce premier article pose les bases de la problématique de la performance des SI. Dans un prochain article, seront abordés le coût de la gestion des performances, les modèles permettant de d’appréhender la performance et la démarche générale proposée par enioka pour gérer la performance des SI.

Représenter la complexité ou complexifier la représentation ?

Une représentation sous forme de graphique est parfois la meilleure façon de représenter la complexité d’un système d’information ou d’une application.

Par exemple, à l’échelle d’une application, un diagramme de classe est souvent plus clair qu’une grande description écrite. En effet, le graphique symbolisant des classes par des boites et des relations par des flèches est on ne peut plus adapté.

À l’échelle du SI, les représentations d’architecture normalisées sont moins convaincantes. Mais au delà de ce manque de formalisme dans les représentations, c’est surtout la réalisation et la maintenance de ces représentations qui sont coûteuses et fastidueuses. Les outils sont souvent peu productifs, qu’ils s’agissent d’outils bureautiques ou d’outils de modélisation. Si les données à représenter existent déjà sous une forme structurée, il est possible de réaliser une large partie de ces représentations avec une certaine forme d’automatisation, ce qui pourtant reste très peu présent dans les outils courants.

L’objectif de cet article est de proposer une approche simple pour automatiser la représentation graphique de données structurées. Cette approche a été validée par une première implémentation.

Les types de problèmes à traiter

La première question à se poser porte sur le sens que donne une
représentation. En effet, une position relative, un alignement, ou encore un
style de flèches ou une couleur peuvent avoir une sémantique particulière dans
le graphique : des boites de la même forme sont du même type, un alignement de
plusieurs étapes représente un flux, etc.

De plus, selon le type de graphique, un même élément peut avoir plusieurs
types de représentations ou encore plusieurs dispositions différentes. Dans
notre exemple du diagramme de classe, la représentation de la classe est faite
sous forme de boite rectangulaire contenant les attributs et les méthodes, alors
que dans le cas d’un diagramme de séquence, cette même classe sera au sommet
d’une ligne vertical depuis et vers laquelle les méthodes appelées seront
reliées.

Dans l’optique d’une représentation graphique, il y a donc plusieurs aspects
que nous allons considérer : les styles, le placement et enfin le routage. Il
est donc primordial d’avoir un paramétrage commun qui permette à la fois de
définir tous ces aspects mais aussi de sélectionner les éléments sur lesquels ce
paramétrage doit s’appliquer. L’approche retenue sera un paramètrage déclaratif
sous forme de règles. En effet celui-ci permet de de pouvoir facilement se
rattacher à un type d’objets, à un attribut, etc., tout en donnant une syntaxe
claire.

Style

Tout d’abord, le style des éléments pourra être personnalisé. Couleur, forme,
transparence, etc. pourront ainsi être renseignés dans les règles. Mais le point
clé est que ces styles peuvent avoir une signification dans le graphique : des
éléments d’une couleur de plus en plus foncé en fonction du nombre de leur
liens, une flèche en pointillés pour des liens d’une certain nature par
exemple. Le style est donc déterminé par des attributs qui caractérisent un
objet, son type (application, classe, ligne de vie d’un objet) et d’autres
attributs qui le définissent, comme par exemple la distinction synchrone,
asynchrone pour les fleches dans un diagramme de séquence.

De plus, ces aspects graphiques peuvent avoir eux aussi une incidence sur le
placement des éléments. Par exemple, on peut vouloir contraindre un objet à être
d’une certaine taille ou forme, et alors les autres éléments autour de celui-ci
devront prendre en considération cet aspect de style.

Placement

De la même façon qu’un style peut avoir une signification, un placement aussi
peut porter une sémantique particulière. Le cas le plus parlant est sans doute
celui de l’arbre, dans lequel les éléments d’un même niveau hiérarchique seront
sur un même niveau visuel. De même, pour reprendre l’exemple du diagramme de
classe, on peut se placer dans une logique où les attributs sont traités de la
même manière que les objets. Alors le nom de la classe doit être au dessus
dans une case séparée, suivie de deux autres cases pour respectivement les
attributs et les méthodes, chacune sous forme de liste.

Ces placements peuvent correspondre à une norme ou à une simple
standardisation adoptée pour un type de graphique. Le placement est donc porteur
de sens et à ce titre constitue une contrainte à satisfaire. Cela peut-être un
alignement, un positionnement relatif, un chevauchement ou encore un groupement
logique. Ces groupements logiques sont par exemple le plus souvent représentés
par une inclusion visuelle d’un ou plusieurs éléments dans un autre. Alors
l’élément englobant devra prendre en compte les caractéristiques ( taille, marges) de ses éléments fils pour sa propre
disposition.

Pour chaque regroupement d’objets, des dispositions spécifiques pourront être
adoptées. Les trois dispositions de base qui ont été implémentées sont :

  • en grille (celle-ci permettant également de réaliser une ligne
    horizontale ou verticale selon le nombre de lignes et de colonnes) ;
  • en cercles, avec des éléments fils sur un cercle centré sur le père ;
  • en arbre.

Au delà de ces contraintes de placement, une optimisation du placement est
souvent bénéfique. En effet, même sous une ou plusieurs contraintes, un certain
degré de liberté peut perdurer pour les objets, et alors un algorithme peut être
utilisé pour optimiser le positionnement. C’est notamment cette phase qui permet de
rendre la représentation plus visuelle et naturelle en éloignant les blocs qui
ne sont pas reliés entre-eux, et en rapprochant ceux qui sont reliés comme s’ils
étaient joints par des ressorts. Cette optimisation peut être atteinte avec un
algorithme de type

Force-directed
.

Routage

Même si les entités supportent souvent la majeure partie des règles de
positionnement, les relations sont toutefois aussi à prendre en compte. Et
de la même manière qu’on parle de disposition pour les éléments, on parle de
routage pour un lien. Ainsi plusieurs aspects sont importants à considérer :

  • le ou les libellés du lien (par exemple un libellé au centre du trait et des libellés aux extrémités) ;
  • le choix des points d’ancrage en fonction du sens de la relation, du placement relatif des objets, du nombre de relations qu’ont les objets et de la sémantique qui est donnée aux différents ports ;
  • et pour finir le routage en lui-même, qui est composé de deux choses : la
    stratégie, qui peut consister à minimiser la longueur, le nombre
    d’intersections, etc., et le type de ligne, comme une courbe de Bézier ou des
    liens orthogonaux.

Cas d’usage

Le cas le plus simple à envisager est l’inclusion d’un élément dans un autre
c’est le cas d’une boite qui en contiendrait plusieurs autres, par exemple
pour affiché les traitements exécutés par une application à l’intérieur de
celle-ci. Cette boite père devrait de par sa nature avoir une taille qui
s’adapte à la taille de ses fils et à leur disposition. Dans la même idée,
l’algorithme doit pouvoir être appliqué tout en respectant les contraintes,
comme l’illustre la figure ci-dessous.

Blog_graphslide17

Mais cela devient encore plus délicat quand ces contraintes se composent. Un
exemple de cette composition de contraintes est illustré ci-dessous à gauche.
Dans celui-ci, on contraint les rectangles arrondis à être alignés
verticalement, et les formes bleues à être alignées horizontalement. Dans cette
configuration un rectangle arrondi bleu doit se trouver au croisement de ces
deux regroupements, si bien que les deux systèmes de contraintes
(un pour les rectangles, l’autre pour les formes bleues), se
retrouvent liés. Ainsi, le premier système s’articule initialement autour de
deux inconnus, de même pour le second, mais la composition des deux n’aura
globalement que deux inconnus. En effet, la composition induit une relation
entre les inconnus du premier système et ceux du second.

Blog_graphslide19

Le dernier cas, illustré dans la figure ci-dessus à droite, est encore plus
complexe. Dans ce cas on exige un alignement vertical des formes bleues, et les
rectangles arrondis sont eux disposés en grille. Alors on remarque que
l’organisation interne de la grille est dépendante d’une contrainte externe.

Proposition de résolution de ce problème

Le modèle général

Le modèle général envisagé fonctionne par composition de règles, de telle
manière que chaque élément peut être contraint par rapport à n’importe quel
autre élément.

Le déroulement se fait en trois étapes :

  • assembler les contraintes : déclarer pour chaque élément les relations
    qu’il dispose par rapport aux autres ;
  • résoudre le système de contraintes pour identifier les degrés de liberté
    restant à optimiser ;
  • appliquer l’algorithme de résolution par rapport aux degrés de liberté
    précédemment identifié.

Le modèle adopté en première approche

Malheureusement le précédent modèle, bien que non restrictif, s’avère d’une
complexité importante. Pour faire une première implémentation, nous nous sommes
donc restreint. En effet, un
premier modèle de contraintes hiérarchiques permet de réaliser une grande
partie des besoins, et on ne veut pas complexifier les cas simples au nom de
quelques cas compliqués, les 20% de cas restants à supporter pouvant induire 80%
de complexité supplémentaires…

Hiérarchique, c’est à dire qu’un élément n’est contraint que par rapport à
son père. Ainsi, les éléments sont tous disposés selon un arbre. Les avantages
sont multiples : déjà, le parcours des éléments est grandement simplifié, et
ensuite il n’y aura plus besoin de résoudre les contraintes dans le sens où il
ne pourra plus y avoir plusieurs contraintes sur un même élément. À l’inverse,
ce modèle induit des limitations, notamment dues au fait de se restreindre à une
architecture en arbre. Un élément ne pouvant être contraint que par rapport à un
seul autre élément, on empêche certains cas d’usage tels que la structure en
croix précédemment illustrée.

Le moteur de mise en forme fonctionne donc de façon récursive en parcourant
l’arbre des éléments. À chaque niveau, le moteur demande donc à ses enfants de
se mettre en forme, et chacun d’eux lui renvoie une boite rectangulaire dont les
dimensions sont calculées pour contenir l’enfant et ses petits enfants dans une
configuration donnée.

L’algorithme du moteur de mise en forme comporte 2 étapes principales :

  • une première passe qui depuis la racine du graphique entraîne par
    récursion la mise en forme des enfants. Cette mise en forme consiste à
    positionner les éléments fils relativement au père et à définir la taille
    du container nécessaire pour contenir tous les fils. Ce container n’est pas
    forcément représenté graphiquement, ce sont uniquement ses dimensions qui sont
    utilisées pour ensuite mettre en forme les éléments du niveau supérieur.
  • Une seconde passe, à nouveau récursive depuis la racine, pour calculer à
    partir des positions relatives des éléments leur position absolue sur le
    graphique. Chaque élément, dont la position a été calculée relativement à son
    père, peut simplement calculer sa propre position puis continuer la récursion en
    demandant la même opération à ses fils.

La descente dans l’arbre peut suivre deux types de relations : des relations portées par des données (liens entre objets) qui se retrouvent directement entre les objets graphiques et des relations d’inclusion qui sont matérialisée par des objets que nous avons appelés « ports d’inclusion ». Ce
sont des espaces de forme rectangulaire qui vont pouvoir réceptionner des
éléments selon une configuration établie. Ces ports sont vus comme des enfants
de l’élément, et à ce titre ils s’insèrent de façon identique dans la récursion
et leur fonction de mise en forme renvoie elle aussi une boite aux dimensions
calculées par son contenu.

Cette homogénéité de la méthode permet toute combinaison de mise en forme :
on peut insérer une grille dans un arbre, lui-même dans une autre grille,
etc.

Implémentation

Une implémentation de cette approche a été réalisée. Elle s’appuie sur
un moteur de règles et une implémentation en Javascript, HTML5 et Canvas.

Voici quelques exemples de représentations obtenues automatiquement à partir
d’un jeu de règles et de données d’entrée structurées. Le modèle de données utilisé ici est le modèle enioka des flux entre applications. En particulier, les objets représentés sont des flux contenant des étapes qui ont des stocks de données en entrée et en sortie, ces stocks appartenant à des applications.

Blog_graphenioka

Voici ci-dessus un exemple de ce qui a été obtenu à l’issu de la première
implémentation. Il s’agit d’un diagramme de flux représentant les
différentes étapes du flux alignées, ainsi que les applications en dessous,
en grille de même hauteur de ligne, classées (et non optimisées pour le moment)
pour minimiser le croisement des liens, et contenant des stocks de données,
dont les liens avec les étapes du flux représentent des accès en lecture et
en écriture selon le sens de la flêche. Tout ceci est généré de manière
automatique depuis un ensemble de données structurées.

Conclusion

Il s’agit d’une première étape dans l’automatisation des représentations
automatiques de modèles. Tous les modèles ne se prêtent pas à ce type de
représentation automatisée par des règles. Une évolution pourrait être de
combiner génération automatique et disposition manuelle. Le moteur étant en
charge de générer les formes, les styles, le placement initial et d’assister
les modifications manuelles pour vérifier que certaines règles sont toujours
respectées.

Problématiques des interfaces entre applications

Ce blog est destiné à traiter de sujets de modélisation, et plus particulièrement de la modélisation de systèmes d’information complexes. Nous commencerons par traiter d’un sujet au coeur de la décomposition de systèmes informatiques complexes : les interfaces.

La première définition que nous pouvons donner est la suivante « Limite commune à deux systèmes, permettant des échanges entre ceux-ci » (Larousse). Cette définition précise qu’il s’agit donc d’éléments communs à deux applications qui permettent des échanges, dans notre cas, principalement d’informations ou de demande d’exécution d’ordre.

Nous limiterons ce billet aux interfaces d’échanges d’information, en opposition aux interfaces d’interrogation (par exemple via des web-services) et aux diffusion large de type publish-and-subscribe.

Les éléments constitutifs d’une interface

Au delà de la définition théorique d’une interface entre deux applications, il nous faut définir sa décomposition en éléments identifiables qui porteront les exigences, et qui auront des représentations physiques tout au long de la vie de l’interface : spécifications, programmes de traitements, fichiers de données.

Un premier niveau d’analyse logique d’une interface dans le contexte d’un SI se focalise principalement sur les données qui y transitent, sur ses dépendances, en terme de données de référentiel ou d’autres données transitant dans des interfaces, ainsi que sur les éléments déclencheurs : critère horaire, déclenchement à la demande d’un utilisateur ou sur l’apparition d’un évènement interne à l’application ou externe.

Au niveau technique, une interface peut se décomposer suivant les éléments suivants :

  • Un ou plusieurs traitements d’extraction qui permettent de transformer les données d’un format propre à l’application émettrice dans un format intelligible
  • Un ou plusieurs mécanismes de transport. Ceux-ci ne modifient pas les données mais sont chargés de déplacer physiquement les données d’une machine (serveur, poste utilisateur …) à un autre.
  • Un ou plusieurs traitements intermédiaire qui sont chargés de transformer le format émit par l’application source dans un format compatible avec les traitements de chargement de l’application destinataire.
  • Des données transportées d’une application à une autre, matérialisées par un format (schéma XML, description de champs pour un fichier plat …)
  • Un ou plusieurs traitements de chargement qui ont pour rôle de charger les données émises afin que les traitements propres à la logique de l’application destinataire puisse les utiliser.

Cette décomposition est évidemment maximaliste et vise à décrire les cas les plus complexes. Nous verrons plus tard les intérêts et les problèmes posés par la mise en place de pivots, mais la mise en place de traitements intermédiaire n’a de sens que dans un tel cas.

Les données de référentiel

Les données de référentiel sont les données auxquels font référence les objets transportés dans une interface. Elles ont en général une durée de vie plus longue et une fréquence de mise à jour plus faible que les données de transaction.

D’un certain point de vue, les données de référentiel sont des données comme les autres et font l’objet d’interface entre les applications maîtresses de leurs mises à jour et les applications qui les utilisent. Cependant, ces données ont un rôle important puisque c’est sur celles-ci que reposent les données de transaction qui portent les informations opérationnelles : factures, écritures comptables, commande d’achat … Cette importance se traduit dans une question qui revient souvent lors de la conception d’interfaces dans un système d’information : doit-on faire transiter les données de référentiel avec les données de transaction ou faire des interfaces séparées ?

Les données de référentiel utilisées par une interface doivent en général faire l’objet d’interfaces à part pour plusieurs raisons :

  • Le cycle de vie des interfaces de référentiel et de transaction n’est pas le même
  • Les interfaces de référentiel sont en général de bons candidats à la réutilisation, surcharger ces interfaces avec des données spécifiques à certaines applications peut nuire à cette réutilisation en augmentant la complexité de l’interface
  • La séparation de ces flux facilite une mise en oeuvre ultérieure d’une concentration des données référentielles dans une application dédiée à leur gestion.

Cependant, certaines situations rendent la séparation en différentes interfaces trop complexe ou coûteuse pour l’intérêt que cela représente :

  • Des interfaces particulièrement simples : le format et les traitements utilisés sont simples et stables. Par exemple, créer une interface supplémentaire uniquement pour transférer les libellés d’objets n’est pas nécessairement judicieux.
  • Un référentiel très lourd dont peu d’objets sont utilisés et qui ne sont pas identifiables à priori.
  • Des besoins de fraîcheur de données très importants : les données de référentiel sont très souvent modifiées et que l’utilisation des données les plus fraîches est indispensable (problèmes en cas de désynchronisation des applications)
  • Un référentiel pauvre ne gérant pas les données à date pour permettre leur accrochage avec les données de transaction.

Ces cas peuvent amener à charger des données de référentiel dans des interfaces initialement prévues pour transférer des transactions. Chaque référence faite par celles-ci est alors remplacées dans le format d’extraction par les informations utiles à l’application cible.

La réutilisation des interfaces : les formats pivots

Lors qu’il est question d’interfaces dans un SI, le terme de format pivot est une question centrale. Le principe de fonctionnement est le suivant : pour chaque interface on fait l’effort d’extraire les données dans un format pivot ou de les y transformer et ensuite de le re-transformer dans le format de chargement dans l’application cible ou de l’y charger directement.

La thèse est que la réutilisation permise par ce mode de fonctionnement est supérieure au surcout engendré par la complexité supplémentaire de chaque interface.

Ce mode de fonctionnement ne peut être indépendant des frontières posées entre les applications : les gains engendrés par une réutilisation sont plus importants si une partie des transformations intermédiaires peut être partagée entre les différentes applications.

Le principal piège tient au fait que la description d’un format pivot ne fait pas tout. En effet, en plus de son format, une interface est décrite par ses dépendances externes (référentiels associées, codifications), son mode de fonctionnement (par exemple transfert de toutes les données ou uniquement des données modifiées) et ses conditions de déclenchement. S’il y a besoin de faire la combinaison de toutes ces possibilités, l’interface pensée comme générique devient vite un cas particulier pour chaque application partenaire.

Dans certains cas, la définition et l’usage d’interfaces standards d’intégration (définies par un format et les caractéristiques mentionnées précédemment) des applications présentent des avantages en terme d’efficacité de travail. Par exemple la diffusion de référentiels et les interfaces proposées par une application proposant des services centraux utilisés par différentes applications (par exemple une application comptable qui recueille l’ensemble de les factures afin de les comptabiliser) sont de bons candidats. La mise en place de ces interfaces standards autour d’applications structurantes dans le SI permet ensuite de cadrer l’intégration de nouvelles applications en offrant un certain nombre de points d’entrée partagés.

Nous ne faisons ici qu’effleurer le sujet des formats pivots, dont les intérêts et inconvénients sont souvent mal compris. Nous l’approfondirons donc dans un prochain billet.

La réutilisation des interfaces : les composants techniques

Dans une même optique que le partage des formats, il est envisageable de partager entre les différentes interfaces et différentes applications un certain nombre de composants techniques.

Les éléments les plus évidents à partager sont les middleware : ils sont par définition agnostiques des données qu’ils manipulent et sont souvent structurés afin de pouvoir gérer des contextes et des projets différents. Il s’agit d’outils de transfert de données (transfert de fichier, middleware orienté message …), de traitement (ETL, EAI/ESB, EDI …) ou de stockage des données (Bases de données …) ou d’outils utilisés par les applications en dehors du strict domaine des interfaces comme un ordonnanceur.

En poussant la réflexion, on se rend compte qu’il est possible de partager à l’intérieur de ces outils des éléments : code source, paramétrage … Ceci permet de constituer un framework autour duquel est capitalisé le travail réalisé sur les différentes interfaces. Dans le cas d’un middleware de traitement de données, on peut donner comme exemple des formats de fichier ou des traitements génériques (changement de codification des données, de format techniques ou d’encodage des fichier).

Enfin, certains services annexes sont utiles pour la plupart des applications mais relèvent presque d’une logique applicative, on peut alors imaginer le développement d’un tel outil partagé. Par exemple, la gestion des rejets dans une interface demande des écrans permettant aux utilisateurs de voir des données, éventuellement les corriger voire de relancer l’interface. L’assemblage des différents services partagés peuvent former un véritable service d’intégration, mais ceci sera le sujet d’une prochaine note sur ce blog.

Cette partie technique est aujourd’hui plus mure et permet ainsi d’espérer des gains de productivité plus importants que la mise en place d’une approche fondée sur des formats pivots.

Les frontières de responsabilités entre les applications

La création d’interfaces entre applications demande de définir la propriété de certaines données, ce qui nécessite de délimiter les périmètres de responsabilité des différentes applications. Il est donc important de faire ces attributions avant de mettre en place les interfaces.

Nous partons ici du principe qu’une interface entre deux applications nécessite forcément des modifications sur les informations transportées, que ce soit des changements sur les données elles-même (transcodification …) ou des traitements techniques (changement d’encodage des caractères, de formats de dates …). En effet, la question de l’adaptation ne se pose pas sinon.

La solution par défaut lors de la mise en place d’une nouvelle application est souvent de dire que toutes les adaptations seront réalisées par celle-ci. Cette position vient du fait que la nouvelle application est en cours de projet et que, par conséquent, elle a un budget alloué et des équipes présentes et qu’il est plus simple de gérer les modifications localisées à un seul projet.

Il convient ainsi de prendre plusieurs facteurs en considération :

  • « La norme » : quelle est l’application qui a le comportement le plus spécifique ? Car si une des applications doit s’adapter à l’autre c’est alors celle-ci.
  • Cycle de vie : si une application est en fin de vie, c’est à elle de s’adapter : ces spécificités disparaîtront alors avec son décomissionnement au lieu de perdurer et de constituer un standard de fait au sein de l’entreprise.
  • Capacité d’adaptation : si une application a des contraintes qui l’empêchent de s’adapter (pauvreté des mécanismes d’intégration disponibles, application hébergée en ASP, indisponibilité des équipes, etc.), le travail devra être fait par l’autre application concernée
  • Les besoins de données externes : si les modifications réalisées ont besoin de données appartenant à une des applications alors les adaptations doivent y être faites.
  • Présence de d’interfaces standard (formalisés ou de fait) : si l’interface qui est mise en place correspond à une interface déjà existante avec une autre application alors c’est la nouvelle application qui doit s’adapter.

Les questions et difficultés que nous avons mentionnées sont également présentes dans l’intégration inter-système d’information (client-fournisseur ou SI partenaires) mais sont rendues plus aiguës par la distance introduite entre les équipes et les différences de conception des interfaces (vocabulaire, principes de partage …).

Conclusion

Cette note de sensibilisation nous a permis d’aborder un certain nombre de problématiques rencontrées dans la mise en place d’interfaces entre les différentes applications d’un système d’information classique. Elle laisse volontairement de côté les aspects de techniques et d’urbanisme qui sont des sujets à part entière et qui mériteront des notes de blog dédiées.

Les différents objets mentionnés ainsi que leurs propriétés constituent une première présentation d’un modèle logique des interfaces entre applications.

Gérer la complexité des SI

Une complexité croissante

La complexité est au cœur des systèmes d’information (SI) d’aujourd’hui. On ne peut que constater que les grandes organisations ont à gérer des SI de plus en plus vastes et hétérogènes à tout point de vue : des centaines d’applications, des milliers de serveurs, des centaines de milliers d’échanges et de transactions, des utilisateurs de plus en plus nombreux et répartis sur la planète, qu’ils soient collaborateurs, partenaires, clients ou fournisseurs. La pression des évolutions imposées aux entreprises, l’intégration toujours plus forte des processus intra et inter entreprises et la poussée de la dématérialisation dans tous les domaines de l’économie ne font qu’accélérer ce phénomène et confèrent un rôle de plus en plus critique au SI. L’accroissement inexorable du périmètre du SI s’accompagne mécaniquement d’une concentration des risques et des enjeux portés.

Les effets néfastes de cette complexité sont multiples et la cause profonde de beaucoup des difficultés dans la gestion du SI sur de nombreux plans comme la gouvernance de l’urbanisme du SI, la maîtrise de l’intégration des grands projets d’évolution, la maîtrise des coûts informatiques et de leur refacturation aux clients métier, la gestion des performances et de la disponibilité, la gestion des risques techniques, la sécurité, etc. La complexité rend en effet très délicat le traitement de ces problématiques transverses.

Tous les SI importants font aujourd’hui face à des difficultés croissantes pour maîtriser les coûts et les risques tout en apportant satisfaction aux besoins métier dans des délais raisonnables. Il n’est pas rare de constater que de petites structures agiles réagissent de manière plus adaptée, plus rapide et finalement plus efficace que de grandes structures dotées de plus de moyens. La complexité s’avère souvent un obstacle aux fameuses économies d’échelle promises par tous les projets de mutualisation, centralisation, ou externalisation des moyens informatiques.

Caractérisation de la complexité des SI

Avant tout, il faut mieux définir ce qui caractérise la complexité d’un système en général et la complexité d’un SI en particulier. Bien qu’il n’en existe pas de définition objective et formelle qui fasse consensus, notamment dans le domaine des SI, plusieurs éléments clés caractérisent un système complexe :

  • en premier lieu, la taille du système rapportée à ce qui finalement est la métrique la plus naturelle : le temps pris par un humain à le décrire, le spécifier ou le construire. Un « petit » système ne peut pas être complexe. Pour un SI, cette taille se mesure en nombre d’applications, de tables de données, de flux, etc.
  • l’impossibilité (ou à tout le moins la très grande difficulté) à subdiviser ce système en sous systèmes plus petits sans introduire un nombre de liens entre ces parties qui ne croisse plus vite que leur nombre (de manière quadratique typiquement). Pour un SI c’est la difficulté rencontrée à isoler des sous ensembles pertinents du SI pour le découper en éléments plus simples : processus, domaines, applications, infrastructures, etc.
  • le couplage « in-démêlable » de toute partie du système avec les autres et l’action indirecte et mal maîtrisée qu’elle peut avoir sur d’autres parties avec lesquelles elle est connectée même indirectement. Dans un SI, ce couplage est porté par les interfaces entre applications, par les moyens mutualisés d’infrastructure, par les données partagées de manière transverse, etc. En dépit des promesses de la SOA (Service Oriented Architecture), la gestion des évolutions relève souvent du casse tête avec des coûts et des délais qui ne sont plus en proportion avec la valeur des changements apportés.
  • l’hétérogénéité forte, voire l’incohérence des parties entre elles qui rend impossible l’application de règles ou d’opérations communes à toutes les parties. Au niveau d’un SI cette hétérogénéité se constate sur tous les plans : organisation et processus métier, données partagées, architectures applicatives, langages de développement,
    infrastructures, etc… Cette hétérogénéité se paye à toute action globale sur le SI : les économies d’échelle de mutualisation/industrialisation se transforment alors en surcoûts par rapport à une action strictement locale et spécifique sur chaque élément.
  • l’impossibilité de prévoir le comportement ou de tester le système dans son ensemble par rapport à l’ensemble de ces cas potentiels de fonctionnement et encore moins de dysfonctionnement. Cette impossibilité est la conséquence directe des éléments précédents qui vient de l’explosion combinatoire de ses états possibles. Au niveau SI, cette incapacité se traduit par la multiplication des incidents et problèmes (au sens ITIL) et la grande difficulté d’intégration de grands projets.

Les « fausses bonnes idées » pour résoudre la complexité des SI

Il y a quelques mirages récurrents et souvent dangereux sur les moyens de résoudre ces problèmes liés à la complexité des SI. Si ces idées apportent des éléments de réponse, elles sont souvent très dangereuses à considérer comme des solutions « magiques » en tant que telles, car elles sont toutes myopes aux phénomènes systémiques de la complexité et finalement en nient le caractère profondément structurel :

  • Le « top down » comme moyen de pilotage ou de gouvernance unique : à l’image des démarches en V classiques rassurantes qui partent d’un besoin et aboutissent à une solution technique, il y a le rêve de pouvoir appréhender de manière hiérarchisée et descendante un SI dans son ensemble. Ce serait possible si justement le SI n’était pas complexe et se prêtait à une description hiérarchisée, si ce n’est unique, au moins complète et représentative de l’ensemble de la complexité. Il est possible heureusement de gouverner un SI, mais rarement par un seul point de vue, fût il aussi prégnant que celui des coûts, des besoins métier ou des risques.
  • La centralisation, notamment autour d’un outil : un autre moyen de contrôle souvent préconisé est la mise en place d’un outil fédérateur et central qui permettrait de gérer et de piloter l’ensemble. Qu’on parle d’outil de CMDB (inspiration ITIL), d’outil de cartographie ou de solution d’intégration centralisée (EAI, ESB…) par exemple, le biais reste le même : l’idée d’un point fédérateur unique qui réussirait à capturer la complexité et à la gérer. L’expérience est plutôt que pour ce type d’outil, plus son périmètre est large, plus il est délicat à mettre en place et surtout quasi impossible à maintenir. Le fait est que cet élément central, qui
    cherche à capturer un objet d’une très grande complexité, se trouve lui même empêtré dans cette complexité, et à un degré de contraintes supérieur encore, parce que centralisé et donc très fragile. L’effort de sa maintenance s’avère finalement très souvent inférieur aux bénéfices réels qu’il apporte.
  • L’uniformisation comme solution ultime à tous les problèmes de complexité. L’industrie a répondu à la problématique de la gestion des processus complexes par une très forte normalisation et le travail en « séries » très homogènes. Si beaucoup de bénéfices sont à attendre d’approches de normalisation, le SI se trouve confronté à la réalité opérationnelle et humaine d’un SI structuré en strates hétérogènes historiques et technologiques qu’aucune volonté ne peut faire converger complètement à un instant donné. L’exception à la norme résiste au changement par le poids du patrimoine et s’introduit dans les nouveaux projets par le biais des nouvelles technologies, de nouveaux types de besoins ou de solutions progicialisées au socle incompatible avec les choix communs. Les opérations de fusion/acquisition entre sociétés rendent encore plus aléatoires les possibilités d’uniformisation. Enfin, traiter uniformément tous les éléments du SI strictement avec les mêmes normes amène à des solutions, lourdes, coûteuses et pas toujours adaptées aux attentes.
  • La transformation globale du patrimoine vers une cible idéale et enfin
    urbanisée. Toutes les initiatives qui constituent un choc sur le patrimoine et qui ne laissent pas la place à une trajectoire de convergence flexible et potentiellement partielle, sont vouées à l’échec. Pour deux raisons majeures : d’une part, un système complexe réagit de manière très violente et inattendue à une transformation trop rapide ou trop globale, et ce principalement parce que les impacts des changements importants ne peuvent pas réellement être maîtrisés dans un système complexe. D’autre part, la dimension temps est un facteur qui est un frein très direct aux transformations rapides : tout changement profond sur un SI complexe, que ce soit au niveau métier ou technique, prend un temps incompressible lié à son déploiement. Même des transformations relativement innocentes et apparemment simples comme le changement d’infrastructures de stockage ou de stratégie d’hébergement physique sont à mener en étapes progressives et en tout cas par étapes maîtrisées. Et la longueur de la trajectoire rend particulièrement incertaine cette fameuse cible globale initialement pensée comme idéale : la cible bouge finalement plus vite que la trajectoire…

Une décentralisation nécessaire

Ces approches font toutes plus ou moins l’hypothèse que la complexité est le fruit d’une histoire passée qu’il convient de redresser ou de corriger et recherchent une solution pour reprendre un contrôle central de l’ensemble. Le fait est que la complexité résiste à toute approche globale si celle ci n’est pas structurellement décentralisée. Autrement dit, les seules méthodes qui fonctionnent sont celles qui développent des caractéristiques locales au niveau des composantes élémentaires du SI et qui confèrent de manière systémique des caractéristiques intéressantes et vertueuses » à l’ensemble. Les éléments centraux, pour être nécessaires et utiles doivent rester extrêmement simples et robustes aux changements de toute nature.

Mais pour l’essentiel, un système complexe doit être décomposé en sous ensembles les plus découplés possibles entre eux. C’est la force clé attendue d’une approche décentralisée : la résolution des problèmes doit pouvoir être locale à chaque partie du système, et ainsi porter sur des sous ensembles moins complexes. La décentralisation doit minimiser les interactions, les interdépendances et les couplages entre les parties, pour permettre cette action locale, autonome, et adaptée au besoin. La difficulté réside finalement dans la qualité de ce découpage, qui n’est hélas pas naturel et surtout pas homogène selon les différentes facettes du SI. En fait, il n’existe pas un découpage unique. Il existe plutôt plusieurs découpages qui se superposent à la réalité du SI sur ses différents plans, des plans métiers et fonctionnels, aux plans des infrastructures et de l’exploitation.

L’approche enioka

Pour structurer son action et sa réflexion sur les systèmes complexes avec ses clients, enioka fonde son approche sur quatre éléments clés :

  • L’identification et la formalisation de plans ou points de vue du SI : pour percevoir un système complexe, il faut l’observer à travers des projections sur différents plans qui sont des points de vue du SI. Ces « plans de coupe » du SI permettent des analyses simplifiées focalisées sur des objectifs portés par différentes parties de l’organisation de la DSI, un peu à la manière d’une radiographie ou d’un scanner. Ces plans masquent certains aspects de la complexité pour se focaliser sur certains objectifs, comme le coûts, la sécurité, l’urbanisme, les infrastructures, l’exploitation, etc. Chacun de ces points de vue n’a pas besoin de traiter la complexité des autres points. Mais cette segmentation en points de vue se doit d’être cohérente et de ne pas introduire de biais dans les raisonnements.
  • La modélisation du SI : la difficulté rencontrée dans l’analyse et la maîtrise des systèmes complexes vient avant tout d’un manque de modèles formels du SI qui permettent de raisonner efficacement sur le SI par des vues simplifiées adaptées à certains types de questions sur le SI. Le pluriel à modèleS est volontaire, car il n’est pas à notre sens possible ni même intéressant de construire un modèle unique, central et uniforme du SI qui permettrait de répondre à toutes les questions sur la complexité du SI. Les modèles doivent être adaptés pour répondre à des questions concrètes ou comme support à une politique de gouvernance sur les différents plans et points de vue du SI… Ces modèles doivent être faiblement couplés entre eux mais fédérés autour de quelques notions pivot communes comme celles d’application, de flux, de service, etc. Ces modèles doivent en outre être déployés en fonction des objectifs et non de manière uniforme et systématique. Par exemple, on peut très bien avoir deux niveaux de modélisation de l’intégration des applications selon leur complexité et leur criticité : un niveau commun très simple pour le pilotage du patrimoine et un niveau fin réservé aux objets et processus critiques du SI.
  • L’approche service : une forme de modèle très générale et très puissante est la notion de service. Ce principe consiste à identifier des services généraux réutilisables et à en masquer l’implémentation aux clients par des interfaces formelles et abstraites. L’identification des services est une véritable démarche marketing d’analyse du « marché » des besoins et de promotion de solutions partagées (qui s’opposent souvent à l’axe « local » des projets métier).Cette démarche se décline sur les différents plans du SI, qu’il s’agisse de l’urbanisme, du développement ou des infrastructures ou de l’exploitation. De plus, cette vision de service est très utile comme support à la décomposition normalisée d’un SI complexe en éléments simples, et structurellement plus homogènes. Enfin, l’approche service permet à la fois d’unifier sans uniformiser : un même « service » peut être implémenté de différentes manières selon les cas d’usage. enioka s’attache notamment à développer un modèle des services du SI, structuré en différents plans de service, des infrastructures aux services applicatifs et métier.
  • La définition de trajectoires d’évolution : on raisonne trop sur la cible et pas assez
    sur le chemin qui y mène. Très souvent le chemin dicte des contraintes déterminantes sur la cible. Et comme on l’a vu, le chemin étant souvent long pour les projets de transformation significatifs, la cible « désirable » peut évoluer beaucoup au fil du parcours. Une bonne cible est avant tout une cible avec une trajectoire robuste aux événements inattendus, qui fait intelligemment levier sur les évolutions majeures et les grands projets incontournables pour porter les transformations systémiques. Enfin, la trajectoire elle même doit être modélisée
    et suivie pour être réactualisée.

L’ambition d’enioka à travers son activité et plus spécifiquement au travers de ce blog, est de contribuer de manière très concrète au développement de ces différents modèles du SI et d’en décliner l’usage à travers la réponse à des questions très opérationnelles sur les coûts, sur les analyses de risque, sur la maîtrise du niveau de service, sur la maîtrise du patrimoine applicatif et technique, etc. enioka développe en outre un outillage de modélisation permettant de supporter ces différents modèles et de collecter les informations déjà existantes dans le SI, qu’il s’agisse de référentiels du SI ou de sources de métriques adossées à ces référentiels. A travers ce blog, au fil des mois, nous tenterons de partager nos réflexions sur les différents aspects de la complexité autour de thèmes comme : l’industrialisation des processus, les normes et standards techniques, l’intégration des grands projets applicatifs, la gouvernance opérationnelle des flux, l’urbanisation des référentiels de l’entreprise, la maîtrise des coûts récurrents et notamment de licence, etc.