Article
· Jan 8 14m de lecture

Diffusion continue de votre solution InterSystems à l'aide de GitLab - Partie XI : Interopérabilité

Bienvenue dans le prochain chapitre de ma série CI/CD, où nous discutons des approches possibles vers le développement de logiciels avec les technologies InterSystems et GitLab.

Aujourd'hui, parlons d'interopérabilité.

Problème

Lorsque vous avez une production d'interopérabilité active, vous avez deux flux de processus distincts : une production active qui traite les messages et un flux de processus CI/CD qui met à jour le code, la configuration de la production et les paramètres par défaut du système.

De toute évidence, le processus CI/CD affecte l'interopérabilité. Mais il y a des questions :

  • Que se passe-t-il exactement lors d'une mise à jour ?
  • Que devons-nous faire pour minimiser ou éliminer les temps d'arrêt de la production lors d'une mise à jour ?

Terminologie

  • Business Host (BH) - un élément configurable de la production d'interopérabilité : Service métier (BS), Processus métier (BP, BPL) ou Opération métier (BO).
  • Business Host Job (Job) - Tâche InterSystems IRIS qui exécute le code du Business Host et qui est gérée par la production d'interopérabilité.
  • Production : ensemble interconnecté de serveurs d'entreprise (Hôte métier).
  • System Default Settings (Paramètres par défaut du système) (SDS) - valeurs spécifiques à l'environnement dans lequel InterSystems IRIS est installé.
  • Message actif - demande en cours de traitement par une tâche Business Host Job. Une tâche Business Host Job peut avoir un maximum d'un Message actif. Une tâche Business Host Job qui n'a pas de message actif est inactif.

Qu'est-ce qui se passe?

Commençons par le cycle de vie de la production.

Démarrage de la production

Tout d'abord, la production peut être démarrée. Une seule production par espace de noms peut être lancée simultanément, et en général (à moins que vous ne sachiez vraiment ce que vous faites et pourquoi vous le faites), vous ne devrez lancer qu'une seule production par espace de noms, jamais. Il n'est pas recommandé de passer d'un espace de noms à l'autre entre deux ou plusieurs productions différentes. Le démarrage de la production démarre tous les Business Hosts activés définis dans la production. Le fait que certains Business Hosts ne démarrent pas n'affecte pas le démarrage de la production.

Conseils:

  • Démarrez la production à partir du portail de gestion du système ou en appelant : ##class(Ens.Director).StartProduction("ProductionName")
  • Exécutez un code arbitraire au démarrage de la production (avant qu'un Job Business Host ne soit démarré) en implémentant une méthode OnStart.
  • Le démarrage de la production est un événement contrôlable. Vous pouvez toujours voir qui et quand a fait cela dans le journal d'audit.

Mise à Jour de la production

Après le démarrage de la production, l'outil Ens.Director surveille en permanence la production en cours. Il existe deux états de production : état cible, défini dans la classe de production et les paramètres par défaut du système ; et état en cours d'exécution - les tâches en cours d'exécution avec les paramètres appliqués lors de la création des tâches. Si l'état souhaité et l'état actuel sont identiques, tout va bien, mais la production peut (et doit) être mise à jour s'il y a une différence. Habituellement, vous voyez cela sous la forme d'un bouton rouge "Mettre à jour" sur la page Configuration de la production dans le Portail de gestion du système.

La mise à jour de la production signifie une tentative pour que l'état de production actuel corresponde à l'état de production cible.

Lorsque vous exécutez ##class(Ens.Director).UpdateProduction(timeout=10, force=0) pour mettre à jour la production, il effectue les opérations suivantes pour chaque Business Host :

  1. Comparez les réglages actifs aux réglages de production/SDS/classe.
  2. Uniquement si (1) révèle une incohérence, le Business Host est marqué comme étant obsolète et nécessitant une mise à jour.

Après avoir exécuté cette opération pour chaque Business Host, UpdateProduction construit l'ensemble des changements :

  • Business Hosts à arrêter
  • Business Hosts à démarrer
  • Paramètres de production à mettre à jour

Ensuite, il les applique.

De cette manière, la "mise à jour" des paramètres sans rien changer n'entraîne aucune interruption de la production.

Conseils:

  • Mettre à jour la production à partir du portail de gestion du système ou en appelant : ##class(Ens.Director).UpdateProduction(timeout=10, force=0)
  • Le délai de mise à jour par défaut du portail de gestion du système est de 10 secondes. Si vous savez que le traitement de vos messages prend plus de temps, appelez Ens.Director:UpdateProduction avec un délai plus long.
  • Le délai de mise à jour est un paramètre de production, et vous pouvez le modifier pour une valeur plus importante. Ce paramètre s'applique au portail de gestion du système.

Mise à jour du code

UpdateProduction NE MET PAS A JOUR les BHs dont le code est obsolète. C'est un comportement orienté vers la sécurité, mais si vous voulez mettre à jour automatiquement tous les BHs en cours d'exécution lorsque le code sous-jacent change, suivez les étapes suivantes :

First, load and compile like this:

do $system.OBJ.LoadDir(dir, "", .err, 1, .load)
do $system.OBJ.CompileList(load, "curk", .errCompile, .listCompiled)

Maintenant, listCompiled contiendrait tous les éléments qui ont été compilés (utilisez git diffs pour minimiser l'ensemble des éléments importés) à cause du marqueur u. Utilisez cette listCompiled pour obtenir un $lb de toutes les classes qui ont été compilées :

set classList = ""
set class = $o(listCompiled(""))
while class'="" { 
  set classList = classList _ $lb($p(class, ".", 1, *-1))
  set class=$o(listCompiled(class))
}

Et ensuite, calculer une liste de BHs qui nécessitent un redémarrage :

SELECT %DLIST(Name) bhList
FROM Ens_Config.Item 
WHERE 1=1
  AND Enabled = 1
  AND Production = :production
  AND ClassName %INLIST :classList

Enfin, après avoir obtenu bhList, arrêtez et démarrez les hôtes affectés :

for stop = 1, 0 {
  for i=1:1:$ll(bhList) {
    set host = $lg(bhList, i)
    set sc = ##class(Ens.Director).TempStopConfigItem(host, stop, 0)
  }
  set sc = ##class(Ens.Director).UpdateProduction()
}

Arrêt de production

Les productions peuvent être arrêtées, ce qui implique d'envoyer une demande à tous les Jobs Business Host pour qu'ils s'arrêtent (en toute sécurité, une fois qu'ils ont terminé leurs messages actifs, le cas échéant).

Conseils:

  • Arrêtez la production à partir du portail de gestion du système ou en appelant : ##class(Ens.Director).StopProduction(timeout=10, force=0)
  • Le délai d'arrêt par défaut du portail de gestion du système est de 120 secondes. Si vous savez que le traitement de vos messages prend plus de temps que cela, appelez Ens.Director:StopProduction avec un délai plus long.
  • Le délai d'arrêt est un paramètre de production. Vous pouvez le modifier pour une valeur plus importante. Ce paramètre s'applique au portail de gestion du système.
  • Exécuter un code arbitraire lors d'un arrêt de production en implémentant une méthode OnStop.
  • L'arrêt de la production est un événement contrôlable, vous pouvez toujours voir qui et quand a fait cela dans le journal d'audit.

Ce qui est important ici, c'est que la production est la somme totale des Business Hosts :

  • Le démarrage de la production signifie le démarrage de tous les Business Hosts activés.
  • L'arrêt de la production signifie l'arrêt de tous les Business Hosts en cours d'exécution.
  • La mise à jour de la production consiste à calculer un sous-ensemble de Business Hosts qui sont obsolètes, de sorte qu'ils sont d'abord arrêtés, puis redémarrés immédiatement après. En outre, un Business Host nouvellement ajouté est seulement démarré, et un Business Host supprimé de la production est seulement arrêté.

Cela nous amène au cycle de vie des Business Hosts.

Démarrage du Business Host

Les Business Hosts sont composés de Business Hosts Jobs identiques (en fonction de la valeur du paramètre Pool Size). Le démarrage d'un Business Host implique le démarrage de tous les Business Hosts Jobs. Ils sont démarrés en parallèle.

Business Host Job individuel commence comme ceci :

  1. Interopérabilité de JOBs est un nouveau processus qui deviendrait un Business Host Job.
  2. Le nouveau processus s'enregistre en tant que job d'interopérabilité.
  3. Le code du Business Host et le code de l'adaptateur (Adapter) sont chargés dans la mémoire du processus.
  4. Les paramètres relatifs à un Business Host et à un adaptateur sont chargés dans la mémoire. L'ordre de priorité est le suivant
    a. Paramètres de production (remplacent les paramètres par défaut du système et les paramètres de classe).
    b. Paramètres par défaut du système (prévalent sur les paramètres de classe).
    c. Paramètres de classe.
  5. Le travail est prêt et commence à accepter des messages.

Une fois le point (4) effectué, la tâche ne peut plus modifier les paramètres ou le code. Ainsi, lorsque vous importez un nouveau code et de nouveaux paramètres par défaut, cela n'affecte pas les tâches d'interopérabilité en cours d'exécution.

Arrêt de Business Host

L'arrêt du Business Host Job signifie le suivant :

  1. L'interopérabilité ordonne à Job d'arrêter toute acceptation de messages/entrées.
  2. S'il y a un message actif, le Business Host Job dispose d'un délai de quelques secondes pour le traiter (en le complétant - en complétant la méthode OnMessage pour BO, OnProcessInput pour BS, la méthode d'état S<int> pour les BP BPL, et la méthode On* pour les BP).
  3. Si un message actif n'a pas été traité avant le timeout et force=0, la mise à jour de la production échoue pour ce Business Host (et vous verrez un bouton rouge Update dans le SMP).
  4. L'arrêt réussit si l'un des éléments de cette liste est vrai :
    • Pas de message actif
    • Le message actif a été traité avant le timeout.
    • Le message actif n'a pas été traité avant le timeout MAIS force=1.
  5. Le travail est désenregistré auprès de l'interopérabilité et s'arrête.

Mise à jour de Business Host

La mise à jour du Business Host signifie l'arrêt des tâches en cours d'exécution pour le Business Host et le démarrage de nouvelles tâches.

Les régles métier "Business Rules", les régles de routage "Routing Rules" et les DTL

Tous les Business Hosts commencent immédiatement à utiliser les nouvelles versions des régles Business Rules, Routing Rules et des DTL dès qu'elles sont disponibles. Le redémarrage d'un Business Host n'est pas nécessaire pour cela.

Mises à jour hors ligne

Il arrive cependant que les mises à jour de la production nécessitent l'arrêt de certains Business Hosts.

Les régles dépendent du nouveau code

Considérons la situation. Vous disposez d'une règle de routage Routing Rule X qui achemine les messages vers le processus Business Process A ou B en fonction de critères arbitraires.
Dans un nouveau commit, vous ajoutez simultanément:

  • le processus Business Process C
  • Une nouvelle version de Routing Rule X, qui achemine les messages vers A, B ou C.

Dans ce scénario, vous ne pouvez pas charger la règle d'abord et mettre à jour la production ensuite. En effet, la règle nouvellement compilée commencerait immédiatement à router les messages vers le Business Process C, qu'InterSystems IRIS n'a peut-être pas encore compilé, ou que l'interopérabilité n'a pas encore mis à jour pour l'utiliser.
Dans ce cas, vous devez désactiver le Business Host avec une règle de routage, mettre à jour le code, mettre à jour la production et réactiver le Business Host.

Remarques:

  • Si vous mettez à jour une production à l'aide du fichier de déploiement de la production, tous les BH concernés seront automatiquement désactivés/activés.
  • Pour les hôtes invoqués par InProc, la compilation invalide le cache de l'hôte particulier détenu par l'appelant.

Dépendances entre Business Hosts

Les dépendances entre les Business Hosts sont essentielles. Imaginons que vous ayez des processus Business Hosts A et B, dans lesquels A envoie des messages à B.
Dans un nouveau commit, vous ajoutez simultanément :

  • Une nouvelle version du Processus A, qui définit une nouvelle propriété X dans une demande adressée à B
  • Une nouvelle version du Processus B qui peut traiter une nouvelle propriété X

Dans ce scénario, nous DEVONS mettre à jour le Processus B d'abord et le Processus A ensuite. Vous pouvez procéder de deux manières :

  • Désactiver les Business Hosts pendant la durée de la mise à jour.
  • Diviser la mise à jour en deux parties : d'abord, mettre à jour le Processus B uniquement, et ensuite, dans une mise à jour séparée, commencer à lui envoyer des messages à partir du Processus A.

Une variante plus difficile de ce thème, où les nouvelles versions des Processus A et B sont incompatibles avec les anciennes versions, nécessite un arrêt des Business Hosts.

Files d'attente

Si vous savez qu'après la mise à jour, un Business Host ne pourra plus traiter les anciens messages, vous devez vous assurer que la file d'attente du Business Host est vide avant la mise à jour. Pour ce faire, désactivez tous les Business Hosts qui envoient des messages au Business Host et attendez que sa file d'attente soit vide.

Changement d'état dans les BPL Business Processes

Tout d'abord, une petite introduction sur le fonctionnement des BPL BP. Après avoir compilé un BPL BP, deux classes sont créées dans le paquet, avec le même nom qu'une classe BPL complète :

  • La classe Thread1 contient les méthodes S1, S2, .... SN, qui correspondent à des activités au sein de BPL
  • La classe Context contient toutes les variables de contexte ainsi que le prochain état que BPL exécutera (c'est-à-dire S5).

La classe BPL est également persistante et stocke les demandes en cours de traitement.

BPL fonctionne en exécutant des méthodes S dans une classe Thread et en mettant à jour la table de la classe BPL, la table Context et la table Thread1, où un message "en cours de traitement" est une ligne dans un tableau BPL. Une fois la requête traitée, BPL supprime les entrées BPL, Context et Thread. Puisque les BPL BP sont asynchrones, une tâche BPL peut traiter simultanément de nombreuses requêtes en sauvegardant des informations entre les appels S et en passant d'une requête à l'autre.
Par exemple, BPL traite une requête jusqu'à ce qu'il arrive à une activité sync - en attendant une réponse de BO. Il sauvegarde le contexte actuel sur le disque, avec la propriété %NextState (dans la classe Thread1) fixée à la méthode S de l'activité de réponse, et travaille sur d'autres requêtes jusqu'à ce que BO réponde. Après la réponse de BO, BPL charge le contexte en mémoire et exécute la méthode correspondant à un état sauvegardé dans la propriété %NextState.

Maintenant, que se passe-t-il lorsque nous mettons à jour le BPL ?
Tout d'abord, nous devons vérifier qu'au moins une des deux conditions est remplie :

  • Pendant la mise à jour, le tableau Contexte est vide, ce qui signifie qu'aucun message actif n'est en cours de traitement.
  • Les nouveaux états (New States) sont les mêmes que les anciens (Old States), ou de nouveaux états sont ajoutés à la suite des anciens .

Si au moins une condition est remplie, nous sommes prêts à démarrer. Soit il n'y a pas de demandes de pré-mise à jour à traiter par BPL après la mise à jour, soit les états sont ajoutés à la fin, ce qui signifie que les anciennes demandes peuvent également être traitées (en supposant que les demandes de pré-mise à jour sont compatibles avec les activités et le traitement de BPL après la mise à jour).

Mais que se passe-t-il si vous avez des demandes actives en cours de traitement et que BPL change l'ordre des états ? Idéalement, si vous pouvez attendre, désactivez les appelants BPL et attendez que la file d'attente soit vide. Vérifiez que le tableau Contexte est également vide. N'oubliez pas que la file d'attente n'affiche que les demandes non traitées, et que le tableau Contexte stocke les demandes en cours de traitement, de sorte qu'il peut arriver qu'un BPL très occupé affiche une file d'attente nulle, et c'est normal.
Ensuite, désactivez le BPL, effectuez la mise à jour et activez tous les Business Hosts précédemment désactivés.

Si ce n'est pas possible (généralement dans le cas où le BPL est très long, par exemple, je me souviens avoir mis à jour un BPL qui prenait environ une semaine pour traiter une demande, ou si la fenêtre de mise à jour est trop courte), utilisez l'outil BPL versioning.

Vous pouvez également écrire un script de mise à jour. Dans ce script de mise à jour, associez les anciens next states aux nouveaux next states et exécutez-le sur le tableau Thread1 afin que le BPL mis à jour puisse traiter les anciennes requêtes. BPL, bien sûr, doit être désactivé pendant la durée de la mise à jour.
Ceci dit, il s'agit d'une situation extrêmement rare, et généralement, vous n'avez pas besoin de faire cela, mais si jamais vous devez le faire, voici comment procéder.

Conclusion

L'interopérabilité met en œuvre un algorithme sophistiqué pour minimiser le nombre d'actions nécessaires pour actualiser la production après la modification du code sous-jacent. Appelez UpdateProduction avec un délai d'attente sûr à chaque mise à jour de SDS. Pour chaque mise à jour de code, vous devez décider d'une stratégie de mise à jour.

La réduction de la quantité de code compilé à l'aide de git diffs permet de réduire le temps de compilation, mais la "mise à jour" du code en lui-même et sa recompilation ou la "mise à jour" des paramètres avec les mêmes valeurs ne déclenchent pas ou ne requièrent pas de mise à jour de la production.

La mise à jour et la compilation des règles de gestion "Business Rule", des règles de routage "Routing Rules" et des DTL les rendent immédiatement accessibles sans mise à jour de la production.

Enfin, la mise à jour de la production est une opération sûre qui ne nécessite généralement pas de temps d'arrêt.

Liens

L'auteur tient à remercier @James MacKeith, @Dmitry Zasypkin et @Regilo Regilio Guedes de Souza pour leur aide précieuse dans la rédaction de cet article.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer