Domanda

Sto lavorando ad un'applicazione ASP.net scritta in C # con il database SQL Server 2000. Abbiamo diversi report PDF che i clienti utilizzano per le loro esigenze aziendali. Il problema è che questi rapporti richiedono del tempo per generare (> 3 minuti). Ciò che di solito accade quando l'utente richiede al report il timeout della richiesta interrompe la richiesta prima che il server Web abbia il tempo di terminare la generazione del report, in modo che l'utente non abbia mai la possibilità di scaricare il file. Quindi l'utente aggiornerà la pagina e riproverà, il che avvia l'intero processo di generazione del report e finisce ancora con il timeout. (No, non stiamo memorizzando nella cache i rapporti in questo momento; è qualcosa che sto spingendo duramente per ...).

Come gestite questi scenari? Ho un'idea nella mia testa che prevede di effettuare una richiesta asincrona per avviare la generazione del report e quindi disporre di javascript per controllare periodicamente lo stato. Una volta che lo stato indica che il rapporto è terminato, fai una richiesta separata per il file effettivo.

C'è un modo più semplice che non vedo?

È stato utile?

Soluzione

L'uso del filesystem qui è probabilmente una buona scommessa. Richiedi una richiesta che restituisca immediatamente un URL alla posizione pdf del rapporto. Il server può quindi avviare un processo esterno o inviare una richiesta a se stesso per eseguire il reporting. Il client può eseguire il polling del server (utilizzando http HEAD) per il PDF nell'URL fornito. Se si fa derivare il nome file del PDF dai parametri del report, utilizzando un hash o inserendo direttamente i parametri nel nome, si otterrà anche la memorizzazione nella cache lato server istantanea.

Altri suggerimenti

Vorrei prendere in considerazione l'idea di rendere questo rapporto in qualche modo un po 'più offline dal punto di vista dell'elaborazione.

Come creare una coda in cui inserire richieste di report, elaborare i report da lì e dopo aver finito, può inviare un messaggio all'utente.

Forse avrei persino creato un servizio Windows separato per la gestione delle code.

Aggiornamento: l'invio all'utente può essere e-mail o possono avere una pagina "rapporti", in cui possono controllare lo stato dei loro rapporti e scaricarli se sono pronti.

I tuoi utenti potrebbero non accettare questo approccio, ma:

Quando richiedono un rapporto (facendo clic su un pulsante o un collegamento o qualsiasi altra cosa), puoi avviare il processo di generazione del rapporto su un thread separato e reindirizzare l'utente a una pagina che dice "grazie, il tuo rapporto ti verrà inviato via email entro pochi minuti " ;.

Quando il thread ha generato il report, è possibile inviare direttamente il PDF tramite e-mail (probabilmente non funzionerà a causa delle dimensioni) oppure salvare il report sul server e inviare tramite e-mail un collegamento all'utente.

In alternativa, puoi andare su IIS e aumentare il timeout su > 3 minuti.

Ecco alcune delle cose che farei se mi venisse presentato questo problema:

1- Ferma quei timeout! Sono uno spreco totale di risorse. (visualizza il valore di timeout delle pagine asp)

2- Centralizza tutto l'accesso db in un unico punto, quindi raccogli le statistiche su quali rapporti sono stati eseguiti da chi e quanto tempo ha impiegato. Scopri perché ci vuole così tanto tempo, è a causa della complessità del rapporto? intervallo di dati? carico del server? (potresti effettivamente scriverlo su un file .csv sul server e importarlo periodicamente nel server sql per analizzarlo in seguito).

Alla fine, sarà più facile per te " cache " segnala se si passa attraverso questo singolo punto di accesso (ad esempio, la stessa query stessa data restituirà lo stesso PDF precedentemente generato)

3- So che questa non era davvero la domanda, ma hai provato ad approfondire quelle domande per capire perché sono così lunghe da correre? Ottimizzazione delle query forse?

4- E-mail / SMS / messaggio sullo schermo quando il report è pronto sembra ottimo ... se l'utente in genere invia un batch di report da generare, forse un piccolo pannello che indica l'avanzamento di " loro " la coda potrebbe essere costruita nell'app. Un piccolo controllo Ajax aggiorna periodicamente lo stato.    Suggerimento: se hai utilizzato l'accesso centralizzato al database e disponi di informazioni sufficienti su ciò che viene eseguito quando e perché, alla fine sarai in grado di stimare approssimativamente il tempo necessario per l'esecuzione di un rapporto.

Se il tempo di risposta è di importanza critica, alcuni utenti dovrebbero essere limitati nell'intervallo di dati (intervallo di date ad esempio) durante alcune ore del giorno?

Buona fortuna e pubblica maggiori dettagli sul tuo scenario se vuoi ottenere suggerimenti più precisi ...

L'ottimizzazione delle query è probabilmente il miglior punto di partenza. Anche se non so che stai generando il rapporto, questo passaggio non dovrebbe richiedere così tanto tempo. D'altra parte, una query con prestazioni scarse potrebbe assolutamente uccidere la tua performance.

A seconda di ciò che si trova osservando la query, potrebbe essere necessario aggiungere alcuni indici o eventualmente impostare una tabella per archiviare le informazioni per il report in modo denormalizzato, per renderlo disponibile più velocemente. Questa tabella denormalizzata potrebbe quindi essere aggiornata (tramite un processo di SQL Server) ogni ora o con qualsiasi frequenza dettata dai requisiti (entro limiti ragionevoli).

Se si tratta di un report relativamente statico, senza variare i parametri di input dell'utente, anche la memorizzazione nella cache del report eseguito all'inizio della giornata sarebbe una buona idea, ma è difficile dire altro al riguardo senza conoscere la propria situazione.

Per un problema come questo è davvero necessario iniziare dal database a meno che non si abbia motivo di sospettare che il proprio report generi codice di essere il colpevole. Esistono vari cerotti che potresti usare per un po ', ma se il tuo db è la causa principale, quelle soluzioni non si ridimensioneranno bene e probabilmente incontrerai problemi simili (o peggio) in futuro .

Che dire di inviare il rapporto via e-mail all'utente. Tutto ciò che la pagina ASP dovrebbe fare è inviare la richiesta per generare il rapporto e restituire un messaggio che il rapporto verrà inviato via email una volta terminata l'esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top