Condividi tramite


Gestione della perdita di connettività

Dopo il completamento di una chiamata RPC, la connessione non viene chiusa; è contrassegnato come libero. Di conseguenza, il server può andare inattivo o la connettività di rete può essere persa durante o tra le chiamate, mentre una connessione è seduta nel pool. In materia di criteri, il tempo di esecuzione RPC ritenti tali chiamate solo se vengono soddisfatte le due condizioni seguenti:

  • Il server non può eseguire la chiamata oppure la chiamata è idempotente.
  • Il client può implementare nuovi tentativi in modo efficiente in base alle prestazioni.

I paragrafi seguenti espandono e chiarisce le due condizioni.

Una chiamata idempotente è una chiamata che può essere eseguita più volte sul server senza effetti collaterali indesiderati. Ad esempio, la presenza di una chiamata RPC che esegue una query sul saldo della banca per un determinato conto è idempotente. Se questa chiamata viene eseguita due volte a causa della perdita di connettività, non viene eseguito alcun danno. Un altro esempio di chiamata idempotente consiste nel modificare l'indirizzo di un cliente in un database. L'esecuzione due volte è corretta, poiché la seconda esecuzione sostituisce semplicemente l'indirizzo già corrente con lo stesso indirizzo. Un'operazione come "sottrarre cinquanta dollari dal conto xyz" non è idempotente. La perdita di connettività di rete non deve comportare più esecuzioni di una chiamata di questo tipo.

Per essere sicuro, il runtime RPC considera tutte le chiamate come non idempotenti. L'attributo [idempotent] non è supportato per ncacn_ip_tcp e viene ignorato. Di conseguenza, la prima condizione nell'elenco precedente viene ridotta al server che non può eseguire la chiamata.

In molti casi il tempo di esecuzione RPC non è in grado di determinare definitivamente che la chiamata non è già stata eseguita nel server. In questi casi, il client non ritenta l'esecuzione della chiamata.

Gli esempi seguenti illustrano quando il runtime RPC esegue o non ritenta una chiamata:

  • Un server viene riavviato.

    Una semplice chiamata RPC senza sicurezza viene eseguita su un'interfaccia in cui non è stata effettuata alcuna chiamata precedente dopo il riavvio. Poiché non sono state effettuate chiamate su questa interfaccia, la fase di esecuzione RPC tenta per la prima volta di negoziare l'uso dell'interfaccia. Invia un pacchetto usando una connessione nel pool. Poiché il server è stato riavviato e la connessione non è più valida, viene restituito un errore. Poiché il tempo di esecuzione RPC sul lato client non ha ancora avviato l'invio dei dati per la chiamata effettiva, il client determina che il server potrebbe non essere stato eseguito su tali dati. Pertanto, chiude la connessione e cerca un'altra connessione nel pool. Se non riesce a trovare una connessione, apre una nuova connessione e tenta di negoziare di nuovo l'uso dell'interfaccia. Se l'operazione ha esito positivo, viene eseguita la chiamata, ovvero viene effettuato un nuovo tentativo, perché l'errore è stato rilevato prima dell'avvio della chiamata.

  • Una chiamata RPC con sicurezza a livello di privacy (crittografia) viene effettuata su una connessione con un contesto di sicurezza già negoziato.

    Per garantire prestazioni efficienti, il runtime RPC crittografa il pacchetto sottoposto a marshalling inline (sui dati di testo non crittografati). Se il tentativo di invio dei dati ha esito negativo, il tempo di esecuzione RPC non può ripetere la chiamata, poiché i dati non crittografati sono stati sovrascritti con i dati crittografati e non possono crittografare nuovamente i dati con un nuovo contesto di sicurezza. Pertanto, non viene eseguito alcun nuovo tentativo.

  • L'invio di un frammento non primo ha esito negativo.

    Non viene eseguito alcun tentativo, poiché il tempo di esecuzione RPC può scegliere di rimuovere il contenuto del primo frammento una volta completato e non è possibile riprovare a inviare il primo frammento.

  • La richiesta RPC viene inviata.

    Il server interrompe la connessione. Non viene eseguito alcun tentativo, poiché RPC non è in grado di determinare se il server ha ricevuto la chiamata e ha avviato l'esecuzione.

Se il server usa un endpoint dinamico, RPC non risolverà nuovamente l'endpoint durante i tentativi. Ciò significa che se un server viene arrestato e viene eseguito il backup, potrebbe risiedere in un endpoint diverso e RPC non risolverà in modo trasparente l'endpoint quando viene ritentata una chiamata. Per forzare la risoluzione dell'endpoint, il client RPC deve chiamare RpcBindingReset prima di ritentare una chiamata.

In molti di questi casi, se un client RPC può determinare se una chiamata è idempotente o se mantiene i dati ignorati da RPC, può scegliere di compilare un meccanismo di ripetizione dei tentativi su RPC.

Nota

Se il server è un cluster e i diversi nodi del cluster eseguono versioni diverse del software server, un nuovo tentativo RPC può effettuare la chiamata su un nodo diverso del cluster in caso di failover e potenzialmente in una versione diversa del server. In questi scenari di distribuzione, assicurarsi che il client non si basi su una determinata versione del software server per eseguire una determinata chiamata. In tal caso, il client deve creare un meccanismo su RPC che rileva e gestisce tali condizioni.