Esplorazione di istanze, concorrenza e limitazione in WCF

Quando si lavora in WCF è necessario essere consapevoli dei concetti di istanza, limitazione e concorrenza per creare servizi scalabili e in grado di fornire una velocità effettiva migliore.

La limitazione in WCF viene utilizzata per limitare la velocità effettiva del servizio in modo che il consumo di risorse (memoria, processore, disco, rete e così via) nel sistema sia a un livello accettabile, ovvero garantire che il servizio non consumi risorse oltre i limiti accettabili. La classe ServiceThrottlingBehavior può essere utilizzata per controllare le prestazioni dei servizi WCF.

Concorrenza

In WCF, possono verificarsi problemi di concorrenza quando due o più thread tentano di accedere alla stessa risorsa contemporaneamente. Tieni presente che un servizio WCF può gestire una singola richiesta alla volta. La concorrenza in WCF consente di controllare più thread attivi in ​​un InstanceContext in un determinato momento. In sostanza, ti aiuta a configurare il numero di istanze di servizio che possono servire più richieste simultanee. I tre possibili tipi di modalità di concorrenza includono quanto segue:

Modalità concorrenza singola: in questa modalità ogni contesto di istanza può avere un massimo di un thread in grado di elaborare la richiesta in un determinato momento. Quando arriva la richiesta successiva, deve attendere il completamento della prima richiesta. Ciò comporta anche la necessità di blocchi di sincronizzazione. Il frammento di codice seguente illustra come utilizzare la modalità a concorrenza singola.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Single)]

servizio di classe pubblica: IServiceContract

{

     stringa pubblica GetMessage ()

     {

          return "Hello World!";

     }

}

Modalità simultanea multipla: in questa modalità, il servizio consente a più thread di accedere a un'operazione del servizio nello stesso momento. Nella modalità di funzionamento a più concorrenza, ogni servizio WCF ha più thread che a loro volta possono elaborare le richieste in ingresso contemporaneamente.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]

public class Service : IServiceContract

{

    readonly object lockObj = new object();

    public string GetMessage()

    {

        string message = string.Empty;

        lock (lockObj)

        {

             message = "Hello World!";

        }

        return message;

    }

}

Modalità concorrenza rientrante : nella modalità operativa rientrante, sebbene un singolo thread possa accedere all'oggetto servizio, il thread può comunque uscire dal servizio e quindi chiamare un altro servizio. Il frammento di codice seguente mostra come implementare questa modalità.

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]

public class Service : IServiceContract

{

     public string GetMessage()

     {

          return "Hello World!";

     }

}

La proprietà InstanceContextMode viene utilizzata per specificare quando verrà creata un'istanza del servizio e la sua durata. Si noti che sia InstanceContextMode che ConcurrencyMode vengono specificati utilizzando ServiceBehaviorAttribute. I tre valori della modalità contesto dell'istanza disponibili includono: PerCall, PerSession e Single. Nella modalità PerCall, il servizio è a thread singolo ed è senza stato. La modalità PerSession è l'impostazione predefinita e viene utilizzata quando si desidera mantenere le informazioni sullo stato tra le chiamate originate dallo stesso consumatore del servizio. La modalità singola viene utilizzata quando il servizio deve mantenere le informazioni sullo stato tra i client e non sarà necessario aumentare il livello del servizio in futuro.

Throttling

È possibile sfruttare la limitazione per controllare e ottimizzare l'utilizzo delle risorse e anche per ottenere un modo per bilanciare le prestazioni del servizio. La limitazione in WCF può essere configurata in modo dichiarativo e programmatico.

Puoi configurare le proprietà maxConcurrentCalls, maxConcurrentInstances, maxConcurrentSessions in modo dichiarativo utilizzando il tag nel file di configurazione del servizio come mostrato nello snippet di codice di seguito.

   

     

       

         

           

         

       

       

     

   

   

     

       

         

         

         

                                maxConcurrentInstances

                                maxConcurrentSessions/>

       

     

   

The maxConcurrentCalls property is used to limit the total number of calls across all the service instances. The default value is 16 per processor. The maxConcurrentInstances property is used to specify the total number of service instances that can be allocated at a particular point of time. The default value of this property is Int32.MaxValue. The maxConcurrentSessions property is used to specify the total number of concurrent active sessions that is permissible for a service at a given point of time. The default value is 100 per processor.

Now that we know how to configure service throttling in WCF declaratively, let’s explore how we can configure service throttling in WCF programmatically. To configure service throttling in WCF programmatically, you would need to take advantage of the ServiceThrottlingBehavior class. The following code listing shows how you can take advantage of the ServiceThrottlingBehavior class to configure the concurrent calls, session and instance properties.

ServiceHost serviceHost = new ServiceHost(typeof(Service));

           ServiceThrottlingBehavior throttleBehavior = serviceHost.Description.Behaviors.Find();

            if (throttleBehavior == null)

            {

                throttleBehavior = new ServiceThrottlingBehavior();

                throttleBehavior.MaxConcurrentCalls = 1000;

                throttleBehavior.MaxConcurrentSessions = 250;

                throttleBehavior.MaxConcurrentInstances = 500;

              serviceHost.Description.Behaviors.Add(throttleBehavior);

            }

In the above code snippet, an instance of ServiceThrottlingBehavior is created and its properties set to the appropriate values. Next, this instance is added to the Behaviors collection of the service host instance.