ASP.NET 2.0: Performance e Scalabilità Giuseppe Guerrasio Architect, Microsoft "If you're very lucky, performance problems can be fixed after the fact. But, as often as not, it will take a great deal of effort to get your code to where it needs to be for acceptable performance. This is a very bad trap to fall into. At its worst, you'll be faced with a memorable and sometimes job-ending quote: 'This will never work. You're going to have to start all over.'" Rico Mariani – Enterprise Architect -Microsoft Corp Un Approccio Tipico Al Problema Code&Pray Approccio purtroppo comune sia per architetti che sviluppatori Scrivere il codice e sperare che soddisfi i requisiti Problema esclusivo della Tecnologia ovvero scala “by design” Test limitati alle funzionalità Confusione fra velocità di risposta e scalabilità Nessuna idea formalizzata su tempi di risposta e carichi richiesti Attenzione minima al problema in fase di design e codifica Eventuali problemi si sistemeranno dopo Al limite basta aggiungere Hardware Causa principale dell’aumento dei costi nei progetti Aumento Hardware Modifiche in corsa all’architettura Funzionalità critiche riscritte su architetture diverse , disomogeneità Aumento dei costi e complessità di gestione Un Approccio Completo e Sistematico Performance e Scalabilità sono quasi sempre un elemento reale di risk management Decidere subito l’importanza nel progetto Inserire la problematica all’interno del ciclo di sviluppo Definire parametri chiari e misurabili Stabilire momenti di verifica sull’architettura selezionata Amministrare il rischio come in tutti gli altri aspetti critici Validare al più presto l’architettura con dei test Inserire Test su funzionalità e nel complessivo Permette di Risparmiare denaro Aumentare le possibilità di successo Evitare le scorciatoie fuori architettura per funzionalità critiche Ridurre i tempi di sviluppo Definizioni Principali:Evitare Confusione Performance Relative all’ottenimento di tempi di risposta, throughput, e utilizzo delle risorse di sistema in accordo con le esigenze/obiettivi Response Time Tempo di risposta percepito dal chiamante nell’utilizzo di una fuzionalità Throughput Richieste eseguite nell’unità di tempo Scalabilità Capacità di mantenere costanti le performance al crescere del carico attraverso l’eventuale tuning ed eventuale aggiunta di risorse hardware Identificare , Documentare e Pianificare Identificare il Target Il carico può essere genericamente determinato dai dati Marketing Utenti Potenziali, Utenti concorrenti ed Utenti Attivi Volumi di Transazioni, Concorrenza tra Letture/Scritture,Attenzione ai Picchi Stabilire dei Livelli di Service Level Agreement Tempi di Risposta, Carichi, Occupazione di risorse, Throughput Problema condiviso da tutte le figure coinvolte nel progetto Definire Scenari per l’implementazione dei Test Test su singole funzionalità e sul complessivo Test affiancati ai testi di funzionalità Load Testing, Stress Testing, Capacity Testing Monitoraggio continuo delle risorse in produzione Valutare le risorse ancora disponibili Anticipare i Blocchi per esaurimento risorse Pianificare i meccanismi di Scalabilità Differenti Livelli di Impatto Design Coupling e Cohesion Communication Concurrency Resource Management Caching e State Management Data Structure / Algorithm Tuning Network System Platform Application La piattaforma: ASP.NET 2.0 Semplificare lo sviluppo di applicazioni Web Nuovo ambiente di sviluppo Riduzione del codice Plumbing del 50% + di 40 nuovi controlli Master Page, Temi e Skin Estendibilità : Modello a Provider “Ovunque” Framework per Membership, Profile, Role Canale di rendering verso Host riscritto (IIS) Nuovo modello di compilazione e deployment Dynamic compilation, Pre-compilation, Build Provider ASP.NET page lifecycle migliorato Call backs, cross-page post Pagine Asincrone Evoluzione nelle fondamenta Obiettivi: Long-Term: rendere le performance del CLR simili al codice nativo Short-Term: Riduzione startup time e working set, aumento performance e affidabilità Enhanced tool: NGen Nuove Interfacce di Hosting API Esistenti Migliorate Cross AppDomain Remoting: 200x veloce AppDomain Footprints: 20% in meno Interface/Delegate chiamata: 2x veloce UTF8Encoding: translation è 2.5x veloce Reflection working set migliorato Nuovo Gestore per le Transazioni : System.Transaction Nuove, API APIs per resource lookup Reflection migliorata Lightweight CodeGen Visual Studio Team Edition Visual Studio Team Edition Visual Studio Team Edition Software Architects Software Developers Software Testers Application Designer Dynamic Code Analyzer Load Testing System Designer Static Code Analyzer Manual Testing Logical Datacenter Designer Code Profiler Test Case Management Deployment Designer Unit Testing Code Coverage Class Designer (in Visual Studio Standard Edition and higher) Visio for Enterprise Architects (in MSDN Premium Subscription) Team Explorer (includes Team Foundation Server CAL) Visual Studio Professional Edition Visual Studio Team Foundation Server Change Management Reporting Integration Services Team Build Work Item Tracking Project Portal Project Management Visual Studio Industry Partners Process and Architecture Guidance Visual StudioTeam System Importanza delle “Piccole” scelte Ogni scelta anche a livello di codifica ha un impatto sulle performance Ad esempio non tutti considerano che: Scelta del corretto contenitore in base all’utilizzo: Array, Collection, Utilizzo corretto delle stringhe Sealed sui metodi virtual quando non occorre override ulteriore Corretto utilizzo ByRef ByVal DataBinding ASP.NET e problematiche di casting Etc, etc , etc Sensibilizzare i Developer Lead sulla problematica Revisione continua del codice durante i Test Attenzione ai processi di revisione “infinita” Il “Poster” per L’Architetto Problematiche di Design Principali Cause di Degradazione Performance e Scalabilità in ASP.NET Operazioni Lente/Bloccanti Utilizzo errato Thread Resource Affinity / State Management Gestione “allegra” del view state Eccessiva Allocazione Memoria Errori nella condivisione di Risorse Utilizzo errato COM Interop Caching Errato o Mancante Gestione della Concorrenza sui dati Gestione Long Running Task Sincrono è bello ma... Asincrono è meglio Asincrono ?? Si perdono i dati !!!! Mancanza di cultura per questo aspetto Gestione di più Task Paralleli Abbiamo il Free Threading , usiamolo Nel CLR e in ASP.NET funzionalità specifiche per questo tipo di gestione: Begin... / End.... Pattern Sfruttamento delle I/O Completion Port Handler Asincroni, Moduli Asincroni Attenzione : Non tutto ha senso come meccanismo asincrono Miglioramenti significativi e nuove funzionalità con ASP.NET 2.0 Percezione sulla User Interface Avvisare l’utente Evitare le interfacce a clessidra.... Gestire i “click selvaggi” Esecuzione Chiamata Esterna Esecuzione sincrona su web server Avvio page processing Chiamata Web Service Prende un thread dal thread pool Web Service Fine Chiamata Web Service Continua page processing Ritorna il thread nel thread pool Esecuzione Chiamata Esterna Esecuzione sincrona su web server Richieste in esecuzione su un Thread: thread #1 thread #2 thread #3 thread #N Richieste in Coda: Tutti i thread possono essere impegnati nel processamento di una pagina che effettua I/O Esecuzione Chiamata Esterna Esecuzione asincrona sul web server Avvio pagina chiamata al Web Service Web Service Prende un thread dal thread pool Ritorna il thread nel thread pool In attesa della risposta nessun Thread viene bloccato Prende un thread dal thread pool Chiamata Web Service Completata continua page processing Ritorna il thread nel thread pool Esecuzione Chiamata Esterna Esecuzione asincrona su web server Richieste in esecuzione su thread: thread #1 thread #2 thread #3 Molti thread disponibili per eseguire nuove richieste. No thread bloccati thread #N No richieste in coda: Richieste in waiting per completamento senza thread bloccati: API Asincrone nel .NET Framework asynchronous pattern introdotto in v1.0 Metodi Begin/End Il metodo Result Method(params) diventa: IAsyncResult BeginMethod(params, callback, state) Result EndMethod(IAsyncResult) Implementato da molti .NET component System.IO e System.Net Delegates: BeginInvoke/EndInvoke Web Service proxy SQL Client (in ADO.NET v2.0) Utilizzo delle I\O completation port API Asincrone nel .NET Framework nuovo event-based pattern introdotto in v2.0 API Basate su Eventi Result Method(params) : void MethodAsync(params) event MethodCompleted MethodCompletedEventHandler MethodComplatedEventArgs ha le Result property Modello semplificato no (IAsyncResult / AsyncCallback) Implementato da Web Service proxy v2.0 API Asincrone in ASP.NET v1.x pagine sincrone, supporto handler asincroni In ASP.NET v1.x le pagine sono sincrone. Le operazioni I\O sono bloccanti. ASP.NET v1.x supporta meccanismi asincroni via IHttpAsyncHandler. Consente l’esecuzione di chiamate asincrone Non è possibile sfruttare il framework delle pagine ASP.NET Esecuzione asincrona tramite la pipeline di eventi HTTP runtime asincroni (Begin, End). Utilizzabile via GLOBAL.ASAX o HTTP Module. Pagine Asincrone in ASP.NET v2.0 <%@ page async="true" %> Le pagine asincrone implementano automaticamente IHttpAsyncHandler ‘Asynchronous point’ nel ciclo di vita della pagina prima dell’evento PreRenderComplete Tutte le operazoni asincrone sono avviate prima dell’asyncpoint e “agganciate” Durante l’esecuzione delle parti asincrone l’esecuzione della pagina è sospesa ed il worker thread liberato L’esecuzione della pagina riprende al termine dell’ultima chiamata asincrona Compatibile con entrambe le opzioni di pattern asincroni di .NET event-based e asynchronous API patterns ASP.NET v2 Page Framework Async Page Lifecycle GET/ POST Initialize Load Load State and Post Data Raise Changed Events Postback Event Async Point: Sospensione della pagina Pre-render OnPreRenderComplete Save State Render Unload Domanda Ricorrente Come faccio a sincronizzare più chiamate asincrone rispetto alI’AsyncResult principale ? Page Async Task in ASP.NET v2.0 Pagine con chiamate multiple <%@ Page Async="true"AsyncTimeout="5" %> Consentono la gestione di task asincroni e l’impostazione di handler per la gestione del timeout Usano il framework asynchronous pattern, ma: Risolvono con semplicità la necessità di combinare IAsyncResult di task paralleli Permettono il flow di impersonazione, culture, HttpContext.Current sia nell’end handler che nel timeout Handler Funzionano anche in pagine (blocking page thread) I Task possono essere anche eseguiti su richiesta con Page.ExecuteRegisteredAsyncTasks Tecniche Ulteriori Submit & Poll Disconnette completamente il chiamante fino ad avvenuta operazione Il Client sottomette una richiesta che viene identificata Consigliabile per operazioni estremamente lente Più semplice in uno scenario Smart-Client altrimenti utilizzare script ad esempio Ricaricamento periodico della pagina Script Asincroni per i Web Service In ASP.NET 2.0 semplificato dalla presenza delle CallBack native sulla pagina Code Messaggi 1 -Invio del Long Task Con specifico GUID univoco 3 – Ritorno al client – Polling fino a determinazione risposta 2 – Accodamento della richiesta 4 – Esecuzione e scrittura risposta su DB La Gestione della Sessione Elemento critico nella scalabilità Ridurre al minimo l’utilizzo o addirittura eliminarla ASP.NET consente l’utilizzo di storage condivisi per la sessione InProc, State Service, Database Il database va inizializzato Lo State Server di default funziona solo da localhost, modificare le chiavi seguenti per porta e accesso da remoto HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\asp net_state \Parameters\Port=PORT HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\asp net_state \Parameters\AllowRemoteConnection=1 Nuovo modello per la sessione nella v.2.0 Architettura flessibile , Modello a Provider Granularità nella possibilità di estensione La Gestione della Sessione Suggerimenti per la Sessione Disabilitare la sessione dalle pagine che non la utilizzano o impostarla sul corretto livello (read only) <%@ Page EnableSessionState="False|ReadOnly" %> Possibile anche attraverso il Web.config in <system.web>: <pages enableSessionState="false|readnoly" /> Per implementare la sessione su Handler Attenzione ai meccanismi di serializzazione, evitare l’utilizzo di oggetti complessi Possibile sostituzione attraverso il meccanismo a Provider di parte delle componenti della sessione ad esempio Sostituzione dell’IDGenerator per gestire richieste che non necessitano nemmeno dell’ID della Session, eliminiamo round trip per verifica id <sessionState sessionIDManagerType=“typename"/> La sessione può diventare un collo di bottiglia perchè appoggiata su un unico storage, possibile partizionarla con <sessionState mode="StateServer" partitionResolverType= “typename" /> Gestione del View-State Funzionalità utile ma con impatto significativo Forte semplificazione di sviluppo Aumento significativo della dimensione della pagina Approccio tipico tutto o niente Alcuni eventi sui controlli non funzionano più se disabilitiamo view-state Nella versione 2.0 miglioramenti significativi Nuovo algoritmo per il view-state con miglioramento significativo della dimensione Separazione tra stato e contenuto del controllo (viewstate control-state) Controlli ed eventi a funzionalità completa anche senza view-state Ricaricamento dei dati “intelligente” Gestione Avanza dei Lock Nello sviluppo asincrono e multithread in generale i lock assumono una importanza rilevante In molti scenari possono diventare un freno alle performance Tipico esempio la sincronizzazione di una risorsa esclusiva tra letture e scritture Funzionalità offerte dal framework per le collection Ottimo supporto nell’accesso da codice managed per l’accesso alle funzionalità del Windows Kernel ma Switch di contesto con prezzo da pagare In caso di elevata concorrenza nelle letture rispetto alle scritture alto costo di performance Possibili tecniche alternative per evitare l’utilizzo delle funzionalità Kernel o ridurle al minimo In v2.0 entra in gioco lo SpinWait Gestione Avanzata dei Lock Test Time per 200,000,000 Operazioni (secondi) Kernel Mode Metodo Vuoto 1.0 No Thread.SpinWait(1) 2.4 No Interlocked.Increment(Int32 ) 2.8 No SwitchToThread() 73.0 Yes Thread.Sleep(0) 115.2 Yes WaitHandle.WaitOne(0, false) 328.2 Yes Gestione Avanza dei Lock Tecniche di Interlocked like I metodi Interloked funzionano in user mode Limitati all’utilizzo su strutture Estendere la tecnica del loro funzionamento a operazioni più complesse public void Push(int elem) { ListNode newNode = new ListNode(); newNode.elem = elem; ListNode origHead; do { origHead = head; newNode.next = origHead; } while (CompareExchange<ListNode> ( ref head, newNode, origHead) != origHead); } Tecniche di SpinLock utili per alta concorrenza per l’acquisizione dei lock No switch in kernel mode SpinWait sul Thread Nuova funzionalità offerta da .NET v2.0 Effettua un wait senza switch in Kernel Mode Specificatamente pensata per ambienti multiprocessore HyperThreading Gestione del Caching Funzionalità fondamentale per ottenere performance elevate Sfruttare tutti i livelli di caching Non esiste solo la cache del server Non dimenticare il browser client ed i proxy Effettuare il caching solo degli elementi che hanno più senso ovvero : condivisi da più utenti Cache Per-Request con la collezione Items l’oggetto di contesto Caching per utente senza affinità inutile a meno di utilizzo del browser client Innovazione e potenziamento del Caching nella versione 2.0 Gestione del Caching Nuove Funzionalità offerte dal caching Cache Profile Permette di stabilire profili differenti attraverso Keyword che possono essere inserite nei .config e dal li modificati per tutte le pagine che li utilizzano Custom Cache Dependency Implementata ereditando da CacheDependency SqlCacheDependency Nuova e potente funzionatà offerta dalle SQLNotification e SqlDependency Può lavorare in polling o via notifica Validation Callback Fornisce la possibilità di registrare un proprio Handler di tipo HttpCacheValidateHandler per effettuare in modo custo la validazione della cache Post-Cache Substitution Oltre alla fragmentation cache via controlli permette di sostituire una parte dell’output sottoposto a caching Miglioramenti Miglioramento allo Scavenging Miglioramenti alla cache fragmentation via control SqlDependency SqlDependency utilizza la QP Notification per generare un evento client side quando il risultato cambia Si Registra con un runtime listener alla creazione Listener per HTTP o TCP Può essere associato a uno o più commandi Crea un SqlNotificationRequest dietro le quinte Specifica il routing per il messagio e la default message queue Espone un OnChanged Event Notification Dispatcher scatena la notifica dal database Attivato all’arrivo di Msg in coda Usa le informazioni del messaggio per determinare la destinazione Response caching con data invalidation Anche le ASP.NET Response possono essere dipendenti dai dati nel database Explicita associazione SqlCacheDependency(s) con Response Response.Cache.SetExpires(DateTime.MaxValue); SqlDataAdapter adapt = getDataAdapter(); SqlCacheDependency cacheDep = new SqlCacheDependency(adapt.SelectCommand); adapt.Fill(ds); Response.AddCacheDependency(cacheDep); O Specificare la parte con la page directive <%@ OutputCache Duration=3600 VaryByParam=“none” SqlDependency=“database/table name pair | CommandNotification" %> Response Caching In ASP.NET <% @ OutputCache Duration=3600 VaryByParam=“none” SqlDependency= “CommandNotification” %> Products Execute() Change Detection SqlCommand SqlCommand ASP.NET Application/ WebService IIS Http.Sys Response Cache Middle Tier Execute() Notification Delivery Service SSB Database Server Object caching con data invalidation Gli oggetti inseriti in Cache possono essere invalidati in base al meccanismo analizzato di Notifica e quindi essere dipendenti dalla porzione di database associata Usa la nuova classe SqlCacheDependency Supporto QP Notification Command nel costruttore Crea una SqlDependency dietro le quinte Supporta il polling per pre-MSSQL2005 database Specificare database e tablename nel costruttore Caching information aggiunte al web server configuration file DataSet ds = (DataSet)Cache[ProductID]; if (null==ds) { ds = new DataSet(); SqlDataAdapter adapt = getDataAdapter(); SqlCacheDependency cacheDep = new SqlCacheDependency(adapt.SelectCommand); adapt.Fill(ds); Cache.Insert(ProductID, ds, cacheDep); } Preparare l’ambiente Usare Aspnet_regsql.exe per prepare il db se di versione precedente a Sql 2005 e poi entry in Web.config aspnet_regsql -S localhost -E -d Northwind -t Products -et <configuration> <connectionStrings> <add name="Northwind" connectionString="server=localhost;database=northwind;..." /> </connectionStrings> <system.web> <caching> <sqlCacheDependency enabled="true" pollTime="5000"> <databases> <add name="Northwind" connectionStringName="Northwind" /> </databases> </sqlCacheDependency> </caching> <system.web> </configuration> Riepilogo Le Performance e la Scalabilità sono un requisito fondamentale nello sviluppo del software L’Hardware non è tutto e non risolve tutti i problemi Visual Studio Team System fornisce un insieme di strumenti per il Test del codice Windows 2003 e ASP.NET 2.0 offrono un ottima base di partenza ma non possono fare miracoli Conoscere la tecnologia per sfruttarla correttamente Considerare questo aspetto in tutto il ciclo di vita dall’Architettura al Mantenimento in esercizio Bilanciare correttamente con le altre caratteristiche di QoS Ogni scelta deve essere ponderata sugli obiettivi prefissati Pianificare la scalabilità Testare l’Architettura anche in fase di Design per determinare i colli di Bottiglia architetturali In ogni dove: Testing, Testing, Testing , Tuning , Tuning, Tuning © 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary. COM Interop Gestire il referencecounting Ricordarsi del GC (Garbage Collector) Utilizzare sempre le Dispose Chiamare sempre Marshal.ReleaseCOMObject Ridurre al minimo l’interazione con l’interfaccia COM Eventualmente accorpare con componenti facciata Attenzione alle strutture troppo pesanti Attenzione ai Modelli di Threading Applicare il parametro ASPCOMPAT per i componenti STA Valutare l’impiego di tecniche di Web Garden e/o Application Pooling COM+ in caso di utilizzo intensivo di componenti STA o comunque tecniche Multi-Processo NO STA IN SESSION O APPLICATION Gestione della Concorrenza Scegliere il giusto livello di Isolamento per le transazioni Attenzione alla concorrenza tra letture e scritture Usare gli HINT nel caso di SQL Leggere fette limitate di dati Attenzione alla durata delle transazioni bloccanti Concorrenza Pessimistica Uccide la scalabilità Utilizzarla solo se indispensabile Supportata in ADO.NET con la transazione SELECT * FROM Customers WITH(UPDLOCK) WHERE CustomerId='ALFKI' Tecniche alternative: Concorrenza Ottimistica Campi originali in WHERE, Timestamp Tecniche di compensazione Lock personalizzato con campi di concorrenza aggiunti alla tabella Novità in ADO.NET 2.0 e SQL 2005 Paginate Gente, Paginate Selezionare solo i dati di cui l’utente ha realmente bisogno Raramente è utilizzabile un cursore con >100 record Forzare l’utente ad utilizzare criteri di ricerca stringenti Paginazione dei dati SQLServer TOP n, SET MAXROWS Paging via Ordinal range (i.e., records 91-100) SELECT TOP 10 * FROM (SELECT TOP 100 ProductName, UnitPrice FROM Products ORDER BY UnitPrice ASC) AS Products ORDER BY UnitPrice DESC Paging via value range (i.e., M-N) SELECT TOP 10 ProductName, UnitPrice FROM Products WHERE ProductName > @PreviousName ORDER BY ProductName ASC AS Products Altri elementi di Attenzione Controllo delle Eccezioni Attenzione all’impersonazione Abilitare il Buffering quando ha senso Attenzione a Redirect e Transfer Validazione Client-Side SEMPRE Monitoring ASP.NET Attività continua in tutti i tipi di testing ed in produzione Monitoring continuo di Response time e latenza Throughput Utilizzo delle risorse Strumenti Dati dai test System Monitoring (Performance Monitor, Event Viewer, etc) Microsoft Operation Manager Clr Profiler Tool Monitoring traffico di rete es Network Monitor Nel caso di utilizzo di Sql Server indispensabili SQL Profiler SQL Query Analyzer Intrumentare l’applicazione Tracing, Performance Counter, Logging Parametri tipici da Monitorare Sistema Processore Processor% Processor Time% Privileged TimeSystemProcessor Queue Length Context Switches/sec Memoria Available MBytes Page Reads/sec Pages/sec I/O Dischi Avg. Disk Queue Length Avg. Disk Read Queue Length Avg. Disk Write Queue Length Avg. Disk sec/Read Avg. Disk sec/Transfer Disk Writes/sec I/O Rete Network InterfaceBytes Total/sec Bytes Received/sec Bytes Sent/sec Parametri tipici da Monitorare ASP.NET Worker Process ASP.NET\Worker Process Restarts Throughput ASP.NET Applications\Requests/Sec Web Service\ISAPI Extension Requests/sec Requests ASP.NET\ Requests Current ASP.NET Applications\Requests Executing ASP.NET Applications\ Requests Timed Out Response time / latency ASP.NET\ Request Execution Time CLR Process\Private Bytes .NET CLR Memory\% Time in GC .NET CLR Memory\# Bytes in all Heaps .NET CLR Memory\# Gen 0 Collections .NET CLR Memory\# Gen 1 Collections .NET CLR Memory\# Gen 2 Collections .NET CLR Memory\# of Pinned Objects .NET CLR Memory\Large Object Heap size NET CLR Exceptions\# of Exceps Thrown /secContention NET CLR LocksAndThreads\Contention Rate / sec .NET CLR LocksAndThreads\Current Queue Length Un “Poster” per il Tuning ASP.NET Consigli su Configurazione In alcuni casi le configurazioni di base sono inadeguate Configuration setting Default Valore Raccomandato maxconnection 2 12 * #CPUs maxIoThreads 20 100 maxWorkerThreads 20 100 minFreeThreads 8 88 * #CPUs minLocalRequestFreeThreads 4 76 * #CPUs Solo una base di partenza per il tuning Ridurre la Contesa su risorse Consigli su Configurazione Separare ASP e ASP.NET in Application Pool diversi Rimuovere tutti i servizi non utilizzati Attenzione ai parametri del Web Config Debug e Trace a false Eliminare i moduli non necessari Impostare Time- Out aggressivi Configurare in modo aggressivo i Time-Out Valutare l’utilizzo della compressione Utilizzare il Pinging per Monitorare ed utilizzare le Action per Riciclare i processi che non rispondono Restart Ciclico Applicazioni In base al parametro migliore Num Richieste Inattività UpTime Memoria Utilizzare se possibile l’Overlapping altrimenti incrementare le dimensioni code, attenzione al consumo di memoria