Koliko sam u dosadašnjem iskustvu primetio, upravljivosti razvijenih aplikacija se obično poklanja malo ili najčešće nimalo pažnje. Veoma malo programera ili projektanata može da odgovori na sasvim jednostavna pitanja o projektima koje su sami napravili, kao na primer:
Osim toga često se upravljanje aplikacijom svodi na periodični restart kompletnog servera u slučaju da nešto ne radi. Niko se i ne pita šta to tačno ne radi, ni da li se može nekako bezbolnije popraviti.
Šta bi bilo kad bi imali neki alat pomoću kog bi mogli zaviriti unutar aplikacije, i pogledati trenutne vrednosti objekata? I kad bi mogli u sred izvršavanja aplikacije promeniti vrednost tih promenjivih? Ili još bolje, "ručno" pozvati bilo koji metod u aplikaciji, u trenutku dok se ona izvršava? Odgovor je kao i uvek troslovna skraćenica, a ovaj put je to JMX.
JMX je skraćenica za Java management extensions. Iza naziva se opet krije način da upravljate aplikacijama ili servisima. JMX definiše arhitekturu, API i Java servise za upravljanje aplikacijama. Tehnologija se u principu sastoji od tri koraka:
JMX arhitektura pojednostavljeno izgleda kao na slici:
Kao dodatni bonus, korišćenje JMX standarda vam omogućava da upravljate i mnogim tehnologijama koje koristite u svakodnevnom radu. Zaista mnogo prvoklasnih biblioteka (na primer ActiveMQ) su instrumentalizovane kroz JMX tako da njihov monitoring i podešavanje dobijate bez ikakvog truda. Osim toga i sama virtuelna mašina je na isti način instrumentalizovana, pa možete na primer gledati koliko JVM memorije ili niti alocira. Posebno moćan osećaj je mogućnost da kliknete na GC collect dugme – garantovano ćete se osećati kao Java guru. :)
Evo jednog jednostavnog primera na kom se vidi koliko je u stvari trivijalno koristiti JMX ili ga uvesti u postojeću aplikaciju. U ovom primeru se radi o konzolnoj aplikaciji, ali vas ništa ne sprečava da isti princip koristite u bilo kakvom servisu, swing ili web aplikaciji. Primer će eksportovati atribute i operacije jednog objekta koji kasnije možemo pogledati u JConsole monitoru. Nadgledaćemo vrednost polja counter, i moći ćemo da izvršimo operacije pause, resume i incrementCounter.
Svakako, u realnom okruženju ništa vas ne sprečava da napravite proizvoljno kompleksne objekte koje kasnije možete nadgledati. Na primer, zašto ne napraviti MBean u kom bi mogli da podešavate maksimalan broj konekcija na server, da praznite keš, gledate trenutno ulogovane korisnike ili pratite brzinu izvršavanja pojedinih operacija u aplikaciji.
Za početak, deklarisaćemo interfejs objekta koji želimo nadgledati. Po konvenciji (koja se obavezno mora pratiti), ime interfejsa se završava sa „Mbean“.
public interface WorkerMBean {
|
Implementacija je takođe jednostavna. Po konvenciji, klasa koja implementira MBean interfejs se zove kao interfejs, ali bez nastavka.
public class Worker implements WorkerMBean {
|
Main metod instancira Worker klasu, i na svaki sekund inkrementira brojač. Ovako bi izgledao naš test program bez korišćenja JMXa:
public class Main {
|
Da bismo našu instancu videli kroz JMX, potrebno je da se ona registruje u MBeans serveru. Kod za to je veoma jednostavan. Prvo dobavimo instancu MBeans servera pozivom:
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
I zatim registrujemo naš objekat:
ObjectName name = new ObjectName("net.javasvet:type=Worker");
|
Tako registrovan objekat kasnije je moguće videti u bilo kom JMX monitoring alatu. Kompletna Main klasa našeg primera na kraju izgleda ovako:
public class Main {
|
Posle pokretanja našeg test programa, možemo pogledati kako to izgleda iz JConsole. JConsole nalazi u "bin" folderu JDK instalacije. Na početku se prikazuje ekran u kom se vide sve virtuelne mašine na računaru, i gde možemo izabrati koju JVM želimo da posmatramo.
Nakon izbora virtuelne mašine otvara se prozor u kom možemo videti detaljnije informacije. Sama virtuelna mašina je u velikoj meri instrumentalizovana, tako da je moguće pratiti informacije o stanju same VM. Moguće je videti detalje konfiguracije, raspoloživu i zauzetu memoriju, informacije o klasama i nitima, te podesiti parametre virtuelne mašine.
Ono što nas zanima je jezičak MBeans na kom se mogu videti svi registrovani beanovi. Između ostalog tu se pojavljuje i WorkerMBean:
Kao što se vidi na slikama, moguće je videti vrednost promenjivih unutar beana, te pritiskom na dugme pozvati određeni metod (da, toliko je jednostavno). Na slici se takođe vide eksportovani objekti od drugih komponenti – monitoring i upravljanje tim objektima je bonus koji dobijate bez ijedne linije koda ili bilo kakvog truda za instalaciju.
Naravno, sve što je jednostavno uraditi u Javi, uz pomoć Springa je još jednostavnije. Da bi koristili MBeans, nije potrebno deklarisati interfejs. Osim toga o registraciji MBeana se brine Spring, tako da je sve što je potrebno je deklarisati eksporter u konfiguracionom fajlu:
<bean id="exporter"
|
Main klasa sad izgleda ovako:
public class Main {
|
Za sve mnogobrojne fanove Groovyja ;) evo i primer kako se tamo koristi JMX. Groovy ne bi bio to što jeste da ne postoji builder za JMX. Uz njegovu pomoć eksportovanje MBeana je nešto lakše. Nije potrebno definisati interfejs, a pored toga builder na sebe preuzima zadatak registrovanja.
import groovy.jmx.builder.JmxBuilder
|
Više informacija o JmxBuilderu se može naći na http://groovy.codehaus.org/Groovy+JmxBuilder
Ono što je takođe moguće postići (a nije pokriveno ovim člankom) su notifikacije, odnosno MBeans mogu poslati informaciju o nekom događaju koja se posle može pratiti u alatu za monitoring. Ukoliko je neko zainteresovan dodatne informacije može pronaći na http://java.sun.com/docs/books/tutorial/jmx/notifs/index.html
Ja u Java tehnologiji nikad nisam video bolje osmišljenu ili implementiranu tehnologiju. Stvar se jednostavno koristi, i prosto rečeno – radi. Sama mogućnost da recimo možete da povećate broj DB konekcija bez da prekinete rad aplikacije je fascinantna. Ili da recimo pauzirate neki zahtevan proces i pokrenete ga kad je opterećenje sistema manje. Pošto se JMX tako jednostavno koristi, šteta je bar ne probati kako stvar radi. A za bilo koji sistem koji iole cilja na high-availability, JMX se jednostavno mora primenjivati. Ukratko – sve preporuke.