Přibližně před dvěma měsíci jsem musel řešit
instalaci nové verze systému pro správu naší automatizace (automation harness).
Systém byl vyvinut teamem v Redmondu. Jelikož je tento systém určen pouze
pro interní potřebu, instalace je vždy spojena s téměř detektivním vyhledáváním
všech možných závislostí a zadrátovaných (hardcoded) předpokladů, které
prostředí naší pracovní skupiny neplatí.
Jednou z nových závislostí, kterou jsem nedávno objevil byla
MSMQ fronta, do které systém posílá velké množství zpráv. Jakmile počet zpráv v
této frontě přesáhl jistou mez, celý server, na kterém je systém nainstalován,
se neúměrně zpomalil. PerfMon mi pomohl najít úzke hrdlo - velké množství I\O
operací v procesu MqSvc.exe. V jedné z MSMQ front se nahromadilo několik
miliónů MSMQ zpráv.
Tyto zprávy nebyly z fronty vybírány proto, protože
komponenta, která tyto zprávy konzumuje, není v našem prostředí nainstalována
(není potřebná). Jelikož je produkt MS Office těsně před dokončením, tak si
nemohu, a hlavně nechci, dovolit provádět nějaké skopičiny v klíčové
infrastruktuře našeho vývojového prostředí. Instalace této dodatečné
komponenty, která pro nás nepřináší žádnou přidanou hodnotu, a spíše
představuje potencionální destabilizaci infrastruktury v klíčové částí
projektu, jsem zamítnul poměrně rychle.
Rozhodl jsem se tedy najít takové řešení
problému (odborně známé pod názvem "hack"), které by stálo minimální usílí na
implementaci. Myslím si, že jsem ho našel.
Zde je malá rekapitulace problému. Mám MSMQ frontu, do
které je posíláno velké množství MSMQ zpráv. To po čase vede k degradaci
výkonu celého serveru.
Řešení, které jsem zvolil, používá technologii
MSMQ Triggers v kombinaci s technologií scriptlets. Jediným kódem,
který jsem musel v tomto případě napsat, byl kód COM komponenty.
Ta byla posléze nastavena jako výkonná komponenta k
nastavené MSMQ spoušti (trigger). Posláním COM komponenty je
zahození MSMQ zprávy. MSMQ spoušť tedy vyzvedne zprávu z dané fronty a
předá ji COM komponentě, která v ji zprávu zahodí. Tím dojde k automatickému
vyprázdnění fronty kdykoliv se objeví nová zpráva ve této frontě.
Scriptlets - COM s příchutí VBScriptu
Nejrychlejší způsob, jak napsat COM objekt, je IMHO napsat
ho jako skript. Žádná kompilace, jednoduché ladění, pohoda. Zde je kód:
<?XML version="1.0"?>
<?component error="true" debug="true"?>
<component>
<registration description = "Manage MSMQ Queues used by harness"
progid = "MyApp.QueueManager"
version = "1.00"
classid = "{9386AE41-3A2B-4672-963A-61AD1EC32946}" >
<script language="VBScript">
Function register()
End Function
Function unregister()
End Function
</script>
</registration>
<comment>
This component is used to manage MSMQ queues used by automation harness.
</comment>
<public>
<method name="DropMessage" >
<parameter name="body" />
</method>
</public>
<script id="dd" language="VBScript">
<![CDATA[
' This method is empty on purpose. The main reason is to consume
' message from the queue and throw it away. This method is called
' from MSMQ trigger and for this reason no MSMQ code is required
' here.
Public Function DropMessage(body)
End Function
]]>
</script>
</component>
Tento kód jsem uložil jako soubor s koncovkou .sct. Jedná se
o plně funkční COM objekt implementující rozhraní IDispatch. Soubor s koncovkou
.sct jsem pak zaregistroval pomocí REGSVR32.EXE. Explorer dokonce rozpozná
soubor s koncovkou .sct jako platný COM objekt a ve svém kontextovém menu
nabízí možnosti Register\UnRegister. Jakmile je tento skript zaregistrován jako
COM objekt, lze ho použít v kterémoliv vývojovém prostředí jako jakýkoliv
jiný COM objekt. Dokonce lze v tomto skriptletu provádět změny, které jsou
okamžitě viditelné při dalším volání metody objektu. Změny lze provádět bez
jakékoliv kompilace, instalace či registrace. Samozřejmě pouze dokud nezměníte
rozhraní objektu. IMHO ideální pro prototypy COM objektů!
Konfigurace MSMQ spouští.
Zbytek už je jen snadná procházka růžovou zahradou v
přítomností několika průvodců. Administrativní konzoli pro MSMQ Triggers
zobrazíte pomocí Start -> My Computer -> Manage -> Services And
Applications -> Message Queuing -> Triggers.
Nejdříve je třeba vytvořit nové pravidlo (rule). Pravidlo
určuje kritéria, která musí zpráva splnit, aby bylo zpracována podle potřeby:
Další nastavení pravidla (rule) je to, jakou akci je
třeba vykonat poté, co je zpráva, která vyhovuje zadaným kritériím,
nalezena ve frontě:
Zde říkáme, že poté, co je vhodná zpráva nalezena, MSMQ
engine zavolá námi určenou metodu daného COM objektu. Po kliknutí na tlačítko
Parameters... lze definovat vstupní parametry pro danou metodu COM objektu.
Hodnoty pro tyto parametry pak MSMQ engine předá na vstupu do dané metody
objektu. Tím je konfigurace pravidla hotova.
Posledním krokem de konfigurace vlastní spouště:
Tento konfigurační dialog spojí (bind) pravidlo (rule) s
danou frontou. Tím je konfigurace hotova.
Třeba se vám to bude hodit.