7 Tecniche di debug per accelerare la risoluzione dei problemi in produzione
Pubblicato: 2022-03-11Fornire supporto di produzione a un'applicazione è uno degli aspetti più impegnativi dello sviluppo del software. Gli sviluppatori vengono assegnati al team di manutenzione e lavorano alla correzione dei bug sull'applicazione. Tuttavia, sono disponibili anche su chiamata in caso di interruzione della produzione, nel qual caso lavorano per riportare l'applicazione in pista il più rapidamente possibile.
Questo articolo mira a fornire una serie di consigli curati in modo da poter prevenire i bug in produzione e trovare i problemi molto più rapidamente. La gestione di queste applicazioni in produzione è un compito complicato: spesso non è disponibile documentazione, l'applicazione è stata scritta in uno stack tecnologico legacy o entrambi. Ci sono pochissime sessioni di formazione ed è comune essere chiamati a fornire supporto per un'applicazione di cui si conosce poco.
Molti sviluppatori non hanno esperienza nella gestione di un'applicazione in produzione. C'è una serie di problemi che si verificano negli ambienti di produzione che causano bug e interruzioni, causando generalmente migliaia e talvolta milioni di dollari di mancato guadagno per l'azienda. Inoltre, poiché la maggior parte degli sviluppatori non è esposta all'ambiente, continua a commettere alcuni errori che, a loro volta, causeranno tali problemi. Questo elenco di suggerimenti dovrebbe rendere il tuo lavoro meno doloroso insegnando dall'esperienza di produzione.
Suggerimento n. 1: rimuovere o automatizzare tutta la configurazione necessaria per l'esecuzione dell'applicazione.
Quanta configurazione è necessaria per installare il software su un nuovo server? In passato, a volte il completamento dell'operazione poteva richiedere tre giorni ogni volta che c'era un nuovo sviluppatore nel team. L'installazione dell'applicazione richiederebbe molti passaggi che devono essere eseguiti manualmente. Nel tempo, il software evolve verso nuove versioni che diventano incompatibili con tali istruzioni e, naturalmente, le istruzioni di solito non vengono aggiornate. Improvvisamente, stai spendendo molto più tempo del necessario semplicemente per far funzionare l'applicazione.
Con l'avvento della containerizzazione, è diventato molto più semplice fornire un modo per far funzionare un'applicazione in pochissimo tempo, con configurazione zero e con l'ulteriore vantaggio che, poiché l'immagine Docker è autonoma, si esegue un rischio di incorrere in problemi con diverse versioni del sistema operativo, linguaggi e framework utilizzati.
Allo stesso modo, semplifica la configurazione degli sviluppatori, quindi non ci vuole molto tempo per essere installato e funzionante, inclusa la configurazione dell'IDE. Uno sviluppatore dovrebbe essere in grado di passare da zero a eroe in meno di 30 minuti.
Quando si verifica un problema di produzione, a volte i tuoi migliori esperti potrebbero non essere disponibili (ad es. ferie o malattia) e desideri che chiunque ti occupi del problema sia in grado di risolverlo e rapidamente.
Suggerimento n. 2: non cadere nella trappola della zuppa di stack tecnologico.
Meno tecnologie utilizzate, meglio è. Naturalmente, a volte, devi usare lo strumento giusto per il lavoro. Tuttavia, fai attenzione a non sovraccaricare gli "strumenti giusti". Anche l'acqua potabile può causare seri problemi di salute se la usi troppo. Ogni nuovo linguaggio e framework aggiunto allo stack tecnologico deve seguire un processo decisionale chiaramente definito con un'attenta considerazione degli impatti.
- Non aggiungere una nuova dipendenza dal framework solo perché hai bisogno di una classe
StringUtils
. - Non aggiungere una lingua completamente nuova solo perché devi scrivere uno script rapido per spostare i file.
Una grande pila di dipendenze può rendere la vita infelice quando le librerie diventano incompatibili o quando vengono rilevate minacce alla sicurezza nei framework stessi o nelle loro dipendenze transitive.
Inoltre, ricorda, le complessità dello stack aggiunte rendono difficile trovare e formare nuovi sviluppatori per il team. Le persone passano a nuovi ruoli in altre aziende e tu devi trovarne di nuovi. Il fatturato è molto alto nei team di ingegneri, anche in aziende riconosciute per avere grandi vantaggi e prelibatezze per l'equilibrio tra lavoro e vita privata. Vuoi trovare il nuovo membro del team il più rapidamente possibile. Ogni nuova tecnologia aggiunta in cima allo stack tecnologico aumenta il tempo per trovare un nuovo candidato e ha il potenziale per rendere le nuove assunzioni sempre più costose.
Suggerimento n. 3: la registrazione deve guidarti a trovare il problema, non affogarti con dettagli inutili.
La registrazione è molto simile ai commenti. È necessario documentare tutte le decisioni critiche che vengono prese e tutte le informazioni da utilizzare nelle tecniche di debug. Non è semplice, ma con un po' di esperienza è possibile tracciare alcuni possibili scenari di interruzioni della produzione e quindi inserire la registrazione necessaria per risolvere almeno questo. Naturalmente, la registrazione si evolve insieme alla base di codice a seconda del tipo di problemi che si presentano. In generale, dovresti avere l'80% della tua registrazione sul 20% più importante del tuo codice, la parte che verrà utilizzata di più. Informazioni importanti, ad esempio, sono i valori degli argomenti passati a un metodo, i tipi di runtime delle classi figlie e le decisioni importanti prese dal software, ovvero il momento in cui si trovava a un bivio e ha scelto sinistra o destra.

Suggerimento n. 4: gestisci situazioni impreviste.
Tracciare molto chiaramente quali sono le ipotesi del codice. Se una determinata variabile deve sempre contenere i valori 2, 5 o 7, assicurati che sia di tipo enum, non int. La fonte numero uno di grandi interruzioni di produzione è quando una certa ipotesi fallisce. Tutti cercano il problema nel posto sbagliato perché danno alcune cose per scontate.
I presupposti dovrebbero essere documentati in modo esplicito e qualsiasi errore di tali presupposti dovrebbe generare allarmi sufficienti affinché il team di supporto alla produzione possa correggere rapidamente la situazione. Dovrebbe esserci anche un codice per impedire che i dati vadano in uno stato non valido o almeno per creare una sorta di avviso in quel caso. Se determinate informazioni devono essere archiviate in un record e improvvisamente ci sono due record, dovrebbe essere attivato un avviso.
Suggerimento n. 5: dovrebbe essere semplice replicare un problema che si verifica a un cliente.
Uno dei passaggi più difficili è sempre replicare il problema affrontato dal cliente. Molte volte, trascorrerai il 95% del tempo cercando di replicare il problema, quindi nel momento in cui puoi replicarlo, è questione di pochi minuti per correggere, testare e distribuire. Pertanto, l'architetto dell'applicazione dovrebbe assicurarsi che sia estremamente semplice e veloce replicare i problemi. Molto di questo accade perché, per arrivare alla stessa situazione in cui si trova il cliente, lo sviluppatore deve eseguire una quantità significativa di configurazione dell'applicazione. Ci sono molti record archiviati che insieme aggravano la situazione in cui si trova il cliente, il problema è che tu come sviluppatore devi indovinare esattamente cosa ha fatto il cliente. E a volte, hanno eseguito una sequenza di passaggi, di cui ricordano solo l'ultimo.
Inoltre, il cliente spiegherà il problema in termini commerciali, che lo sviluppatore deve poi tradurre in termini tecnici. E se lo sviluppatore ha meno esperienza con l'applicazione, non saprà chiedere i dettagli mancanti, poiché non conosce ancora nemmeno i dettagli mancanti. Copiare l'intero database di produzione sulla tua macchina non è fattibile. Quindi dovrebbe esserci uno strumento per importare rapidamente dal database di produzione solo i pochi record necessari per simulare la situazione.
Supponiamo che il cliente abbia un problema con la schermata Ordini. Potrebbe essere necessario importare alcuni dei loro ordini, il record del cliente, alcuni record di dettaglio dell'ordine, record di configurazione dell'ordine, ecc. Quindi puoi esportarlo in un database all'interno di un'istanza Docker, avviare quell'istanza e, proprio così, sei vedendo la stessa cosa che vede il cliente. Tutto questo, ovviamente, dovrebbe essere fatto con la cura adeguata per garantire che nessuno sviluppatore abbia accesso a dati sensibili.
Suggerimento n. 6: dovrebbe essere ovvio dove posizionare i punti di interruzione nell'applicazione.
Se hai una schermata Cliente, dovrebbe esserci un oggetto Cliente in cui puoi posizionare i punti di interruzione per eseguire il debug di un problema su quella schermata. A volte gli sviluppatori cadono nella febbre dell'astrazione e escogitano alcuni concetti incredibilmente intelligenti su come gestire gli eventi dell'interfaccia utente. Invece, dovremmo sempre fare affidamento sul principio KISS (Keep it Simple, St— er, Silly) e avere un metodo facilmente individuabile per ogni evento dell'interfaccia utente. Allo stesso modo, per i processi di elaborazione batch e le attività pianificate, dovrebbe esserci un modo semplice per individuare dove si trova il punto di interruzione per valutare se quel codice funziona o meno.
Suggerimento n. 7: assicurati che tutte le dipendenze esterne siano documentate in modo esplicito.
Idealmente, eseguire questa operazione nel file README all'interno del sistema di controllo del codice sorgente in modo che la documentazione non vada persa. Documentare qualsiasi sistema esterno, database o risorsa che deve essere disponibile per il corretto funzionamento dell'applicazione. Inoltre, annota quali di questi sono facoltativi e aggiungi istruzioni su come gestirli quando sono facoltativi e non disponibili.
Oltre le tecniche di debug
Una volta seguiti questi consigli durante la creazione di nuove funzionalità o la manutenzione di un sistema, il supporto alla produzione diventerà molto più semplice e la tua azienda spenderà molto meno tempo (e denaro). Come già sapete, il tempo è essenziale durante la risoluzione dei problemi di bug e arresti anomali della produzione: ogni minuto che può essere risparmiato fa una grande differenza in termini di risultati. Buona codifica!