From a23dfec354a2051467105fe0d58a3aaaa92eb919 Mon Sep 17 00:00:00 2001 From: Fred Pauchet Date: Mon, 2 May 2022 20:10:45 +0200 Subject: [PATCH] Retrieve architecture image from data intensive apps --- chapters/architecture.tex | 10 ++-- chapters/infrastructure.tex | 10 +++- chapters/new-project.tex | 3 ++ images/diagrams/infrastructure.drawio.png | Bin 0 -> 60951 bytes parts/deployment.tex | 55 ++++++++++++---------- 5 files changed, 47 insertions(+), 31 deletions(-) create mode 100644 images/diagrams/infrastructure.drawio.png diff --git a/chapters/architecture.tex b/chapters/architecture.tex index 3046f2c..8e4ff3f 100644 --- a/chapters/architecture.tex +++ b/chapters/architecture.tex @@ -38,7 +38,7 @@ Des équivalents à ces directives existent au niveau des composants, puis au ni \section{Modules} -\subsection{Single Responsility Principle} +\subsection{Single Responsility Principle} \label{SRP} Le principe de responsabilité unique conseille de disposer de concepts ou domaines d'activité qui ne s'occupent chacun que d'une et une seule chose. @@ -474,7 +474,7 @@ L’implémentation d’une imprimante multifonction aura tout son sens: \begin{listing}[H] \begin{minted}[tabsize=4]{java} - public class AllInOnePrinter implements Printer extends IPrinter + public class AllInOnePrinter extends Printer implements IPrinter { public AllInOnePrinter(string name) { @@ -504,7 +504,7 @@ Tandis que l’implémentation d’une imprimante premier-prix ne servira pas à \begin{listing}[H] \begin{minted}[tabsize=4]{java} - public class FirstPricePrinter implements Printer extends IPrinter + public class FirstPricePrinter extends Printer implements IPrinter { public FirstPricePrinter(string name) { @@ -723,7 +723,7 @@ Plus spécifiquement, la définition exacte devient celle-ci: Que l'on résumera ainsi: "don’t depend on things you don’t need", comme nous l'avons déjà expliqué plus haut. -\subsection{Stable dependency principle} +\subsection{Stable Dependency Principle} \label{SDP} Ce principe définit une formule de stabilité pour les composants, en fonction de leur faculté à être modifié et des composants qui dépendent de lui: au plus un composant est nécessaire, au plus il sera stable (dans la mesure où il lui sera difficile de changer). En C++, cela correspond aux mots clés \#include. @@ -731,7 +731,7 @@ Pour faciliter cette stabilité, il convient de passer par des interfaces (donc, En Python, ce ratio pourrait être calculé au travers des import, via les AST. -\subsection{Stable Abstraction Principle} +\subsection{Stable Abstraction Principle} \label{SAP} Ce principe-ci définit les politiques de haut niveau vs les composants plus concrets. SAP est juste une modélisation du OCP pour les composants: nous plaçons ceux qui ne changent pas ou pratiquement pas le plus haut possible dans l'organigramme (ou le diagramme), et ceux qui changent souvent plus bas, dans le sens de stabilité du flux. diff --git a/chapters/infrastructure.tex b/chapters/infrastructure.tex index 102c8de..d9d5ba6 100644 --- a/chapters/infrastructure.tex +++ b/chapters/infrastructure.tex @@ -1,5 +1,11 @@ \chapter{Infrastructure et composants} +\begin{figure}[H] + \centering + \scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/diagrams/infrastructure.drawio.png}} + \caption{Une architecture possible pour un système de données, qui combine plusieurs composants \cite[p. 5]{data_intensive}} +\end{figure} + Pour une mise ne production, le standard \emph{de facto} est le suivant: \begin{itemize} @@ -94,7 +100,7 @@ Comme nous l'avons vu dans la première partie, Django est un framework complet, La structure des niveaux de journaux est essentielle. \begin{quote} -When deciding whether a message should be ERROR or WARN, imagine being woken up at 4 a.m. +When deciding whether a message should be ERROR or WARN, imagine being woken up at 4 a.m. Low printer toner is not an ERROR. --- Dan North former ToughtWorks consultant @@ -159,7 +165,7 @@ exemples}. \item Zabbix \end{enumerate} - + Il existe également \href{https://munin-monitoring.org}{Munin}, \href{https://www.elastic.co}{Logstash, ElasticSearch et Kibana (ELK-Stack)} ou \href{https://www.fluentd.org}{Fluentd}. diff --git a/chapters/new-project.tex b/chapters/new-project.tex index 843bb96..4f39f06 100644 --- a/chapters/new-project.tex +++ b/chapters/new-project.tex @@ -705,3 +705,6 @@ En relançant la couverture de code, on voit à présent que nous arrivons à 99 \end{verbatim} En continuant de cette manière (ie. Ecriture du code et des tests, vérification de la couverture de code), on se fixe un objectif idéal dès le début du projet. En prenant un développement en cours de route, fixez-vous comme objectif de ne jamais faire baisser la couverture de code. + +A noter que tester le modèle en lui-même (ses attributs ou champs) ou des composants internes à Django n'a pas de sens: cela reviendrait à mettre en doute son fonctionnement interne. +Selon le principe du SRP \ref{SRP}, c'est le framework lui-même qui doit en assurer la maintenance et le bon fonctionnement. diff --git a/images/diagrams/infrastructure.drawio.png b/images/diagrams/infrastructure.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..8c28130efb6df764809751c4238438a45a792941 GIT binary patch literal 60951 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 k>iL`}}+P!QZAlb7lYnPgg&ebxsLQ04Ywzf&c&j literal 0 HcmV?d00001 diff --git a/parts/deployment.tex b/parts/deployment.tex index 24d8954..40a239f 100644 --- a/parts/deployment.tex +++ b/parts/deployment.tex @@ -1,6 +1,11 @@ \part{Déploiement} -\includegraphics{images/penguin-overflow.jpg} +\begin{figure}[H] + \centering + \scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/penguin-overflow.jpg}} + \caption{David Revoy} +\end{figure} + \begin{quote} To be effective, a software system must be deployable. The higher the @@ -10,21 +15,19 @@ is seldom considered during initial development. This leads to architectures that may be make the system easy to develop, but leave it very difficult to deploy. - + --- Robert C. Martin Clean Architecture \end{quote} - + Il y a une raison très simple à aborder le déploiement dès maintenant: à trop attendre et à peaufiner son développement en local, on en oublie que sa finalité sera de se retrouver exposé et accessible depuis un -serveur. -Il est du coup probable d'oublier une partie des désidérata, de zapper une fonctionnalité essentielle ou simplement de passer énormément de temps à adapter les sources pour qu'elles puissent être mises à -disposition sur un environnement en particulier, une fois que leur développement aura été finalisé, testé et validé. -Un bon déploiement ne doit pas dépendre de dizaines de petits scripts éparpillés sur le disque. L'objectif est qu'il soit rapide et fiable. Ceci peut être atteint au travers d'un partitionnement correct, incluant le fait que le composant principal s'assure que chaque sous-composant est correctement démarré intégré et supervisé. +serveur. +En cas de dérogation à ceci, il sera probable d'oublier une partie des désidérata, de zapper une fonctionnalité essentielle ou simplement de passer énormément de temps à adapter les sources pour qu'elles puissent être mises à disposition sur un environnement en particulier, une fois que leur développement aura été finalisé, testé et validé. +Un bon déploiement ne doit pas dépendre de dizaines de petits scripts éparpillés sur le disque: l'objectif est qu'il soit rapide et fiable. Ceci peut être atteint au travers d'un partitionnement correct, incluant le fait que le composant principal s'assure que chaque sous-composant est correctement démarré intégré et supervisé. Aborder le déploiement dès le début permet également de rédiger dès le début les procédures d'installation, de mises à jour et de sauvegardes. A la fin de chaque intervalle de développement, les fonctionnalités auront dû avoir été intégrées, testées, fonctionnelles et un code propre, démontrable dans un environnement similaire à un environnement de production, et créées à partir d'un tronc commun au développement \cite{devops_handbook}. -Déploier une nouvelle version sera aussi simple que de récupérer la dernière archive depuis le dépôt, la placer dans le bon répertoire, appliquer des actions spécifiques (et souvent identiques entre deux -versions), puis redémarrer les services adéquats, et la procédure complète se résumera à quelques lignes d'un script bash. +Déploier une nouvelle version doit être le plus simple possible, et doit se résumer, dans le pire des cas, à quelques lignes d'un script Bash. \begin{quote} Because value is created only when our services are running into production, we must ensure that we are not only delivering fast flow, but that our deployments can also be performed without causing chaos and @@ -33,35 +36,39 @@ disruptions such as service outages, service impairments, or security or complia --- DevOps Handbook Introduction \end{quote} -Le serveur que django met à notre disposition \emph{via} la commande \texttt{runserver} est extrêmement pratique, mais il est uniquement prévu pour la phase développement: en production, il est inutile de -passer par du code Python pour charger des fichiers statiques (feuilles de style, fichiers JavaScript, images, \ldots\hspace{0pt}). De même, Django propose par défaut une base de données SQLite, qui fonctionne -parfaitement dès lors que l'on connait ses limites et que l'on se limite à un utilisateur à la fois. En production, il est légitime que la base de donnée soit capable de supporter plusieurs utilisateurs et connexions simultanés. En restant avec les paramètres par défaut, il est plus que probable que vous rencontriez rapidement des erreurs de verrou parce qu'un autre processus a déjà pris la main pour écrire ses données. En bref, vous avez quelque chose qui fonctionne, qui répond à un besoin, mais qui va attirer la grogne de ses utilisateurs pour des problèmes de latences, pour des erreurs de verrou ou simplement parce que le serveur répondra trop lentement. +Le serveur que Django met à notre disposition \emph{via} la commande \texttt{runserver} est extrêmement pratique, mais il est uniquement prévu pour la phase développement. +En production: + +\begin{itemize} + \item Il est inutile de passer par du code Python pour charger des fichiers statiques (feuilles de style, fichiers JavaScript, images, ... + De même, Django propose par défaut une base de données SQLite, qui fonctionne parfaitement dès lors que l'on connait ses limites et que l'on se limite à un utilisateur à la fois. + \item Il est légitime que la base de donnée soit capable de supporter plusieurs utilisateurs et connexions simultanés. + En restant avec les paramètres par défaut, il est plus que probable que vous rencontriez rapidement des erreurs de verrou parce qu'un autre processus a déjà pris la main pour écrire ses données. En bref, vous avez quelque chose qui fonctionne, qui répond à un besoin, mais qui va attirer la grogne de ses utilisateurs pour des problèmes de latences, pour des erreurs de verrou ou simplement parce que le serveur répondra trop lentement. +\end{itemize} L'objectif de cette partie est de parcourir les différentes possibilités qui s'offrent à nous en termes de déploiement, tout en faisant en sorte que le code soit le moins couplé possible à sa destination de production. L'objectif est donc de faire en sorte qu'une même application puisse être hébergées par plusieurs hôtes sans avoir à subir de modifications. Nous vous renvoyons vers les 12-facteurs dont nous -avons déjà parlé et qui vous énormément nous aider, puisque ce sont des variables d'environnement qui vont réellement piloter le câblage entre l'application, ses composants et son hébergeur. +avons déjà parlé et qui vous énormément nous aider, puisque ce sont des variables d'environnement qui vont réellement piloter le câblage entre l'application, ses composants et son hébergement. -RedHat proposait récemment un article intitulé \emph{*What Is IaaS*}, qui présentait les principales différences entre types d'hébergement. +RedHat proposait récemment un article intitulé \emph{*What Is IaaS*}, qui présentait les principales différences entre types d'hébergement. -\begin{figure} -\centering -\includegraphics{images/deployment/iaas_focus-paas-saas-diagram.png} -\caption{L'infrastructure en tant que service, cc. \emph{RedHat Cloud -Computing}} +\begin{figure}[H] + \centering + \scalebox{1.0}{\includegraphics[max size={\textwidth}{\textheight}]{images/deployment/iaas_focus-paas-saas-diagram.png}} + \caption{L'infrastructure en tant que service, cc. \emph{RedHat Cloud Computing}} \end{figure} Ainsi, on trouve: \begin{enumerate} -\def\labelenumi{\arabic{enumi}.} \item - Le déploiment \emph{on-premises} ou \emph{on-site} + Le déploiment \emph{on-premises} ou \emph{on-site}, \item - Les \emph{Infrastructures as a service} ou \emph{IaaSIaaS} + Les \emph{Infrastructures as a Service} ou \emph{IaaS} \item - Les \emph{Platforms as a service} ou \emph{PaaSPaaS} + Les \emph{Platforms as a Service} ou \emph{PaaS} \item - Les \emph{Softwares as a service} ou \emph{SaaSSaaS}, ce dernier point + Les \emph{Softwares as a service} ou \emph{SaaS}, ce dernier point nous concernant moins, puisque c'est nous qui développons le logiciel. \end{enumerate}