"Ajouter (corriger) des fonctions" "Aucun accident". Le plus dur d'un «ingénieur» est que vous devez faire «les deux». Êtes-vous prêt? J'ai terminé. </ b>
L ' accident décrit ici fait référence à un événement qui empêche l'utilisateur d'utiliser le service et à un événement de perte de confiance du service </ b>. Voici des exemples d'accidents possibles.
La première prémisse qu'un accident est suffisant est le problème de l ' échelle </ b>. Si vous comparez l'échec du service utilisé par 10 personnes avec l'échec du service utilisé par 1 million de personnes, ce dernier est clairement l'accident le plus grave. Ensuite, il faut considérer l'ampleur de l'accident, qu'il s'agisse d'une panne qui a affecté l'ensemble du service ou d'une panne qui n'a touché qu'un petit nombre d'utilisateurs. (Si l'échelle est trop petite, la cause de l'accident peut être écartée et la réponse peut être un règlement.) Deuxièmement, cela dépend de l'importance des informations traitées par le service </ b>. Par exemple, s'il s'agit d'un service qui ne gère pas d'informations personnelles, il n'y a rien à voler, vous n'avez donc pas à vous soucier beaucoup de la sécurité (bien qu'il n'y ait presque pas de tels services de nos jours), et s'il s'agit d'un système bancaire, vous devez bien sûr conserver tous les journaux d'accès au réseau. Il y a, et il est nécessaire d'empêcher la falsification et l'accès non autorisé.
Les humains sont des créatures qui font des erreurs, donc tant que vous le faites manuellement, vous ferez la même erreur un jour, ou une autre personne fera la même erreur. Dans les deux cas, il serait préférable que le contrôle soit automatisé </ b> aussi bien que manuel. En tant que facteur qui cause un accident, il y a de nombreux cas qui se produisent en dehors de la portée de l'hypothèse de l'implémenteur </ b>, donc si vous utilisez un système à grande échelle, partagez les informations entre les membres. Il est important d'utiliser la recherche par mot-clé et l'imagination </ b> pour savoir où </ b> et les corrections vous affecteront. (Par exemple, lorsqu'une modification modifie non seulement le système principal mais également les sous-systèmes en dehors du champ de responsabilité) Il est important de créer un mécanisme de surveillance et de notification et lire les messages d'erreur </ b>. Lors de la création d'un système avec des services cloud tels qu'AWS et GCP, il est recommandé d'utiliser Datadog.
En particulier, le langage et la plate-forme d'exécution peuvent être n'importe quoi, mais j'écris en supposant un service Web général construit à l'aide du cloud PaaS.
Les accidents sont susceptibles de se produire principalement en raison de paramètres incorrects autour du réseau et d'authentification / autorisation </ b> et ressources de serveur insuffisantes </ b>. Il est classé dans ceux qui doivent être vérifiés une fois et ceux qui doivent être vérifiés à chaque fois en raison de modifications fonctionnelles, et ceux qui nécessitent une surveillance constante.
Lors de la création d'un réseau privé virtuel pour l'accès entre serveurs à l'aide de VPC (Virtual Private Cloud) sur AWS, etc. Un accident qui empêche la communication entre des serveurs qui étaient auparavant en mesure de communiquer. En guise de contre-mesure, vérifiez la communication entre chaque serveur du réseau défini et du serveur vers Internet. Une fois confirmé, cela ne peut se produire que lors de la reconstruction du réseau.
Un accident qui se produit lorsque vous faites une erreur en définissant l'enregistrement CNAME, l'enregistrement A, l'enregistrement TXT, etc. lorsque l'enregistrement DNS est défini dans un service tel que Route53 d'AWS. Un accident se produit si vous oubliez de définir ou de confirmer la communication lorsque vous changez de domaine. Une fois confirmé, cela ne peut se produire que lors du changement de domaine ou de changement d'enregistrements.
Quelques années après l'expiration du certificat SSL, la communication https est soudainement devenue impossible et un avertissement du navigateur a été émis. Il est nécessaire de prendre des mesures telles que la mise en place du renouvellement automatique du certificat SSL ou la notification avant la date d'expiration.
Un accident qui se produit lorsque l'autorité d'accès à un service cloud est modifiée par erreur lors de l'ajout ou de la modification de fonctions liées au cloud. Par exemple, lorsque vous utilisez AWS IAM, cela se produit lorsque l'autorisation d'accès S3 est uniquement l'autorisation de lecture et l'autorisation d'écriture est oubliée. En guise de contre-mesure, exécutez-le avec le programme ou l’autorité utilisateur définie et vérifiez s’il est accessible ou écrit.
Vous pouvez avoir un cache pour un chemin d'URL spécifique dans un paramètre CDN tel que CloudFront. En ayant un cache, il est possible de renvoyer une réponse à grande vitesse à partir de la deuxième fois S'il y a une omission dans la définition du paramètre de liste blanche, un accident se produit dans lequel le paramètre n'est pas passé à ALB ou au serveur. Lors de la création d'un cache d'API, notez que lorsque vous ajoutez un paramètre d'implémentation, vous devez également l'ajouter à la liste blanche. </ b>
Le serveur auquel il est fait référence ici comprend un serveur d'API, un serveur de base de données, etc. Les deux nécessitent une surveillance constante. En principe, ne créez pas de point de défaillance unique </ b>. (Par exemple, s'il n'y a qu'un seul serveur et que le serveur est abandonné, tout le système s'arrêtera) Les ressources serveur suivantes posent un problème
Plus précisément, il existe les mesures suivantes
Si le processeur continue de s'en tenir à 100% en raison d'un traitement à forte charge comme une boucle infinie, d'autres traitements ne peuvent pas être effectués et les performances diminuent. Il est nécessaire de surveiller le taux d'utilisation du processeur et le temps de réponse de l'API, et si les ressources du processeur sont insuffisantes, corrigez le traitement en charge ou augmentez les spécifications du processeur. Notez également que les instances t2 d'AWS et dyno de Heroku ont une limite supérieure de ressources CPU, et le serveur s'arrêtera si l'opération dépasse la limite supérieure. Vous devez utiliser l'augmentation ou la charge du processeur.
En créant une zone de swap, vous pouvez temporairement utiliser la zone de disque lorsque vous manquez de mémoire. Étant donné que la zone de swap est une zone de disque, le traitement d'E / S se produit et les performances diminuent, mais la zone de mémoire est perforée et le serveur ne s'arrête pas au pire. (Je veux augmenter la mémoire avant d'utiliser la zone de swap ...) Si la mémoire est perforée, vous ne pourrez pas ouvrir le fichier avec un éditeur tel que vim, alors redémarrez le serveur ou ouvrez le fichier avec less et éditez-le. (Moins était le plus léger de l'expérience passée)
Si vous ne faites rien avec le fichier journal, il occupera le disque du serveur et finira par perforer le disque. Vous pouvez supprimer régulièrement les anciens fichiers journaux à l'aide de la commande logrotate. (Cela évitera les crevaisons dans le fichier journal) Lorsque le service gère les téléchargements de fichiers, téléchargez sur un service de stockage de fichiers tel que S3 au lieu de télécharger directement sur le serveur.
Si vous utilisez AWS EC2, vous pouvez sauvegarder l'intégralité de l'instance EC2 sur l'écran des paramètres AWS. Surtout, s'il y a un problème qui ne peut pas être récupéré immédiatement, annulez-le avec la sauvegarde DB.
Concernant le CPU, la mémoire, le disque, pas de réponse au bilan de santé pendant une certaine période de temps, etc. Il est possible de sauter les notifications (email, Slack) lorsque le seuil est dépassé avec Datadog.
Si vous configurez plusieurs serveurs et accédez via un équilibreur de charge, même si l'un d'entre eux tombe en panne, vous pouvez le couvrir avec un autre serveur, vous n'avez donc pas à arrêter le système. (Le serveur est surveillé en direct par la vérification de l'état de l'équilibreur de charge) Si la charge augmente, augmentez le nombre de serveurs et faites une mise à l'échelle automatique. S'il s'exécute sur un service géré sans serveur tel qu'AWS Lambda ou Firebase Functions, il évoluera automatiquement et vous n'aurez qu'à configurer la mémoire. De plus, si vous créez un serveur avec un conteneur Docker, vous pouvez également utiliser AWS Fargate pour mettre à l'échelle automatiquement le conteneur Docker.
Dans de rares cas, le service cloud lui-même peut échouer. AWS:AWS Service Health Dashboard GitHub:GitHub Status S'il n'est pas rétabli à long terme, l'impact commercial sera très important et les contre-mesures consistent à répartir temporairement les régions et à les rendre superflues.
C'est la cause d'accidents la plus fréquente. Cela se produit souvent parce que l'implémenteur a une mauvaise compréhension des spécifications du système, des spécifications du langage et des bibliothèques </ b>. En outre, si la dette technique s’accumule et que des erreurs de conception, la lisibilité du code, l’uniformité et la possibilité de recherche sont perdues </ b>, les accidents sont plus susceptibles de se produire. Ce que vous devriez voir dans la revue de code est résumé dans Code Review Tiger Volume.
Un accident qui nuit à la confiance du système de l'utilisateur. Cela entraîne également la perte d'informations personnelles et les pires dommages financiers. Bien sûr, s'il s'agit de http, il sera écouté (ou plutôt, un avertissement sera émis par le navigateur), donc la communication https est effectuée. Portez une attention particulière à la zone autour de l'entrée du formulaire, dans laquelle l'utilisateur peut entrer relativement librement, car elle a tendance à être une faille de sécurité.
--XSS: Soumettez une forme de script JS malveillant qu'un utilisateur malveillant peut exécuter sur le navigateur et l'enregistrer dans la base de données. Lorsqu'un autre utilisateur parcourt les données enregistrées dans la base de données, un script JS malveillant est exécuté et des informations telles que le jeton de connexion enregistré dans le navigateur sont envoyées à l'utilisateur malveillant. En guise de contre-mesure, il est codé au moment de l'entrée, et il n'est pas affiché comme un code d'exécution sur le côté frontal. Si vous utilisez un framework tel que React, il sera automatiquement détoxifié. (Hors dangereusement setinnerhtml)
Il y a beaucoup d'autres choses, mais le mot de passe est haché brut sans le sauvegarder dans la base de données. Il est essentiel de séparer les API qui nécessitent une authentification des API qui ne nécessitent pas d'authentification.
Se produit en raison de la mise en cache ou de l'écrasement d'autres chemins lors de l'ajout de chemins
Par exemple, lorsqu'un chemin d'API est ajouté, le routage existant est écrasé et l'API cible n'est pas accessible. (Dans le cas du SPA, il y a un accident où la page cible ne peut pas être affichée en écrasant l'itinéraire du pseudo-routage tel que React Router.)
POST /api/hoge
POST /api/hoge/:id //← Ajouter
POST /api/hoge/:key //← Bien que les paramètres d'URL soient différents, l'API ci-dessus a la priorité en termes de chemin et ne peut pas être atteinte.
Lors de l'ajout, il est important de vérifier si l'accès des autres chemins est écrasé, de modifier l'ordre ou de passer à un autre chemin. Plus précisément, il est possible d'effectuer des tests récursifs avec CI en créant un test d'appel d'API. Puisqu'il s'agit d'un test d'appel pour un chemin spécifié, la fonction attendue à appeler peut être simulée.
Si vous supprimez l'ancienne API ou l'URL de la page, le cache du navigateur restera et l'ancienne API ou l'URL de la page sera accessible, ce qui pose un problème. Surtout dans le cas de SPA, l'ancien bundle.js restera jusqu'à ce que le cache CDN et le cache du navigateur disparaissent et que le navigateur soit rechargé, de sorte que le cache CDN est effacé et l'ancienne API doit être redirigée vers la nouvelle API. De plus, Google Bot, etc. ont un cache de l'ancien chemin, donc l'accès vient à l'ancien. Si vous utilisez le cache, vous devrez 301 rediriger vers la nouvelle page car elle accédera à l'ancienne API et à la page.
Si vous appelez l'API d'un service externe, vous devez vérifier les spécifications de l'API externe.
Il a tendance à être négligé. Il est nécessaire de contrôler même si vous ne savez pas quel type d'erreur est retourné même si vous regardez les spécifications de l'API ou s'il y a une erreur de communication. Vous devez également décider d'effectuer un traitement ultérieur en cas d'erreur.
Ceci est également facile à ignorer si vous ne regardez pas les spécifications de l'API, et si c'est local, il n'y a pas de problème avec un petit nombre de requêtes, mais si vous le mettez en place dans l'environnement de production, vous pouvez faire un grand nombre de requêtes et une erreur peut se produire. Dans de nombreux cas, la limite supérieure peut être augmentée par facturation, mais s'il existe une méthode alternative, elle est limitée aux cas où elle n'est pas utilisée ou où le coût peut être payé. Si la limite supérieure ne peut pas être augmentée, il existe une méthode de mise en file d'attente (batch) afin que la limite supérieure du nombre de requêtes API ne soit pas dépassée, ou si des performances en temps réel sont requises, le renvoyer comme une erreur (faire attendre l'utilisateur).
Pour les API avec état qui ne sont pas sans état (API Rest), vous pouvez conserver la session sous votre compte utilisateur. Si la session expire, vous devez vous reconnecter, vous devez donc prendre des mesures pour le traitement de la reconnexion. Les API avec des sessions de service externes ne doivent pas dépasser la limite de session, etc.
Les langages sans GC (garbage collection) (C, C ++, etc.) seront bien sûr utilisés lorsque la mémoire dynamique est sécurisée, et si la mémoire n'est pas explicitement libérée, la zone mémoire sera consommée. Même dans un langage avec GC (JavaScript, etc.), une instance qui a été allouée en mémoire avec new Si une référence circulaire est faite, la mémoire n'est pas libérée même par GC et une fuite de mémoire se produit. Il existe une méthode pour détecter l'emplacement de la fuite de mémoire et utiliser une référence faible (WeakRef) ou un pointeur intelligent lors du référencement circulaire. En premier lieu, c'est aussi une bonne idée de ne pas utiliser de nouveau autant que possible et de ne pas en faire une référence circulaire.
D'ailleurs, dans le cas de JavaScript, WeakRef existe au stade de la proposition Méthode de détection de fuite de mémoire NodeJS est utile.
Faites attention aux performances des tables avec un grand nombre d'enregistrements. Le traitement backend ralentit les temps de réponse et bloque le système lorsque les performances sont dégradées. Pour la lecture, l'index est collé dans les champs souvent utilisés pour la recherche dans la table, et pour l'écriture en masse dans le script de migration et le traitement par lots, il est nécessaire de prendre des mesures pour écrire en peu de temps par traitement en masse. Après cela, la répartition de la charge provisoire peut être effectuée en démarrant le serveur pour le nombre de cœurs de processeur dans un multi-processus (cluster). Générez un framegraph pour rechercher les goulots d'étranglement des performances à l'échelle du système.
Par exemple, NodeJS a une méthode de recherche bien organisée dans Node.js Performance Tuning Starting from 0.
Si vous faites une erreur lors de la mise en œuvre d'un script de migration de données, telle que l'insertion de données ou une erreur au milieu, entraîne une incohérence des données, implémentez-la dans une transaction et annulez-la en cas de problème. De plus, sauvegardez les données avant l'exécution au cas où il y aurait un problème après l'exécution. En outre, les processus importants qui nécessitent l'écriture dans plusieurs tables, comme la facturation, sont échangés pour éviter les incohérences.
Si vous faites référence à l'API du sous-système à partir du système principal et que vous devez mettre à niveau l'API du sous-système pour renvoyer des données différentes Fondamentalement, il n'est pas possible de libérer le sous-système et le système principal exactement en même temps, il est donc nécessaire de prendre des mesures.
Vérifiez si les changements affectent non seulement le système principal mais également les sous-systèmes. Ce domaine est strict si l'ensemble du système n'est pas connu, et il n'y a pas d'autre choix que de le mettre en œuvre et de le réviser par des experts. Il est nécessaire de disposer d'un système de partage d'informations sur une base régulière. Cela est particulièrement susceptible de se produire lorsque les champs de la table DB sont modifiés ou supprimés. Un accident peut survenir si des outils BI tels que Redash sont interrogés ou si les données sont automatiquement synchronisées avec un autre système tel que Salesforce.
Les transactions DB, le contrôle exclusif multi-thread, etc. le traitement des blocs, donc si vous oubliez de l'annuler, le système se bloquera. (Impasse) Par exemple, il existe une mesure telle que l'encapsulation avec la syntaxe try au début de la transaction et la vérification du déverrouillage avec l'instruction finally.
Cela se produit lors de la gestion d'une bibliothèque tierce avec un outil de gestion de packages tel que npm ou gem Vous ne pouvez utiliser la bibliothèque que s'il y a un mérite qui dépasse la maintenance, car la bibliothèque sur-spécifiée consomme de l'espace (en particulier lorsque l'utilisateur télécharge l'application ou le fichier JS), et il est obligatoire de mettre à niveau la bibliothèque. En premier lieu, implémentez avec des spécifications de langage et des API standard sans inclure de bibliothèques inutiles. La version de la librairie est corrigée sans la remonter indistinctement jusqu'à ce que l'opération soit confirmée (version majeure, version mineure, version patch). En outre, les fichiers qui gèrent des dépendances détaillées telles que package-json.lock et yarn.lock sont répertoriés comme la version de la bibliothèque dont dépend la bibliothèque tierce, ne les supprimez donc pas sans discernement. Si vous supprimez ces fichiers, la version de la bibliothèque dont dépend la bibliothèque tierce sera récupérée lorsque vous la réinstallez, ce qui peut provoquer un accident (une fois).
Ce n'est peut-être pas une cause directe de l'accident, mais cela peut être un facteur qui cause un accident s'il est négligé.
En particulier, le backend doit être implémenté dans un langage typé (NodeJS + TypeScript, go, Java). La raison en est que la compilation statique peut éviter des erreurs imprudentes.
Pour l'implémentation dans TypeScript, Clean Code for TypeScript est utile.
Gardez à l'esprit KISS </ b> (conception et mise en œuvre simples). Lorsque vous utilisez des classes, modifiez les spécifications en faisant attention aux Principes SOLID et à la Loi de Demeter. Il est également solide et facile à tester. (Séparation de la dépendance et de l'intérêt)
Unifiez les règles de dénomination et les règles de codage. C'est bien lorsque le projet est petit, mais lorsque le projet est grand, l'efficacité du travail est évidemment réduite si le fichier ne peut pas être recherché immédiatement. Unifiez l'étui de chameau, l'étui de serpent, etc. en un seul (ne pas mélanger!). Il est étonnamment important d'éviter les fautes de frappe, de ne pas utiliser le même nom de variable ou de fonction même s'il est utilisé dans un sens différent, et d'éliminer les fluctuations de notation. Cela est dû à la prévention des omissions et des malentendus. (Unifier le modèle de domaine) Vous pouvez utiliser une recherche floue telle que fzf pour rechercher une faute de frappe existante dans le projet. La quantité de bogues augmente proportionnellement à la quantité de code, alors gardez toujours à l'esprit YAGNI </ b> (ne pas implémenter inutilement, ne pas partir).
--Insérer de la charpie pour unifier les règles de codage --Saisissez les commentaires appropriés (principalement l'explication des spécifications de la fonction et de la logique métier) et rédigez le plus concis possible
Règles de relations publiques pour éviter les accidents, ne pas avoir plusieurs rôles de relations publiques (responsabilité unique) Étant donné que le nombre d'erreurs augmente proportionnellement à la quantité de code, la quantité de correction doit être réduite. En particulier, il est dangereux de faire de nombreuses corrections qui chevauchent le fichier source ou des corrections qui sont fortement dépendantes, donc ne mélangez pas autant que possible les corrections. Faites une liste de contrôle pour les choses qui nécessitent un travail post-publication et des correctifs importants.
Ecrivez un test </ b> qui devient un atout et effectuez un test récursif </ b> avec CI.
Recommended Posts