WebSphere MQ - Klastry w praktyce

Autor: Marcin Kasiński
28.01.2012 13:20:49 +0200

Klastry MQ, to rozwiązanie pozwalające na połączenie większej ilości menadżerów kolejek w grupę. Rozwiązanie to pozwala na programowe osiągniecie wysokiej dostępności jak również na zmniejszenie ilości kanałów do zarządzania.

W przypadku klastrów MQ wysoka dostępność polega na tym, iż w klastrze tym można tworzyć kolejki klastrowe, których instancje mogą znajdować się na wielu menadżerach kolejek, w związku z czym jeśli np. któryś z tych menadżerów będzie zatrzymany komunikaty będą przesyłane do pozostałych.

Uproszczenie zarządzania polega na tym, iż w przypadku kanałów wewnątrz klastra nie trzeba mieć połączonych ze sobą parą wszystkich menadżerów w klastrze. Wymagane jest tylko stworzenie kanału odbierającego oraz kanału sender do pełnego repozytorium danego klastra.

W przypadku środowiska klastrowego jeśli aplikacja jest połączona do konkretnego menadżera kolejek, to może ona również otwierać kolejki klastrowe umieszczone na innym menadżerze będącym członkiem tego samego klastra.

Pełne repozytorium klastra (Full repository)

Pełne repozytorium klastra stanowi ważny element architektury klastrowej MQ. Jest to standardowy menadżer kolejek, który poza zarządzaniem własnymi kolejkami pełni rolę repozytorium wszystkich menadżerów i ich kolejek klastrowych. Jego zadaniem jest utrzymywaniem aktualnej tej listy na podstawie informacji przekazywanych mu przez inne standardowe menadżery znajdujące się w klastrze lub przez inne pełne repozytorium. Informacje te następnie są wykorzystywane przez pozostałe menadżery w celu zdefiniowania połączenia do innego menadżera w klastrze. Jako, że utrato takiego menadżera skutkowała by niemożnością połączenia z innymi menadżerami w klastrze wskazane jest aby takich pełnych repozytoriów w klastrze było przynajmniej 2. Aby określić dany menadżer kolejek, jako pełne repozytorium MQ należy na nim wykonać komendę:

ALTER QMGR REPOS(NAME)

gdzie:

  • NAMENazwa kastra, którego dany mendzer będzie pełnym repozytorium MQ

Częściowe repozytorium klastra (Partial repository)

Częściowe repozytorium klastra to każdy inny menadżer kolejek, który nie pełni rolę pełnego repozytorium MQ. Menadżer taki nie posiada informacji o pełnej architekturze MQ klastra, tylko częściową informacje o niej. Dzieje się tak dlatego, ponieważ posiada on wyłącznie informacje o menadżera i kolejkach w klastrze do których wcześniej się odwoływał i dostał już wcześniej informacje o ich położeniu od pełnego repozytorium MQ. Jeśli musi się połączyć z menadżerem, którego nie zna wysyła żądanie do pełnego repozytorium o jego dane. Taki wewnętrzny cache w częściowym repozytorium przechowywane jest przez 30 dni. Po tym czasie wysyłane jest ponownie żądanie do pełnego repozytorium o dane na temat obiektów znajdujących się w lokalnej kopii. Z drugiej strony menadżer pełniący rolę pełnego repozytorium MQ przesyła do częściowych repozytoriów informacje tylko i wyłącznie o zmianach w architekturze klastra.

Kanały klastrowe

Kanał cluster sender

Kanał ten musi być stworzony na każdym menadżerze będącym częścią klastra. Wskazuje on na menadżer będący pełnym repozytorium MQ. Każde częściowe repozytorium MQ powinno mieć tyle kanałów cluster sender ile w klastrze znajduje się pełnych repozytoriów. Każde pełne repozytorium klastra powinno mieć po jednym tego typu kanale wskazującym na pozostałe pełne repozytoria znajdujące się w klastrze.

Kanał cluster receiver

Kanał ten musi być stworzony na każdym menadżerze będącym częścią klastra. Wskazuje on na siebie samego i każdy menadżer ma tylko jeden tego typu kanał. Kanał ten służy do wskazywania innym menadżerom w klastrze definicji połączenia z menadżerem, na którym kanał ten został stworzony.

Operacje na klastrach

Łączenie się do klastra z menadżera kolejek znajdującego się poza klastrem

W przypadku kiedy mamy sytuacje, gdy aplikacja podłączona jest do menadżera znajdującego się poza klastrem, a kolejka docelowa znajduje się na menadżerach kolejek wewnątrz klasta w kilku instancjach można zastosować architekturę, w której jeden menadżer w klastrze potraktujemy jednocześnie jako gateway pomiędzy klastrem a zewnętrznymi menadżerami kolejek. W takiej sytuacja pomiędzy zewnętrznym menadżerem, a menadżerem pełniącym rolę klastra tworzy się standardowe definicje par kanałów np. sender-receiver. Następnie aby umożliwić zewnętrznym menadżerom komunikacje z innymi menadżerami wewnątrz klastra na gateway-u tworzy się alias menadżera wskazujący na dowolny menadżer w klastrze. Definicję taką możemy utworzyć np. poleceniem:

DEFINE QREMOTE(ANY.CLUSTER) RNAME(' ') RQMNAME(' ')

Oznacza to, że jeśli do menadżera gatewaya dotrze z zewnątrz komunikat z kolejki zdalnej wskazującej na menadżer o nazwie ANY.CLUSTER, komunikat ten zostanie przekazany do dowolnego menadżera wewnątrz klastra posiadającego instancję kolejki, zdefiniowanej w definicji kolejki zdalnej na zewnętrznym menadżerze. Definicję takiej kolejki zdalnej znajdującej się na zewnętrznym menadżerze może mieć postać:

DEFINE QREMOTE(TO.CLUSTER.QUEUE) RNAME(CLUSTER.QUEUE.IN) 
RQMNAME(ANY.CLUSTER) XMITQ(QM3)

Teraz po umieszczeniu na zdalnym menadżerze komunikatu w kolejce TO.CLUSTER.QUEUE komunikatu przejdzie on za pośrednictwem pary sender-receiver do gatewaya. Tam jako, że docelowy menadżer okazał się aliasem na dowolny menadżer kolejek za pomocą określonych zasad routingu komunikat zostanie umieszczony w jednym z menadżerów kolejek wewnątrz klastra zawierających lokalna kolejkę klastrową CLUSTER.QUEUE.IN .

Usunięcie menadżera z klastra

Niekiedy istnieje potrzeba zatrzymania menadżera lub jego usunięcia. W przypadku architektury klastrowej Ważne jest aby przed dokonaniem tej czynności poinformować innych członków klastra, o tym zdarzeniu aby nowe komunikaty ni były do niego przesyłane. Inne menadżery mogą mieć we własnej częściowej bazie informacje o tym menadżerze i jego zatrzymanie nie spowoduje od razu rozpropagowanie tej informacji. Informacja ta wygaśnie na innych menadżerach po 90 dniach, ponieważ co taki czas menadżery w klastrze odświeżają swoje lokalne repozytorium. Aby prawidłowo zatrzymać menadżera będącego częścią klastra należy przed tym wykonać na nim komendę usuwającą jego definicje z klastra. Komenda ta ma postać:

SUSPEND QMGR CLUSTER(CLUSTER_NAME) MODE(SUSPEND_MODE)

gdzie :

  • CLUSTER_NAMEnazwa klastra, z którego danego menadżera usuwamy
  • SUSPEND_MODEtryb usunięcia. Przyjmuje następujące wartości:

Parametr SUSPEND_MODE przyjmuje następujące wartości:

  • QUIESCE
  • FORCE

Po dokonaniu na nim odpowiednich czynności, np. wgrania poprawki taki menadżer możemy ponownie dodać do klastra. Dodanie ponowne usuniętego menadżera do klastra ma postać:

RESUME QMGR CLUSTER(CLUSTER_NAME)

gdzie :

  • CLUSTER_NAME

Jeśli już się zdarzyło, że usunęliśmy menadżera bez wykonania na nim komendy SUSPEND lub w jakiś inny sposób straciliśmy nad nim kontrolę możemy w takiej sytuacji wykonać na pełnym repozytorium klastra komendę nakazującą wszystkim menadżerom w klastrze usunąć definicje tego zagubionego menadżera. Komenda taka ma postać:

RESET CLUSTER(CLUSTER_NAME) ACTION( FORCEREMOVE ) QMNAME(QMGR_NAME)

gdzie :

  • CLUSTER_NAMEnazwa klastra, z którego usuwamy wszystkie definicje danego menadżera
  • QMGR_NAMEnazwa menadżera kolejek, którego definicje chcemy usunąć

Przykładowa architektura

Dla zobrazowania koncepcji klastrów przykładowe poniższe skrypty wykonują:

Zmienia definicje menadżera QM1 ustalając go pełnym repozytorium klastra MK_CLUSTER, tworzy jego kanał cluster receiver, kanał cluster sender do drugiego pełnego repozytorium klastra QM2 oraz tworzy na nim kolejkę klastrową CLUSTER.QUEUE.IN

#na QM1 wykonyjemy


ALTER QMGR REPOS(MK_CLUSTER)


DEFINE CHANNEL('TO.QM2') CHLTYPE(CLUSSDR) TRPTYPE(TCP) 
CONNAME('localhost(1415)') CLUSTER(MK_CLUSTER)


DEFINE CHANNEL('TO.QM1') CHLTYPE(CLUSRCVR) TRPTYPE(TCP) 
CONNAME('localhost(1414)') CLUSTER(MK_CLUSTER)


define qlocal('CLUSTER.QUEUE.IN') 
CLUSTER(MK_CLUSTER) DEFBIND(NOTFIXED)

Zmienia definicje menadżera QM2 ustalając go pełnym repozytorium klastra MK_CLUSTER, tworzy jego kanał cluster receiver, kanał cluster sender do drugiego pełnego repozytorium klastra QM1 oraz tworzy na nim kolejkę klastrową CLUSTER.QUEUE.IN

#na QM2 wykonyjemy


ALTER QMGR REPOS(MK_CLUSTER)


DEFINE CHANNEL('TO.QM1') CHLTYPE(CLUSSDR) TRPTYPE(TCP) 
CONNAME('localhost(1414)') CLUSTER(MK_CLUSTER)


DEFINE CHANNEL('TO.QM2') CHLTYPE(CLUSRCVR) TRPTYPE(TCP) 
CONNAME('localhost(1415)') CLUSTER(MK_CLUSTER)


define qlocal('CLUSTER.QUEUE.IN') CLUSTER(MK_CLUSTER) 
DEFBIND(NOTFIXED)



Na menadżerze QM3 tworzy jego kanał cluster receiver, kanały cluster sender do pełnych repozytoriów klastra QM1 oraz QM2 oraz tworzy na nim alias określający ten menadżer jako gateway pomiędzy klastrem, a menadżerami spoza klastra.

#na QM3 (GATEWAY) wykonyjemy


DEFINE CHANNEL('TO.QM1') CHLTYPE(CLUSSDR) TRPTYPE(TCP) 
CONNAME('localhost(1414)') CLUSTER(MK_CLUSTER)


DEFINE CHANNEL('TO.QM2') CHLTYPE(CLUSSDR) TRPTYPE(TCP) 
CONNAME('localhost(1415)') CLUSTER(MK_CLUSTER)


DEFINE CHANNEL('TO.QM3') CHLTYPE(CLUSRCVR) TRPTYPE(TCP) 
CONNAME('localhost(1416)') CLUSTER(MK_CLUSTER)




DEFINE QREMOTE(ANY.CLUSTER) RNAME(' ') RQMNAME(' ')


Aby teraz zweryfikować działanie klastra należy na zewnętrznym menadżerze nie będącym w klastrze wykonać komendę tworzącą kolejkę zdalną wykorzystującą alias stworzony wcześniej.

DEFINE QREMOTE(TO.CLUSTER.QUEUE) RNAME(CLUSTER.QUEUE.IN) 
RQMNAME(ANY.CLUSTER) XMITQ(QM3)

Po wrzuceniu kilku komunikatów do tej kolejki część z nich powinna się znaleźć na menadżerze QM1, a część na menadżerze QM2. Ilość komunikatów jakie znajda się w jednej i drugiej kolejce klastrowej będzie rozłożona mniej więcej proporcjonalnie (przy standardowej konfiguracji).


powrót
Zachęcam do przedstawienia swoich uwag i opinii w polu komentarzy.

Komentarze

Dodaj Komentarz