Vous pouvez trouver de nombreux articles sur Internet sur la façon de déployer un projet Django en production pour la première fois. Mais, que faire lorsque votre projet est déjà en production, et lors des déploiements, vous devez assurer la cohérence des systèmes associés et, en même temps, la continuité de votre produit ?
La production est un complexe logiciel et matériel mis à la disposition des utilisateurs finaux. Il comprend des serveurs, des machines virtuelles et des conteneurs avec un logiciel stable installé.
Il existe de nombreuses exigences pour la production. Cependant, dans cet article, nous nous concentrerons sur l'efficacité et la continuité.
L'efficacité est une garantie que le produit fera ce qu'il est censé faire.
La continuité est une garantie de travail efficace lors de l'utilisation de ce produit.
Autrement dit, si une tentative de connexion renvoie toujours une erreur, c'est un manque d'efficacité. Mais, si un utilisateur reçoit rarement une telle erreur, il s'agit d'une violation de la continuité.
Plusieurs conteneurs, machines virtuelles ou serveurs sont utilisés en production selon l'architecture.
Je ne considère pas la situation où un seul processus fonctionne sur un serveur en production car il est similaire à l'environnement de développement habituel.
En général, vous rencontrez le plus souvent le schéma avec plusieurs conteneurs. Ils sont accessibles via un équilibreur. Il peut y avoir plus d'un équilibreur. À partir des conteneurs, une seule base de données est accessible, mais il peut y avoir plusieurs bases de données, y compris le sharding et les répliques. Ils peuvent également accéder à des courtiers comme Kafka et à d'autres services. D'autres services peuvent également, d'une manière ou d'une autre, échanger des informations avec des backends.
Par exemple, considérons uniquement les modifications apportées au code et à une base de données.
Les modifications qui peuvent être apportées au code pour que cela affecte une base de données et vice versa :
Vous pouvez également ajouter des déclencheurs et des fonctions, modifier le schéma, etc. Cependant, les approches générales pour appliquer cela à la production sont illustrées dans ces exemples mêmes.
Si vous devez ajouter un modèle (table) à une application localement dans l'environnement de développement, vous devez procéder comme suit :
python manage.py makemigrations
.python manage.py migrate
.
Mais en production, il existe de nombreuses instances de votre application, git, et un processus distinct pour exécuter les migrations.
Vous n'avez pas souvent un accès direct à Prod. Et c'est bien. Par exemple, le flux pourrait ressembler à ceci.
Dans un tel schéma, les migrations sont exécutées en premier. Puis, un par un, les pods sont redémarrés.
Dans une telle architecture, il peut toujours y avoir une situation où des migrations ont été effectuées, mais le code en production n'a pas changé.
Ensuite, les gousses sont remplacées. Certaines instances ont un nouveau code, d'autres ont l'ancien.
De plus, si vous effectuez des migrations lorsque le remplacement du pod est terminé, une situation différente se produira : le code sur le serveur est mis à jour, mais la base de données ne l'est pas.
Les deux situations impliquent une période de temps pendant laquelle la base de données et le code sont incohérents.
Heureusement, Django ne vérifie pas la cohérence. Cependant, l'absence des éléments nécessaires entraîne des exceptions.
Elles sont:
La migration doit être effectuée avant de modifier le code lorsque cela implique :
La migration doit être effectuée après la modification du code lorsque cela implique :
Le renommage s'effectue en plusieurs étapes :
Tout cela semble compliqué. Mais regardez les schémas donnés ci-dessus. En production multi-pod, lors du déploiement, il arrive toujours qu'une partie du code fonctionne avec l'ancien schéma de base de données tandis qu'une autre partie fonctionne avec le nouveau. Cela peut entraîner des exceptions.
Ainsi, les algorithmes de base pour traiter les modèles Django ne fonctionnent pas en production. Les modifications doivent être déployées en plusieurs étapes en fonction de l'architecture du code et du flux CI/CD utilisé dans un cas particulier.
Cependant, lorsque vous apportez des modifications, vous pouvez toujours être guidé par ce que le code attend lors de l'envoi de requêtes à la base de données. Outre les cas standard, il peut y avoir diverses exceptions et obstacles qui nécessitent de l'ingéniosité pour trouver un moyen de contourner.
Dans les prochains articles, je décrirai en détail certains des cas mentionnés ici.