Protocolli di comunicazione di Service Broker
Service Broker utilizza un protocollo specifico per comunicare con le istanze remote di Service Broker. Le connessioni vengono gestite separatamente rispetto al normale pool di connessioni client. Per lo scambio di messaggi di Service Broker tra due istanze di SQL Server ogni istanza deve essere in grado di inviare traffico TCP/IP alla porta utilizzata dall'altra istanza per le comunicazioni di Service Broker. Per convenzione, per le comunicazioni tra Service Broker diversi viene utilizzata spesso la porta 4022. La porta effettivamente utilizzata, tuttavia, viene specificata al momento della creazione dell'endpoint.
Livelli del protocollo
Per le comunicazioni, Service Broker utilizza un approccio basato su livelli. Ogni livello si basa sul livello sottostante per garantire l'affidabilità del recapito. Questo approccio consente alle applicazioni di operare senza conoscere la posizione del servizio remoto o il supporto fisico di trasporto utilizzato da Service Broker per le comunicazioni. Nella maggior parte dei casi, questi protocolli sono trasparenti per l'applicazione. È comunque utile comprendere il ruolo di ogni livello del protocollo per agevolare la risoluzione dei problemi di un'applicazione.
Il protocollo di livello più alto utilizzato da Service Broker è il protocollo di dialogo. Questo protocollo gestisce la trasmissione di messaggi in sequenza in modo da garantirne l'affidabilità. Il protocollo di dialogo genera numeri di sequenza per i messaggi e messaggi di acknowledgement, recapita i messaggi alle code appropriate e provvede alla frammentazione e al riassemblaggio dei messaggi. Gestisce inoltre l'autenticazione e la crittografia per il dialogo.
Per la trasmissione dei frammenti dei messaggi, il protocollo di dialogo utilizza il protocollo di Service Broker adiacente, che gestisce le trasmissioni di rete scambiate tra due istanze di Service Broker.
Il protocollo di Service Broker adiacente utilizza un protocollo di trasporto, ad esempio TCP/IP, per spostare i messaggi da un'istanza di Service Broker a un'altra.
Protocollo di dialogo
Per i messaggi di una conversazione il protocollo di dialogo gestisce il recapito di messaggi inviati una sola volta rispettando l'ordine di invio. Questo protocollo non descrive il formato utilizzato dai messaggi di Service Broker in rete ma specifica i passaggi logici necessari per una conversazione affidabile. Il protocollo di dialofo gestisce le attività necessarie per garantire l'affidabilità del recapito, compresa la generazione e l'elaborazione dei messaggi di acknowledgement.
Ogni lato di una conversazione rappresenta un endpoint nel livello del protocollo di dialogo. Nella vista del catalogo sys.conversation_endpoints sono riportate informazioni sugli endpoint del protocollo di dialogo. Un endpoint di una conversazione ha una durata pari a quella della conversazione.
Protocollo di Service Broker adiacente
Il protocollo di Service Broker adiacente gestisce i meccanismi di comunicazione tra due istanze di SQL Server. Questo livello codifica ogni frammento di messaggio in un formato standard adatto per la trasmissione in rete. A differenza del livello del protocollo di dialogo, questo protocollo prevede la conoscenza del trasporto di rete utilizzato e la conseguente formattazione dei frammenti dei messaggi. In effetti, il livello del protocollo di Service Broker adiacente rappresenta un livello di astrazione tra il livello del protocollo di dialogo e il livello del protocollo di trasporto.
Ogni connessione di rete di Service Broker costituisce un endpoint nel livello del protocollo adiacente. Nella vista a gestione dinamica sys.dm_broker_connections sono riportate informazioni sulle connessioni di rete di Service Broker. Service Broker mantiene la connessione di rete durante lo scambio attivo dei messaggi e la chiude quando tramite la connessione di rete non vengono inviati o ricevuti messaggi per un breve periodo di tempo.
Protocollo di trasporto
Il livello del protocollo di trasporto gestisce la trasmissione di rete vera e propria. Questo livello è esterno a Service Broker. I messaggi destinati a un'istanza di Service Broker in esecuzione in un'altra istanza di SQL Server, ad esempio, utilizzano il protocollo TCP/IP come livello di protocollo di trasporto.
Gli endpoint di Service Broker specificano le opzioni per il protocollo di trasporto. Per impostazione predefinita, SQL Server non contiene endpoint di Service Broker. Per ulteriori informazioni sulla creazione di un endpoint di Service Broker, vedere Procedura: Attivazione delle funzionalità di rete di Service Broker (Transact-SQL).
Comunicazione di Service Broker
Service Broker utilizza due categorie distinte di messaggi: i messaggi in sequenza, ovvero i messaggi che devono essere recapitati a un'applicazione una sola volta e rispettando l'ordine di invio, e i messaggi non in sequenza, ovvero i messaggi che possono essere elaborati immediatamente, indipendentemente dalla sequenza di arrivo.
Service Broker utilizza i messaggi in sequenza per tutti i tipi di messaggi definiti dall'utente, i messaggi di fine dialogo e i messaggi di errore generati da un'applicazione. Ad ogni messaggio in sequenza è associato un numero di sequenza. Il numero di sequenza del messaggio viene creato e assegnato al messaggio dall'istanza di origine del messaggio stesso. L'istanza di Service Broker ricevente ordina i messaggi inviati a un'applicazione utilizzando il numero di sequenza dei messaggi stessi. Per ogni dialogo, il messaggio con il numero di sequenza inferiore viene sempre recapitato per primo all'applicazione corrispondente. Il numero di sequenza dei messaggi, inoltre, viene utilizzato da Service Broker per rilevare eventuali messaggi duplicati. Quando il livello del protocollo di dialogo riceve due messaggi con lo stesso numero di sequenza nello stesso dialogo, i messaggi vengono considerati duplicati e uno viene scartato.
I messaggi non in sequenza vengono utilizzati per i messaggi di acknowledgement dedicati e i messaggi di errore generati da Service Broker. Service Broker non adotta particolari precauzioni nel recapito di un messaggio non in sequenza. Si noti tuttavia che i messaggi non in sequenza vengono creati in risposta ai messaggi in arrivo. Pertanto, in caso di perdita del messaggio non in sequenza, il mittente invia nuovamente il messaggio originale e il destinatario genera un altro messaggio non in sequenza.
Frammentazione dei messaggi
Service Broker suddivide in frammenti i messaggi in uscita e combina i frammenti in arrivo per ricostruire il messaggio originale. I messaggi di piccole dimensioni sono contenuti in un unico frammento mentre quelli di grandi dimensioni vengono suddivisi in numerosi frammenti.
La frammentazione dei messaggi presenta molteplici vantaggi. L'invio di un messaggio di grandi dimensioni suddiviso in piccoli frammenti determina un incremento della velocità complessiva e dell'affidabilità delle comunicazioni su reti relativamente lente e non affidabili, ad esempio le reti WAN. In caso di perdita di un frammento, viene ritrasmesso solo quel frammento particolare anziché l'intero messaggio. La frammentazione dei messaggi di grandi dimensioni può inoltre ridurre il tempo richiesto per il recapito di un messaggio di piccole dimensioni. Service Broker può inviare un frammento che contiene un intero messaggio di piccole dimensioni tra i frammenti di un messaggio di grandi dimensioni. Questo comporta un lieve rallentamento del messaggio di grandi dimensioni ma riduce il tempo di attesa per la trasmissione del messaggio più piccolo.
Durante il riassemblaggio di un messaggio, il messaggio parziale viene archiviato nella coda di destinazione oppure, se questa non è disponibile, nella coda di trasmissione per il database che ospita la coda di destinazione. Un'applicazione non può ricevere un messaggio parziale. La colonna status di un messaggio parziale è impostata su 2 (disattivato). Questo valore viene inoltre utilizzato per i messaggi non ricevuti secondo l'ordine previsto.
Acknowledgement dei messaggi
Service Broker invia un messaggio di acknowledgement per ogni messaggio ricevuto. Un acknowledgement può riguardare uno o più frammenti di messaggio. Se possibile, l'acknowledgement viene incluso nell'intestazione di un altro messaggio inviato nella stessa conversazione. In assenza di altri messaggi pronti per l'invio, Service Broker restituisce un messaggio di acknowledgement dedicato. L'acknowledgement dei messaggi viene gestito interamente da Service Broker. Questi messaggi non vengono ricevuti da un'applicazione che utilizza Service Broker.
I frammenti di messaggi per i quali il destinatario non ha inviato un acknowledgement vengono mantenuti dal mittente. Se non perviene alcun messaggio di acknowledgement per un periodo di tempo definito dal sistema, il mittente invia nuovamente il frammento di messaggio. Se durante il periodo di attesa non perviene alcun messaggio di acknowledgement, Service Broker aumenta in modo esponenziale il tempo di attesa prima del tentativo successivo, fino a un limite massimo. Il tempo di attesa iniziale prima di un ulteriore tentativo corrisponde ad alcuni secondi. Il tempo di attesa massimo corrisponde a circa un minuto. Si noti che il tempo di attesa non deve necessariamente essere preciso. È infatti possibile che, in funzione del traffico di rete e di altre attività nell'istanza di SQL Server, un nuovo tentativo di invio di un frammento di messaggio venga prorogato di alcuni secondi dopo la scadenza del tempo di attesa.
In caso di perdita o di ritardo di un acknowledgement, il destinatario può ricevere messaggi duplicati. In questo caso, il destinatario invia l'acknowledgement del messaggio duplicato ma non recapita il messaggio duplicato alla coda.
Service Broker utilizza l'acknowledgement dei messaggi per garantire l'affidabilità della messaggistica senza transazioni distribuite. Il destinatario invia un acknowledgement solo dopo avere aggiunto il messaggio o il frammento alla coda. Il mittente mantiene il messaggio nella coda di trasmissione finché non riceve il relativo acknowledgement. Il mittente e il destinatario non condividono mai una transazione. Il protocollo garantisce, tuttavia, che il messaggio non venga rimosso dalla coda di trasmissione del mittente finché non giunge al destinatario.
Controllo dell'integrità dei messaggi
Il formato utilizzato da Service Broker per la trasmissione dei messaggi include il controllo dell'integrità per stabilire se un determinato messaggio ha subito modifiche o danneggiamenti durante il trasporto.
Il controllo dell'integrità dei messaggi è costituito da una firma MD5 per il contenuto del messaggio. SQL Server crittografa la firma con la chiave della sessione per il messaggio e inserisce la firma nelle intestazioni dei messaggi.
Il destinatario decrittografa il messaggio, quindi confronta la firma nel messaggio con una nuova firma calcolata in base al contenuto effettivo ricevuto. Se le firme non corrispondono, il messaggio è stato danneggiato o manomesso durante la trasmissione. Il controllo di integrità ha quindi esito negativo. SQL Server elimina il messaggio e non invia l'acknowledgement al mittente. Quando un messaggio non supera il controllo di integrità, le relative informazioni vengono visualizzate nella classe di evento Broker:Corrupted Message.
Flusso delle comunicazioni di rete
Nella figura seguente viene illustrata una vista di alto livello delle comunicazioni di rete di Service Broker tra due istanze di SQL Server.
Si noti che la conversazione è una connessione logica persistente. La conversazione può protrarsi per qualsiasi periodo di tempo, nel corso del quale può utilizzare un numero qualsiasi di connessioni di rete.
Tra due endpoint di Service Broker vengono stabilite connessioni di rete che utilizzano il protocollo TCP/IP. In caso di inattività della connessione per un breve periodo di tempo, SQL Server chiude la connessione di rete.
Per recapitare un messaggio, Service Broker lo mantiene nella coda di trasmissione per il database che ha inviato il messaggio. Il destinatario recapita il messaggio direttamente alla coda per il servizio di destinazione. Se la coda non è attiva, il messaggio viene mantenuto temporaneamente nella coda di trasmissione per il database di destinazione. Si noti che la coda per il servizio di invio non è coinvolta nell'operazione e che la coda di trasmissione per il database che ospita il servizio di destinazione è coinvolta solo se la coda di destinazione non è attiva.