Ik ben dol op het aanpassen van SQL Server-code om de prestaties te verbeteren, maar er zijn af en toe scenario's waarin zelfs na het afstemmen van de code, indexen en ontwerp een gebruikerstaak van de applicatie langer duurt om te voltooien dan de verwachte eindgebruikerservaring. Wanneer dit gebeurt, moet de gebruikersinterface wachten tot het proces is voltooid of moeten we een alternatieve manier bedenken om de taak af te handelen. De asynchrone verwerking die door Service Broker wordt geleverd, is geschikt voor veel van deze scenario's en maakt het mogelijk om de langlopende taak op de achtergrond afzonderlijk van de gebruikersinterface uit te voeren, zodat de gebruiker onmiddellijk kan blijven werken zonder te wachten tot de taak daadwerkelijk wordt uitgevoerd . In mijn volgende paar artikelen hoop ik een serie te maken over hoe u Service Broker kunt gebruiken met de juiste uitleg en codevoorbeelden om het gemakkelijker te maken om de mogelijkheden van Service Broker te benutten zonder implementatieproblemen.
Methoden voor het uitvoeren van asynchrone verwerking
Er zijn een aantal manieren om met een langlopend, maar al afgestemd proces om te gaan. De applicatiecode kan ook worden herschreven om een BackgroundWorker, de ThreadPool op de achtergrond of een handmatig geschreven Thread-gebaseerde oplossing in .NET te gebruiken die de bewerking asynchroon uitvoert. Dit zorgt er echter voor dat een onbeperkt aantal van deze langlopende processen door de applicatie kan worden ingediend, tenzij er extra codeerwerk wordt gedaan om het aantal actieve processen bij te houden en te beperken. Dit betekent dat de applicatie een mogelijke prestatie-impact zal hebben, of onder belasting een limiet bereikt en terugkeert naar het vorige wachten dat we oorspronkelijk probeerden te voorkomen.
Ik heb ook gezien dat dit soort processen zijn omgezet in SQL Agent-taken die zijn gekoppeld aan een tabel die wordt gebruikt om de te verwerken informatie op te slaan. Vervolgens wordt de taak ofwel gepland om periodiek te worden uitgevoerd, of wordt gestart door de toepassing met behulp van sp_start_job
wanneer een wijziging wordt opgeslagen voor verwerking. Dit zorgt echter alleen voor een seriële uitvoering van de langlopende processen, aangezien SQL Agent niet toestaat dat een taak meerdere keren tegelijk wordt uitgevoerd. De taak zou ook moeten worden ontworpen om scenario's aan te kunnen waarin meerdere rijen de verwerkingstabel binnenkomen, zodat de juiste volgorde van verwerking plaatsvindt en daaropvolgende indieningen afzonderlijk worden verwerkt.
Door gebruik te maken van Service Broker voor asynchrone verwerking in SQL Server worden in feite de beperkingen aangepakt met de eerder genoemde methoden voor het afhandelen van de asynchrone verwerking. De Broker-implementatie maakt het mogelijk om nieuwe taken in de wachtrij te plaatsen voor asynchrone verwerking op de achtergrond, en maakt ook parallelle verwerking mogelijk van de taken die in de wachtrij zijn geplaatst tot een geconfigureerde limiet. In tegenstelling tot de applicatielaag die moet wachten wanneer de limiet is bereikt, zet de brokeroplossing het nieuwe bericht dat wordt ontvangen gewoon in de wachtrij en laat het verwerken wanneer een van de huidige verwerkingstaken is voltooid - hierdoor kan de applicatie doorgaan zonder te wachten.
Configuratie van enkele Database Service Broker
Hoewel Service Broker-configuraties complex kunnen worden, hoeft u voor eenvoudige asynchrone verwerking alleen de basisconcepten te kennen om een enkele databaseconfiguratie te bouwen. Een enkele databaseconfiguratie vereist slechts:
- Twee berichttypen maken
- Een voor het aanvragen van de asynchrone verwerking
- Een voor het retourbericht wanneer de verwerking is voltooid
- Een contract met de berichttypen
- Definieert welk berichttype wordt verzonden door de initiatorservice en welk berichttype wordt geretourneerd door de doelservice
- Een wachtrij, service en activeringsprocedure voor het doel
- De wachtrij biedt de opslag van berichten die door de initiatorservice naar de doelservice zijn verzonden
- De activeringsprocedure automatiseert de verwerking van berichten uit de wachtrij
- Retourneert een voltooid bericht naar de initiator-service wanneer deze de verwerking van een gevraagde taak voltooit
- Verwerkt de http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog en http://schemas.microsoft.com/SQL/ServiceBroker/Error systeemberichttypen
- Een wachtrij, service en activeringsprocedure voor de initiator
- De wachtrij biedt de opslag van berichten die naar de service zijn verzonden
- De activeringsprocedure is optioneel, maar automatiseert de verwerking van berichten uit de wachtrij
- Verwerkt het voltooide bericht naar de doelservice en beëindigt het gesprek
- Verwerkt de http://schemas.microsoft.com/SQL/ServiceBroker/EndDialog en http://schemas.microsoft.com/SQL/ServiceBroker/Error systeemberichttypen
Naast deze basiscomponenten gebruik ik bij voorkeur een in de wrapper opgeslagen procedure voor het maken van een gesprek en het verzenden van berichten tussen brokerservices om de code schoon te houden en het indien nodig gemakkelijker te schalen door hergebruik van gesprekken te implementeren of de 150-gesprekstruc uitgelegd in de whitepaper van het SQLCAT-team. Voor veel van de eenvoudige asynchrone verwerkingsconfiguraties hoeven deze prestatieafstemmingstechnieken mogelijk niet te worden geïmplementeerd. Door een in de wrapper opgeslagen procedure te gebruiken, wordt het echter veel gemakkelijker om een enkel punt in de code te wijzigen, in plaats van elke procedure te wijzigen die in de toekomst een bericht verzendt, mocht dit nodig zijn.
Als u Service Broker nog niet heeft bekeken, biedt deze mogelijk een alternatieve methode om ontkoppelde verwerking asynchroon uit te voeren om een aantal mogelijke scenario's op te lossen. In mijn volgende bericht zullen we de broncode voor een voorbeeldimplementatie doornemen en uitleggen waar specifieke wijzigingen moeten worden aangebracht om de code te gebruiken voor asynchrone verwerking.