2009-05-22 12 views
14

Sono completamente nuovo in WCF. Ero abbastanza sicuro che avrebbe funzionato come i normali servizi web - e sono anche abbastanza sicuro che stavo facendo anche quello sbagliato, ma ora voglio assicurarmi che lo stia facendo bene.Utilizzo di WCF in un'applicazione ASP.Net e best practice

La nostra app ASP.Net si collega al servizio WCF su Internet. Ho una protezione di base implacabile e utilizzo di SSL. Funziona, ma è più lento rispetto a quando venivano eseguiti servizi web regolari. I dati restituiti sono fondamentalmente uguali a quelli del normale servizio web.

Quando utilizzavo il servizio web regolare, ogni volta che dovevo ottenere i dati, creavo un nuovo oggetto di servizio e chiamavo la funzione per i dati di cui avevo bisogno. Sembrava funzionare bene, ma, come immagino, non è il modo migliore di farlo, soprattutto se ci sono migliaia di utenti che si connettono allo stesso tempo. Quindi, quando mi sono convertito in WCF, ho deciso di mantenere aperto un client e di usarlo per tutti quelli che si connettono al sito. L'ho messo nella cache e quando la cache scaricava l'oggetto, avevo una funzione di callback per eliminarla.

Ora non ci ho nemmeno pensato fino a dopo aver cambiato tutto ciò che potrebbe rappresentare un problema per più persone che si connettono. Se la persona A richiede dati, la persona B deve aspettare che finisca prima che i dati vengano recuperati attraverso il servizio.

Quindi l'ho modificato in base alla sessione. Ho implementato questo errore o è semplicemente fallito perché non ha funzionato affatto. Il client si interrompe, causa un errore o semplicemente non funziona. L'ho cambiato di nuovo in cache per ora e sembra che funzioni bene (tranne che lentamente).

Che cos'è una "best practice" per questo scenario? Creo il client al volo quando è necessario, creo una sessione basata (e capisco cosa ho fatto di sbagliato), o la mantieni così com'è e utilizzo il metodo memorizzato nella cache di un client?

+0

+1. Buona domanda. – AnthonyWJones

risposta

6

Questo tipo di problema viene in genere risolto mantenendo un pool. Piuttosto che avere un solo oggetto di servizio in un estremo e uno per utente nell'altro estremo, il pool dovrebbe contenere una raccolta di oggetti di servizio necessari per supportare la domanda corrente dei propri servizi. Quindi la piscina dovrebbe crescere solo fino a un punto di massima richiesta.

Si assicurerà che gli oggetti vengano eliminati dal pool prima di qualsiasi altro timeout dall'interno dell'oggetto di servizio e si assicurano inoltre che vengano abbandonati se presentano qualsiasi tipo di eccezione.

In questo modo non si hanno più richieste client in attesa di accesso a un singolo oggetto, né si hanno oggetti inutilizzati in giro in un servizio e probabile morte per vecchiaia prima che possano essere riutilizzati comunque.

+1

Mai pensato di creare un pool di clienti. Questo potrebbe essere il meglio di entrambi i mondi. Non creare una tonnellata di oggetti al volo e anche non rallentare quando c'è molta attività. Grande idea! – TheCodeMonk

+0

Mi piace la tecnica menzionata, in qualsiasi modo potresti indicare alcune implementazioni di questo in modo da poter giocare? –

+0

Per quanto possa sembrare spaventoso, ho già una buona implementazione in questo. Ho intenzione di testarlo e se funziona come mi aspetto, scriverò un post su questo blog e documenterò cosa ho fatto. – TheCodeMonk

1

Generalmente creo un cliente al volo come hai detto, ma assicurati di smaltirlo al termine della richiesta. Ho risolto questo problema senza problemi, ma sinceramente non ho più di 1000 utenti che utilizzano lo stesso identico servizio allo stesso tempo.

Se si è interessati, è possibile trovare i dettagli esatti di implementazione nel post del blog this.

Giusto per chiarire qualcosa che hai menzionato nella domanda -quando dici "servizio web regolare", stai parlando di ASMX o?

+0

Sì, ASMX. La disposizione era la cosa che mi preoccupava di più. Penso di aver bisogno di fare un po 'di refactoring per pulire tutto questo. – TheCodeMonk

4

La practive migliore per i servizi WCF sarebbe quella di avere il modello a singola istanza per chiamata, quando possibile. Questo ti dà il miglior throughput, il comportamento migliore e più semplice nell'istanza del servizio. Quindi, quando possibile, e a meno che tu non abbia una ragione davvero convincente, usa questo modello.

Sembra che nel tuo caso, la creazione dell'istanza del servizio sia un'operazione piuttosto costosa. Forse è necessario ripulirlo in qualche modo: rendere l'istanza di servizio effettiva molto snella e leggera in modo che possa essere creata e smaltita in un batter d'occhio (o meno) e quindi avere alcuni processi di background worker (o eventualmente un pool) di quelli, come suggerito da Anthony) che puoi quindi chiamare dalle tue istanze di servizio reali.

Marc

Problemi correlati