Fonctionnalité bascule: vues, avantages et utilisation avec eux dans .NET


Le commutateur de fonctionnalité est un outil qui vous permet de passer de l'ancienne fonctionnalité à la nouvelle sans reconstruire l'application et la relâcher à nouveau. Il est implémenté en ajoutant un opérateur conditionnel ( if ) au code, ce qui permet de contrôler le comportement du programme en changeant simplement la valeur souhaitée dans le fichier de configuration ou la base de données. Si vous avez déjà modifié les paramètres dans un fichier ini, vous connaissez bien cette technologie.

En creusant plus profondément, vous pouvez trouver un grand nombre d'options différentes pour les commutateurs et les nouvelles fonctionnalités qu'ils offrent. Cela soulève de nombreuses questions. Où placer la configuration? Mais que se passe-t-il s'il devient indisponible? Peut-être pouvez-vous écrire vous-même un cadre simple pour travailler avec des commutateurs? Peut-être vaut-il mieux prendre une solution toute faite? Cela convient-il à la fois au monolithe et aux microservices?

Ce matériel contient des informations de base sur les commutateurs de fonctionnalités dans le contexte du développement sur la plate-forme .NET. La première partie contient des informations générales sur les commutateurs; ils sont assez indépendants de l'implémentation spécifique et peuvent être utiles pour les professionnels travaillant avec une variété de plates-formes. La deuxième partie traite des outils modernes spécifiques qui facilitent l'utilisation des commutateurs lors du développement pour .NET.

J'ai essayé d'écrire un article qui vous aidera à décider d'implémenter des commutateurs de fonctionnalités dans votre cas spécifique et, si nécessaire, comment. Dans notre département, les commutateurs ne sont jusqu'à présent utilisés que pour résoudre des problèmes particuliers. Par exemple, notre application doit souvent demander des informations juridiques et comptables à un catalogue, qui peut être présenté sous deux formes: un catalogue complet distant et sa copie partielle locale. Dans les paramètres de l'application, les utilisateurs peuvent choisir le type de répertoire avec lequel l'application doit fonctionner à l'heure actuelle. Les plans comprennent l'introduction de commutateurs en tant qu'infrastructure commune pour l'ensemble du projet. Sur cette base, des processus similaires à ceux décrits ci-dessus seront construits.


Présentation du commutateur de fonctionnalités


Qu'est ce que c'est


En termes simples, la signification des commutateurs est la suivante. L'entrepreneur avance à travers notre code, représentant la logique du sujet, et tombe sur une déclaration conditionnelle. Dans cette déclaration, l'entrepreneur demande si un code conditionnel doit être exécuté à partir d'un registre qui sait quand et dans quelles circonstances la fonctionnalité d'intérêt devrait fonctionner.


En conséquence, l'exécuteur va le long d'une branche ou d'une autre, et dans un cas dégénéré, l'autre branche est simplement vide. Dans le cas le plus simple, le commutateur prend l'une des deux valeurs («on» et «off») sous le contrôle de la personne responsable qui tient le registre. Et vous pouvez proposer quelque chose de plus compliqué, par exemple, inclure des fonctionnalités uniquement pour des utilisateurs spécifiques ou pour des utilisateurs de certains pays, ou à un certain moment.

Le registre des fonctionnalités peut prendre différentes formes. Le point est quand vous pouvez gérer ce registre sans arrêter l'application ou le redéployer. Par exemple, les commutateurs peuvent être stockés dans un fichier, dans une base de données ou avoir un service réseau distinct avec des commutateurs. Ci-dessous, le fonctionnement des commutateurs est examiné plus en détail.

Est-ce même pertinent?


Dans son article, le créateur de featureflag.tech affirme que les commutateurs deviennent une pratique standard dans le développement de logiciels. Il existe de plus en plus de documents sur les commutateurs: articles théoriques, histoires sur la pratique de la mise en œuvre de commutateurs, rapports lors de conférences. J'ai inclus des liens vers les matériaux les plus intéressants dans le texte de cet article; Tous les liens sont rassemblés dans la section "Conclusion" .

Je dirais que la croissance de la popularité des commutateurs est facilitée par la stabilisation et la normalisation dans certains domaines des technologies de l'information. Dans «l'entreprise sanglante» apparaît de plus en plus d'îles de stabilité. Une augmentation du nombre de métriques dans le développement, l'automatisation de l'assemblage, l'inspection et la livraison de l'application conduit au fait que les processus de développement deviennent plus transparents et gérables. En conséquence, les exigences pour un nouveau niveau commencent à être présentées à la création de logiciels. L'une de ces exigences est le désir de diffuser dans le temps les moments de publication de l'application et l'inclusion de nouvelles fonctionnalités, qui sont mises en œuvre par les commutateurs. Les capacités de l'industrie ont déjà mûri pour répondre à cette demande industrielle.

Quant aux outils qui aident à travailler avec les commutateurs, ils sont très, très nombreux et pour une variété de plates-formes. L'apparition d'un grand nombre d'outils s'explique probablement par la simplicité avec laquelle vous pouvez implémenter les capacités de base des commutateurs. Mais l'ajout de petits pains plus complexes et «savoureux» peut nécessiter des coûts de main-d'œuvre importants, de nombreux projets open source qui implémentent des commutateurs de fonctionnalités cessent de se développer et d'être pris en charge. Néanmoins, un nombre important de projets, à la fois payants et gratuits, restent à flot. Les plus intéressants d'entre eux (du point de vue de .NET) sont décrits dans la deuxième partie de l'article .

Un peu plus


Cet article a un bon diagramme illustrant le fonctionnement des commutateurs; Je vous invite à vous familiariser avec cela.


Nous commençons notre examen du circuit avec du code. Laissez dans notre exemple une nouvelle fonctionnalité - vérifier l'exactitude du remplissage du document. Nous nous assurons que le document n'est vérifié que si cette fonctionnalité est activée. Faisons un point de commutation:

 var document = GetDocument(); if (feature.IsEnabled("Feature #123. Document validation")) { Validate(document); } 

Dans ce cas, feature est une référence à l'infrastructure qui aide notre application à communiquer avec le routeur et le registre de fonctionnalités. En utilisant cette infrastructure, nous découvrons s'il est nécessaire de vérifier le document, et si oui, puis vérifiez-le.

Le routeur utilise les informations dont il dispose: le nom de la fonctionnalité que nous avons passée en argument et ce que nous pouvons extraire des classes statiques qu'il connaît pour déterminer si la fonctionnalité demandée devrait fonctionner dans ce cas. Le routeur découvre comment les commutateurs du registre sont configurés. Si le registre n'est pas disponible, vous devez soit utiliser les données précédemment mises en cache, soit recourir à une autre stratégie pour ce cas. Vous pouvez également imaginer un routeur qui reçoit explicitement des informations supplémentaires (le contexte) via les arguments de la méthode qui l'aide à décider d'activer la fonctionnalité pour le moment.

Le personnel responsable configure les commutateurs de la manière sélectionnée. Dans l'option la plus agréable, ils se rendent sur le site qui représente le registre des commutateurs, et cliquent sur les commutateurs sélectionnés avec la souris.

Ainsi, dans le sens d'artefacts, le système de commutation se compose de deux parties. D'une part, il s'agit d'une infrastructure permettant au programmeur de déterminer si la fonctionnalité doit fonctionner dans ce cas et de diriger l'exécution le long de la branche de code appropriée. D'un autre côté, c'est un mécanisme qui permet à un employé responsable de choisir la fonctionnalité à activer et celle à désactiver. Dans les cas dégénérés (lorsque le registre est cousu dans le code, voir ci-dessous), les deux artefacts peuvent coïncider et le programmeur peut contrôler les fonctionnalités d'activation et de désactivation.

Configuration système requise pour les commutateurs


Comme vous pouvez le voir, le système de commutation peut être assez compliqué. Nous énumérons les exigences de base qui peuvent être imposées à un tel système.

  1. La dépendance de la fonctionnalité on et off de différents paramètres. Exemples de paramètres: utilisateur (rôle, identifiant, situation géographique), heure (lumière du jour ou obscurité, jours ouvrables ou jours de semaine, périodes spécifiques), environnement (pour le développement, les tests, l'exploitation industrielle).
  2. Collecte de statistiques d'utilisation lors de l'analyse des processus de domaine: quel utilisateur dans quelles conditions a vu ou n'a pas vu la fonctionnalité, combien de fois il a utilisé la nouvelle fonctionnalité.
  3. Un audit de ce qui se passe avec les commutateurs eux-mêmes: qui les appuie, quand, ce qui change.
  4. Fournir un choix flexible entre les fonctionnalités de registre local et distant ou certaines stratégies dans le cas où le registre distant n'est pas disponible.
  5. Configuration de l'accès au système de commutation pour différentes catégories d'employés chez le client et le contractant: spécialistes techniques, spécialistes dans le domaine concerné, ainsi que les utilisateurs d'applications eux-mêmes.

Bien sûr, il n'est pas nécessaire de s'efforcer de satisfaire à toutes ces exigences. Dans de nombreux cas, certaines exigences, au contraire, peuvent être indésirables. Plus vous devez vous conformer aux exigences, plus le développement de votre propre système de commutation est évidemment contraignant. Cela signifie qu'à un moment donné après l'introduction des commutateurs, le support de votre propre système devient non rentable et il est temps de prendre une solution toute faite.

Arbre technologique


Nous résumons les informations considérées sur les commutateurs de fonctionnalité, en recourant à la métaphore de l' arbre technologique des jeux vidéo. Imaginons les commutateurs comme une technologie qui permet à l'entreprise de déployer de nouvelles fonctionnalités sans être liée aux moments de l'assemblage et du déploiement de l'application. Cette technologie a un coût connu (le coût du maintien des cycles de vie des commutateurs et du registre) et les conditions préalables à la mise en œuvre: une méthodologie de développement flexible plus une intégration continue. Bien sûr, l'intégration continue n'est pas une condition préalable, mais elle rend les commutateurs beaucoup plus efficaces et permet une livraison continue de l'application. De plus, la «recherche» des commutateurs «ouvre» d'autres technologies - les tests A / B et les sorties de canaris. Ils seront discutés ci-dessous.



Où se trouve le registre des fonctionnalités


Considérez plusieurs options pour placer le registre des fonctionnalités, en les plaçant dans une complexité croissante de mise en œuvre.

  1. Cousez la configuration directement dans le code, par exemple, commentez le code inutile et décommentez le code nécessaire ou utilisez les directives de compilation conditionnelle. De toute évidence, cette option tue l'essence de l'introduction des commutateurs, car avec elle, vous devrez recompiler et déployer l'application pour voir les nouvelles fonctionnalités. Il convient également de noter deux difficultés. Tout d'abord, avec cette approche, un employé qui inclut des fonctionnalités aura besoin de compétences techniques supplémentaires: l'édition du code source et la capacité de travailler avec le système de contrôle de version (SLE). Dieu sait quelles compétences, bien sûr, mais très probablement, les programmeurs eux-mêmes devront inclure des fonctionnalités. Deuxièmement, la fonctionnalité sera la même sur tous les nœuds où cette version de l'application a été publiée - pour choisir entre l'ancienne et la nouvelle fonctionnalité, vous aurez besoin d'un équilibreur et de plusieurs nœuds avec l'application.
  2. Placez la configuration dans l'environnement d'application, par exemple, dans des variables d'environnement. Cette option semble un peu extravagante, car elle est lourde de l'apparence de dépendances excessives sur le runtime ou sur le système d'exploitation.
  3. Utilisez des fichiers de configuration, qui sont un endroit assez standard pour stocker les paramètres d'application. L'inconvénient de cette option sera la nécessité de maintenir les fichiers de configuration séparément à côté de chaque instance de l'application. Cet inconvénient est inhérent à la version précédente.
  4. Gérez une table dans la base de données qui décrit les commutateurs de fonctionnalité. Les instances d'application vont frapper sur cette base de données pour voir si la fonctionnalité qui les intéresse fonctionne. Dans cette option, le registre est centralisé (contrairement à la version précédente), mais laisse la possibilité d'inclure des fonctionnalités séparément pour chaque nœud, si cela est pris en charge par l'infrastructure de commutation sélectionnée.
  5. Augmentez le service réseau auquel les instances d'application accéderont via le protocole réseau sélectionné. Si dans la version précédente, cela signifiait que les commutateurs seront très probablement stockés avec les entités du domaine concerné, et donc que le coût de l'interrogation des commutateurs sera prévisible, alors nous aurons ici un accès supplémentaire sur le réseau. Le coût d'une manipulation supplémentaire et la possibilité d'un déni de service sont de sérieux inconvénients de cette option, mais, bien sûr, la mise en cache n'est pas interdite. Et pour les échecs, vous devez fournir un comportement par défaut.

Recommandations


Concernant l'utilisation des commutateurs, les recommandations générales suivantes peuvent être faites.

Il n'est pas nécessaire que le point de commutation et la logique soient ensemble . Dans l'exemple le plus simple, après l'instruction conditionnelle, dans laquelle nous interrogeons l'état d'un commutateur spécifique, le code implémente immédiatement la fonctionnalité incluse. Ce n'est pas très pratique, car cela ajoute des dépendances redondantes à la logique: la connaissance de l'infrastructure des commutateurs et le nom d'une fonctionnalité particulière du registre. En pratique, cela complique le processus de test et de retrait du commutateur lorsqu'il devient inutile.

Réglez le point de commutation plus haut . Développement du paragraphe précédent. Les points d'accès à l'infrastructure de commutation doivent être exclus de la logique du sujet jusqu'à la dernière opportunité possible, c'est-à-dire les "rapprocher" de l'endroit où la demande a été reçue. Ainsi, nous réduisons la dépendance des modules individuels vis-à-vis des commutateurs, simplifions les processus de prise en charge et de test.

Utilisez des stratégies plutôt que des instructions conditionnelles . Si le commutateur va vivre pendant longtemps, l'opérateur conditionnel peut être amélioré en une stratégie et isoler explicitement la logique commutable en quelque chose de séparément suivi et testé.

Ne regroupez pas les commutateurs . Vous ne devez pas former de dépendances entre les commutateurs, les grouper et les assembler en hiérarchies. Cela facilitera la maintenance du code avec de nouvelles fonctionnalités et le cycle de vie des commutateurs eux-mêmes.

Consolidez les points de commutation pour une fonctionnalité . Il peut s'avérer que le comportement de plusieurs blocs de programme à la fois dépend du même commutateur. Si le développement est mal coordonné, les points de commutation peuvent être dupliqués à différents endroits, ce qui entraîne des tests et une assistance plus coûteux. Si vous êtes discipliné pour essayer de «pousser» les points de commutation vers l'entrée de l'application, cette recommandation - ne pas disperser les points dans le système - est généralement effectuée automatiquement.

Les principales catégories de commutateurs


Tenez compte de la classification des commutateurs indiquée dans cet article . Elle est basée sur la durée de vie du commutateur et la fréquence à laquelle son état change. L'affectation d'un commutateur à une classe spécifique permet de déterminer comment utiliser le commutateur dans le code et comment stocker l'état du commutateur.

Commutateurs de libération

Ceci est la vue principale des commutateurs. Ils vous permettent de concentrer le développement dans une seule branche principale, qui par ailleurs se déploie régulièrement en opération commerciale. Au lieu de développer dans une branche distincte et de l'injecter dans la branche principale pour publier la version souhaitée, nous introduisons un point de commutation dans le code, qui masque la fonctionnalité qui n'est pas encore prête aux utilisateurs. Une fois prêts, les commutateurs lancent de nouvelles fonctionnalités.

Ces commutateurs vivent plusieurs jours ou semaines - tandis que le développement et la mise en œuvre de nouvelles fonctionnalités sont en cours. Lorsque la fonctionnalité a été testée et jugée appropriée, le commutateur et le point de commutation dans le code peuvent être supprimés. L'état du commutateur change généralement soit lorsqu'une nouvelle version est publiée, soit lorsque la configuration de l'application change. Il est permis de stocker un tel commutateur dans le fichier de configuration. Il y a une forte probabilité que le point de commutation pour une nouvelle fonctionnalité soit le seul; il est logique de ne pas creuser et de le placer sous la forme d'une instruction conditionnelle conventionnelle.

Commutateurs d'expérience

Pour exécuter de nouvelles fonctionnalités, des commutateurs sont utilisés qui durent de plusieurs jours à plusieurs mois. Pendant l'expérience, vous pouvez surveiller la façon dont les utilisateurs perçoivent les changements et comment leur comportement change. Il est souhaitable que l'état du commutateur puisse changer de manière très dynamique à chaque demande. Un stockage centralisé, comme une base de données ou un service réseau, est plus susceptible de convenir ici. Si l'expérience s'inscrit dans un nombre prévisible de problèmes, le point de commutation peut également être émis sous la forme d'une déclaration conditionnelle.

Commutateurs

techniques Les commutateurs techniques aident à gérer les éléments d'infrastructure d'une application qui affectent ses performances globales. Ils peuvent être utiles lorsque nous déployons une mise à jour dont l'impact sur les performances est difficile à évaluer. Dans ce cas, il serait bien d'avoir un «commutateur» qui désactive instantanément les nouvelles fonctionnalités s'il s'avère que son utilisation entraîne des conséquences désastreuses.

Très probablement, ces commutateurs dureront plusieurs semaines ou plus et changeront d'état lorsque la configuration de l'application changera ou plus souvent. La criticité de la fonction implémentée par ces commutateurs suggère qu'ils doivent utiliser un service réseau ou au moins une base de données. Vous devez commencer à vous assurer que dans le code les points de commutation pour la même fonctionnalité ne sont pas dispersés à différents endroits.

Commutateurs pour le contrôle d'accès

Une autre possibilité évidente d'utiliser des commutateurs est de fournir l'accès à de nouvelles fonctionnalités uniquement à certains utilisateurs. Cela peut être nécessaire à la fois pour la version Canary (lorsque de nouvelles fonctionnalités couvrent progressivement de plus en plus d'utilisateurs) et pour créer des sections privées auxquelles seuls les utilisateurs privilégiés ont accès.

Il semble que de tels commutateurs vivent assez longtemps (peut-être aussi longtemps que l'application elle-même) et peuvent changer d'état à chaque nouvelle demande. Un service réseau pour stocker les commutateurs convient également ici. Il est recommandé d'utiliser une sorte de mécanisme centralisé pour choisir entre l'ancienne et la nouvelle fonctionnalité et de ne pas disperser les instructions conditionnelles dans le code.

,


L'introduction de commutateurs de fonctionnalités présente non seulement des avantages évidents, pour lesquels tout est généralement démarré (diversité dans le temps de publication de l'application et d'activation de nouvelles fonctionnalités, réduction du nombre de succursales en devise forte), mais elle peut également simplifier certains processus secondaires. Nous les énumérons et en examinons ensuite plus en détail.

Test A / B. Comparaison du comportement des utilisateurs utilisant les nouvelles et anciennes versions.

Problèmes des Canaries. Augmentation progressive du nombre d'utilisateurs ayant accès à de nouvelles fonctionnalités.

Libérations bleu-vert. Envoyez des demandes à l'aide de l'équilibreur au serveur avec l'ancienne version ou au serveur avec la nouvelle version.

Fonctionnalité extrême prévue.L'inclusion de fonctionnalités pendant une courte période, par exemple pendant la promotion.

Inclusion simultanée de fonctionnalités à plusieurs endroits. L'inclusion de fonctionnalités à la fois sur le site et dans l'application mobile. Ou l'inclusion de fonctionnalités simultanément dans différents modules de la même application.

Changements majeurs d'infrastructure. Par exemple, la transition vers une autre façon de stocker des données.

Tester de nouvelles choses par les utilisateurs. Offrir aux utilisateurs la possibilité d'activer et de désactiver les nouvelles fonctionnalités, en personnalisant l'application pour eux-mêmes.

Test A / B

Jetons un bref coup d'œil à ce qu'est le test A / B. Lors de la préparation des tests A / B, une propriété mesurable du système d'information ou du comportement de l'utilisateur est formulée. Exemples de cette propriété: 1) la durée d'un processus spécifique dans le domaine, 2) le nombre relatif d'utilisateurs qui ont atteint une page spécifique, 3) le nombre de ressources que l'application utilise. En outre, une hypothèse est faite sur la façon dont la valeur de cette propriété changera lorsque de nouvelles fonctionnalités seront incluses. Les utilisateurs obtiendront-ils une réponse plus rapide? Achèteront-ils plus? L'application mangera-t-elle moins?

Ensuite, pendant les tests A / B, pour un groupe, la nouvelle fonctionnalité est activée et pour l'autre, elle reste désactivée. Les hypothèses faites lors de la préparation sont vérifiées et, sur la base des résultats, il est conclu si la nouvelle fonctionnalité donne quelque chose de bien et ne mène pas à quelque chose de mauvais. Parfois, les utilisateurs sont divisés en trois groupes, dans deux desquels la fonctionnalité reste ancienne. Si les résultats des deux groupes de contrôle sont très différents, alors l'ensemble du test contient une sorte d'erreur, ce qui rend les conclusions basées sur ce test peu fiables.

Les commutateurs de fonctionnalité facilitent la division des utilisateurs en groupes et leur gestion. Pour chaque groupe, vous pouvez activer et désactiver de nouvelles fonctionnalités sans attendre la prochaine version de l'application. Cela réduit le temps nécessaire pour vérifier les hypothèses et achever l'ensemble du cycle de test A / B. De nombreuses entreprises cherchent à établir une vérification de plusieurs hypothèses par semaine.

Vous pouvez en savoir plus sur cette méthode dans cet article , ici et ici sur «Habré», et cela vaut vraiment la peine de jeter un coup d'œil au rapport «Feature Toggles, ou How to roll features without release» , qui révèle quelques subtilités intéressantes des tests A / B avec des commutateurs de fonctionnalités.

Problèmes

des canaris et bleu-vert Qu'est-ce que les canaris ont à voir avec cela? Les canaris étaient utilisés dans l'industrie minière: les mineurs emportaient des canaris dans une cage lorsqu'ils descendaient dans une mine, où une forte concentration de gaz explosifs était suspectée. Les canaris aiment beaucoup l'air pur et beaucoup plus tôt que les gens commencent à y sentir des impuretés nocives et dangereuses. Si le canari cesse de chanter, s'éteint ou meurt, les gens doivent évacuer d'urgence jusqu'à ce qu'il explose. Ici , ici vous pouvez en savoir plus sur ce (en anglais).

De là, si je comprends bien, vient l'expression "témoignage du canari". Si vous vivez dans un État poursuivant une politique intérieure répressive (c'est-à-dire dans n'importe quel pays), vous constaterez peut-être un jour que vous avez été chargé non seulement de transférer les données personnelles de vos utilisateurs aux services autorisés, mais également de ne dire à personne que vous ils ont été remis, non pas que vous ayez reçu un tel ordre. Bien sûr, vous ne pourrez pas sortir, mais dans certains cas, vous pouvez régulièrement envoyer des messages de ce type à vos utilisateurs: "Le mois dernier, nous n'avons pas reçu l'ordre de divulguer vos données personnelles." Voilà comment vous gazouillez, gazouillez comme un canari, et quand vous recevez une commande pour fournir des données personnelles, vous fermez. Ainsi, vous respectez l'exigence des autorités et donnez à vos utilisateurs des raisons de se méfier.

Et il y a des problèmes de canaris. Ici, la métaphore fonctionne comme ceci: quand une petite partie des utilisateurs tombe malade, nous «évacuons» de toute urgence - nous désactivons une nouvelle fonctionnalité qui a rendu les utilisateurs malades et ne la laissons pas atteindre tous les utilisateurs (ne la laissez pas «se branler»). Pour ce faire, vous devez pouvoir étendre la nouvelle fonctionnalité à différents groupes. Ici, vous pouvez vous passer de commutateurs. Par exemple, nous avons un équilibreur et deux nœuds où il redirige les demandes. Sur un nœud, nous avons déployé une version stable, et sur le second, une version expérimentale contenant de nouvelles fonctionnalités. Par défaut, toutes les demandes sont envoyées au nœud avec la version stable, et avec l'aide de l'équilibreur, nous commençons à envoyer certaines demandes au nœud avec la version expérimentale.

Mais avec le commutateur, vous pouvez obtenir plus de flexibilité dans la façon dont les nouvelles fonctionnalités s'étendent aux utilisateurs. Dans le commutateur, vous pouvez combiner différents paramètres des demandes reçues et fournir aux employés responsables une interface graphique pratique pour gérer le problème des canaris. En général, le processus reste le même: nous incluons de nouvelles fonctionnalités pour un petit groupe d'utilisateurs, par exemple, pour 1%. Après cela, nous surveillons l'état de l'application, le comportement des utilisateurs travaillant avec la nouvelle fonctionnalité et faisons une prévision de ce qui se passera lorsque nous l'étendrons à un plus grand nombre d'utilisateurs. Embrassant progressivement de plus en plus d'utilisateurs avec de nouvelles fonctionnalités, nous pouvons tester et ajuster nos hypothèses. Si nous remarquons des tendances négatives,alors la nouvelle fonctionnalité peut être facilement désactivée.

Pendant la version bleu-vert, deux serveurs sont utilisés, provisoirement appelés bleu et vert. Nous supposons qu'avant la publication, l'équilibreur envoie toutes les demandes au serveur vert. Pendant la version, une nouvelle version de l'application est déployée sur un serveur bleu, où l'équilibreur commence également à envoyer des demandes. S'il s'avère que la nouvelle version de l'application contient des erreurs, nous revenons au serveur vert.

La version de base de la version bleu-vert suggère que les utilisateurs travaillent avec toutes les nouvelles fonctionnalités incluses dans la nouvelle version, ou ne fonctionnent avec aucune. Et avec l'utilisation de commutateurs, il devient possible lors de la publication d'envoyer des requêtes au serveur bleu avec la nouvelle version, pour laquelle les commutateurs de toutes les nouvelles fonctionnalités sont désactivés. Après cela, vous pouvez progressivement intégrer la nouvelle fonctionnalité dans les pièces.

Vous pouvez voir que les commutateurs de fonctionnalité vous permettent de combiner les avantages des versions canaries et bleu-vert. Habituellement, lors d'une version bleu-vert, il existe deux nœuds clairement séparés avec les anciennes et les nouvelles versions de l'application, et avec l'aide de l'équilibreur, nous redirigeons toutes les demandes à la fois vers un nœud ou l'autre. Et avec les commutateurs, nous pouvons rediriger les requêtes vers le nœud avec la nouvelle version, mais avec la nouvelle fonctionnalité désactivée, puis l'activer progressivement, comme lors de la version canari.

Un peu plus de détails sur les questions canariennes - dans l' article correspondant sur le site Fowler ou sur «Habré», par exemple ici . À propos des versions bleu-vert - dans un article de synthèse. Et l'utilisation des commutateurs de fonction dans les versions bleu-vert peut être trouvée ici .

Changer la façon dont les données sont stockées.

Pendant longtemps, lorsque j'ai étudié des techniques de programmation telles que l'abstraction et le développement à partir d'interfaces, j'ai souvent rencontré la recommandation suivante: essayez d'empêcher votre programme d'être lié à une méthode spécifique de stockage de données, par exemple, à une base de données spécifique, car à l'avenir Vous devrez peut-être modifier la méthode de stockage. Je l'ai enroulé sur ma moustache et j'ai fait ce qui avait été commandé. Depuis lors, cependant, les raisons pour lesquelles je partage la logique du domaine et la méthode de stockage ont changé, et au contraire, j'ai commencé à être sceptique quant à la possibilité de changer la base de données dans un produit commercial.

Et tout en préparant ce matériel, j'ai appris sur les gars qui assurentque de nombreuses entreprises pratiquent la modification des bases de données dans les produits industriels. De plus, le changement de la base de données est censé être complètement indolore si vous utilisez les commutateurs de fonctionnalité. Il est clair que l'article mentionné a été écrit par des personnes intéressées (le site est soutenu par le fabricant d'un outil commercial de gestion des commutateurs), mais cela ne fera pas de mal de considérer la stratégie de basculement vers une autre base de données qu'ils ont proposée.

Décrivez brièvement la stratégie comme suit. Le processus démarre à partir du moment où notre application fonctionne avec une (ancienne) base de données. En utilisant les commutateurs de fonctionnalité, nous forçons séquentiellement notre application à écrire d'abord des données dans une nouvelle base de données, puis à lire les données de la nouvelle base de données. En même temps, l'interaction avec l'ancienne base de données est préservée: nous écrivons et lisons dans les deux bases de données!

Si le dossier est plus ou moins clair, alors la lecture doit être clarifiée. Lorsqu'une application a besoin de données, elle les lit dans les deux bases de données. Ces deux points de lecture sont toujours côte à côte pour qu'après la lecture, vous puissiez comparer les données reçues et vérifier leur cohérence. Après stabilisation de l'application (lorsque les deux bases de données commencent à renvoyer de manière stable les mêmes données), l'application est déconnectée de l'ancienne base de données et les commutateurs sont supprimés.

Une description détaillée de la stratégie pour passer à une nouvelle base de données en utilisant MongoDB et DynamoDB comme exemple.
MongoDB DynamoDB. DynamoDB: ( ) MongoDB. — , , , — . (DynamoDB).

, MongoDB, — DynamoDB. , DynamoDB ( MongoDB). , DynamoDB .



DynamoDB , MongoDB. - MongoDB. , . , («» «»), . - DynamoDB . , , . — .

MongoDB, DynamoDB. , , , , , , . - , , MongoDB, , . , , , . , .

, . , , DynamoDB. MongoDB, .

. , , , DynamoDB , MongoDB , DynamoDB 100 %. , .

Inclusion simultanée de fonctionnalités sur différentes plates-formes

Le rapport déjà mentionné «Fonctionnalité bascule ou comment déployer des fonctionnalités sans publication» a parlé de la nécessité d'activer de nouvelles fonctionnalités en même temps (minute par minute!) À la fois sur le site et dans l'application mobile. Et vous devrez peut-être également l'éteindre de la même manière.

Répondre à une telle exigence n'est pas facile, car la livraison de nouvelles versions pour différentes plates-formes est très difficile à synchroniser. Si les serveurs avec le site sont sous votre contrôle, vous pouvez toujours deviner quelque chose (et espérer que cette fois la livraison fonctionnera comme une horloge), le magasin d'applications mobiles peut changer la politique de mise à jour des mises à jour à sa guise. Dans tous les cas, la mise à jour de l'application est un long processus qui comprend la vérification de l'application publiée par le magasin lui-même. De plus, il ne faut pas espérer que l'application mobile elle-même demandera régulièrement des mises à jour à son API et les installera «à l'intérieur» d'elle-même. Cette boutique, si je comprends bien, est également sous la surveillance attentive du propriétaire de la plate-forme - il y aura certainement des problèmes avec l'exécution de code arbitraire.

Mais les commutateurs aident à répondre à l'exigence de l'inclusion simultanée de fonctionnalités dans un environnement où vous ne pouvez pas contrôler complètement la livraison de l'application. De toute évidence, la livraison devrait toujours être garantie jusqu'à l'inclusion prévue. Cette méthode sera probablement utile pendant les périodes de promotions temporaires, comme le Black Friday.

Une situation similaire existe avec plusieurs modules d'un même système. S'ils sont publiés séparément et participent en même temps à la prise en charge d'un processus du domaine, les commutateurs vous permettent d'apporter des modifications coordonnées à ce processus du côté de divers modules.

Changer d'outils dans .NET


Les outils pour travailler avec des commutateurs peuvent être divisés en trois groupes. Premièrement, ce sont des produits lourds universels (combinées), qui incluent généralement un service réseau qui fonctionne avec un fournisseur et un ensemble de bibliothèques qui vous permettent de communiquer avec ce service pour différents langages de programmation. Presque toujours, vous devez payer (et beaucoup) pour utiliser de tels produits. Deuxièmement, ce sont des projets qui sont des services réseau qui doivent être exécutés sur leurs ordinateurs et auxquels les clients peuvent accéder via l'API REST. Parmi les projets de ce groupe (par souci de concision, nous les appellerons serveurs), seuls ceux qui ont une API bien documentée ou un client officiel pour .NET sont entrés dans l'aperçu. Troisièmement, il s'agit de bibliothèques simples (par rapport aux deux groupes précédents) pour .NET.Ils suggèrent de stocker le registre des fonctionnalités dans des fichiers de configuration ou d'accéder à un registre distant qui ne fait pas partie de ces projets sur le réseau.

Un lecteur attentif remarquera qu'il existe un autre groupe d'outils logiciels qui ne sont pas tombés dans la revue. Ce sont des produits qui peuvent être utilisés comme référentiel de configuration pour un système distribué. Les représentants bien connus de tels produits incluent Apache ZooKeeper , Consul et etcd , et dans les commentaires de cet article, ils mentionnent également Spring Cloud Config Server, qui peut facilement être lié d'amitié avec .NET. En effet, dans leurs capacités de base, les commutateurs sont très similaires aux référentiels de configuration, ces outils peuvent donc être utilisés comme point de départ pour créer votre propre infrastructure de commutateurs. Néanmoins, étant donné que le but des commutateurs de fonctionnalité a certaines spécificités, avec le développement de la culture des commutateurs au sein du projet, les inconvénients des référentiels de configuration universels commenceront à se faire sentir. Pour cette raison, les produits similaires ne sont pas davantage discutés.

Moissonneurs


LaunchDarkly

Il semble que ce soit le produit le plus en vogue et le plus "furieux" dans le domaine des commutateurs de fonctionnalités. On a le sentiment que ce produit correspond à presque tout ce qui ne vient à l'esprit que lorsque l'on parle de commutateurs. Cela s'applique aux capacités de la plateforme elle-même, à la variété des clients disponibles et aux types d'intégration avec divers outils tels que Jira et Visual Studio Code. Tout est documenté en détail et avec des exemples. L'outil, bien sûr, est payant, mais pendant la période d'essai de 30 jours, il peut être utilisé gratuitement.

Catamorphic Co., le fabricant de ce produit, parraine également un site de référence dédié au commutateur de fonctionnalités .

Microsoft.FeatureManagement

Développement Microsoft pour .NET Core, qui peut être utilisé de deux manières principales: d'une part, en tant que bibliothèque cliente, qui permet de travailler avec des commutateurs et de stocker leur état dans un fichier de configuration, et d'autre part, en tant que moissonneuse-batteuse, y compris en plus de cette bibliothèque un emplacement centralisé pour gérer les commutateurs dans Azure. L'outil semble être basé sur l'infrastructure de configuration d'application Azure plus générale, pour laquelle il existe une API documentée .

La bibliothèque cliente offre des possibilités intéressantes d'intégration avec ASP.NET Core, par exemple, des filtres supplémentaires sur les actions des contrôleurs et une visualisation conditionnelle d'une vue, selon l'état des commutateurs.

Dans les commentaires de cet article, ils vous suggèrent de vous familiariser avec la série de notes utilesMicrosoft.FeatureManagement

Déploiement

Le site a l'air bien, mais lorsque vous essayez d'obtenir des informations spécifiques, les problèmes commencent. Par exemple, il est indiqué que le produit possède de nombreuses fonctionnalités intéressantes pour l'audit des commutateurs, la surveillance de l'utilisation des fonctionnalités et la conduite d'expériences. Mais en même temps, les fabricants ne divulguent pas les politiques de prix (il est clair qu'il existe un essai gratuit de 14 jours) et conservent une documentation assez brute de leur API REST. Cependant, la documentation des bibliothèques clientes est en règle. Le système prend en charge le stockage des commutateurs dans les fichiers de configuration.

Optimizely

En général, Optimizely est une sorte de plate-forme intéressante pour collecter des analyses et mener des expériences. Le système a une partie Rollouts gratuite .fournissant des capacités de commutation de base. Il est écrit qu'en plus de prendre en charge le ciblage («déployer» la fonctionnalité sur certains groupes d'utilisateurs), cette partie gratuite prend en charge un nombre infini de commutateurs et de projets. De plus, autant d'employés que vous le souhaitez peuvent utiliser ce système. Il convient de noter que le coût de nombreux autres produits est déterminé précisément par ces caractéristiques quantitatives. Combien cela coûtera de passer à une plate-forme entièrement fonctionnelle est un secret.

Train à grande vitesse

Cette plate-forme semble assez simple. Il n'a pas de fonctionnalités spéciales comme la collection analytique - seulement les principales fonctionnalités des commutateurs. Lorsque vous placez la plateforme sur vos propres serveurs, vous pouvez l'utiliser gratuitement.

Split

Une autre plateforme timide par rapport à ses prix. Des "puces" supplémentaires offrent une intégration avec quelques autres outils de développement et un support pour la conduite d'expériences (tests A / B).

ConfigCat

Et voici un produit avec un site amusant où il y a des chats. Cela a l'air provocateur. Cependant, il est suspect que la documentation de l'API REST n'y soit pas publiée. Avec le client sous .NET, tout va bien. Au fait, il y a un plan gratuit.

Moggles

Un projet open source qui comprend un serveur avec un site pour la gestion des commutateurs et un client. Pour démarrer le serveur, SQL Server est requis. Semble assez mature.

Serveurs


Unleash

Un projet open source assez mature qui implique l'hébergement d'un système sur les serveurs de l'entreprise. Comprend un site de gestion de commutateur simple. Il existe des outils simples intégrés pour prendre en compte l'utilisation des fonctionnalités. L'installation est assez simple; PostgreSQL requis.

Il n'y a pas de bibliothèque cliente .NET officielle, mais plusieurs bibliothèques tierces ont déjà été créées. De plus, grâce à l'API documentée, vous pouvez en théorie créer votre propre bibliothèque.

Indicateurs de fonctionnalité Gitlab

GitLab a construit son système de commutateurs au-dessus de Unleash, donc les mêmes bibliothèques clientes sont utilisées pour interagir avec GitLab que pour Unleash. Il diffère de Unleash lui-même en ce sens que vous devez creuser moins avec l'installation (sauf pour l'installation de GitLab lui-même), mais vous devez payer: des commutateurs de fonctionnalités sont disponibles à partir des plans GitLab Premium (si GitLab fonctionne sur vos propres serveurs) et GitLab Silver (si GitLab s'exécute sur les serveurs du fournisseur).

API de drapeaux de fonctionnalités dans Go

Ce projet open source est un service avec une API (peu documentée) à travers laquelle vous pouvez gérer les commutateurs. Apparemment, il n'y a pas d'interface graphique. Écrit en Go; utilise des bases de données intégrées et un serveur réseau, donc le réglage, à en juger par les instructions, est trivial. Fournit des capacités de ciblage rudimentaires. Dernière modification dans le dépôt: 20 février 2019.

Bandiera

Aussi un projet ouvert. Service avec API et GUI. Écrit en Ruby; nécessite MySQL ou PostgreSQL pour fonctionner, ou peut être installé à partir de Docker. Il existe des clients pour Ruby, Node, Scala, PHP, mais pas pour .NET. Prend en charge un ensemble assez varié de types de commutateurs.

Flagr

Un autre projet open source sur Go. Installé à partir de Docker. Il existe une interface graphique, ainsi que des clients pour Ruby, Go, JavaScript, Python. Il propose des outils simples intégrés pour rendre compte de l'utilisation des fonctionnalités et de l'expérimentation. Chaque commutateur peut être configuré de manière flexible et équipé de sa propre configuration.

Bibliothèques clientes


Il existe un grand nombre de bibliothèques pour .NET qui fournissent les fonctionnalités de base des commutateurs. Mais la plupart d'entre eux sont dans un état abandonné. Un examen rapide a montré qu'en 2019, seuls deux projets avaient été modifiés dans les référentiels. J'ai trouvé deux autres projets intéressants à travers les liens dans les commentaires de cet article. Tous sont présentés ci-dessous.

Esquio

Le projet le plus intéressant, le mieux documenté et le plus fonctionnel de son groupe. Le moteur de stockage intégré est soit un fichier de configuration soit un EF Core. Il s'intègre un peu à ASP.NET Core (comme Microsoft.FeatureManagement); la documentation indique que l'utilisation d'Azure peut simplifier la configuration du commutateur.

Interrupteur

Il peut demander l'état du commutateur à partir du fichier de configuration et à distance (il est configuré à l'aide de classes d'espace FeatureSwitch.Strategies). Dans le kit, il y a un cadre de site Web simple qui vous permet de gérer les commutateurs. Il n'est pas clair s'il est possible de faire un interrupteur plus complexe que l'activation / la désactivation.

Toggle.Net

La bibliothèque la plus simple pour travailler avec des commutateurs, qu'elle stocke dans un fichier texte. Apparemment, il ne prend en charge que les interrupteurs marche / arrêt. Bibliothèque cliente

RimDev.FeatureFlags

pour ASP.NET Core. En plus de permettre l'utilisation de commutateurs de fonctionnalité, il ouvre, avec le site principal du projet, une page supplémentaire sur laquelle les commutateurs peuvent être contrôlés. Le moteur de stockage de configuration intégré est SQL Server.

( ) .


«» .

. , , .

. , , , .

. , A/B-.

. .

. .

Conclusion


Il semble que dans de nombreuses entreprises, il est déjà devenu courant d'utiliser des commutateurs pour couvrir les moments de la sortie de la version et de l'inclusion de nouvelles fonctionnalités. De plus, les commutateurs aident à réduire le degré de folie lors de la fusion de branches dans un système de contrôle de version. En outre, ils ouvrent la voie à des techniques populaires telles que les problèmes de canaris et les tests A / B.

Pour travailler avec des commutateurs, tellement de logiciels ont été créés, à la fois payants et gratuits, que toute entreprise peut choisir l'outil à sa guise.

En conséquence, j'énumérerai les caractéristiques des commutateurs de fonctionnalité et volontairement (comme d'habitude) les diviserai en avantages et inconvénients.

Les avantages


  1. , — , , .
  2. , . , .
  3. , . , , , , .
  4. , . . , «» .
  5. , . , . , .

Inconvénients


  1. . , . : , . , , .
  2. . , , . : , , , , . : ( ), .
  3. . ? , ? . , , . ? ? : , .
  4. — , . , . : (); ( ); .
  5. — , . : (); «/».
  6. , . : ; (, ).
  7. . , ? : , , , ( ).

Les références


( )
( Medium)
( HighLoad++)
- ( )


- («»)
(«»)
(«»)
- ( Featureflags.io)
( Featureflags.io)
Microsoft ( )


( )
( Smithsonian)
(«»)

15.08.2019
15.08.2019 alex1t
17.08.2019 pashuk

Source: https://habr.com/ru/post/fr463471/


All Articles