“Jak usprawnić model domeny wykorzystując jBPM?”
Pierwsza prezentacja dotyczyła jBPM. Dotychczas nie miałem do czynienia z takiego typu narzędziami i uważałem je bardziej za sztukę dla sztuki, które tak na prawdę nadają się tylko na prezentację. Pomimo uprzedzeń, prezentacje uważam za bardzo udaną, zaczęła się od wyjaśnienia znaczenia podstawowych, groźnych skrótów: BPM, BPEL, PDL. Po tym nastąpiło przedstawienie konkretnego narzędzia: JBoss jBPM. Parę rzeczy wyglądało na prawdę obiecująco: procesy można modelować w przeglądarce i pod Eclipse. Szczególnie ta pierwsza opcja może być ciekawa dla analityków - "wyklikają" proces w przeglądarce a później developer może zaimportować go w Eclipse. Sam jBPM może być uruchamiany w trybie standalone lub embedded. Moduł jBPM Console pozwala monitorować i śledzić wykonanie proces w postaci wykresów/tabelek i innych wodotrysków w przeglądarce. Zachwyciłoby to nie jednego managera. Dodatkowo jBPM Console pozwala w łatwy sposób na tworzenie prototypów aplikacji wykorzystujących jBPM, np. zasymulowanie wysłania SMS można zrealizować poprzez utworzenie prostego formularza HTML, którego wysłanie wygeneruje input dla kolejnego etapu procesu.
“Sztuka messagingu"
Pierwsza prezentacja jednej z gwiazd JDD Marka Richardsa, autora Java Message Service. Mark starał się przekonać nas (i mnie osobiście przekonał), że pomimo tego, że JMS API nie zmieniło się od 2002, JMS jest cały czas bardzo użyteczną technologią, a jej umiejętne wykorzystanie pozwala nam tworzyć wydajne/skalowalne/niezawodne i potencjalnie heterogeniczne systemy. Tu znajduje się zapowiedz prezentacji Marka, która pasuję bardzo do obu jego prezentacji na JDD. Na początku prezentacji wiało trochę nudą, i nie pomogło nawet odebranie wiadomości w Groovym w typowym przykładzie send/receive. O wiele ciekawsze okazało się omówienie podstawowych przypadków użycia JMS:
- integracja poprzez JMS pomiędzy aplikacjami/modułami napisanymi w potencjalnie różnych językach (nie chodzi to bynajmniej o wspomniane powyżej Groovy), np JAVA i .NET
- skalowalność - tu szczególnie leży siła rozwiązań opartych na JMS. W przypadku komunikacji 2 komponentów: pierwszy wysyła komunikat do kolejki, a drugi komponent przetwarza ten komunikat. Dzięki takiemu podejściu można bardzo swobodnie i łatwo sterować ilością komponentów (listnerów) przetwarzających komunikaty
- asynchroniczność - możliwość asynchonicznego powiadamiania zainteresowanych komponentów
Dalej pojawiło się parę slajdów związanych z 2 modelami JMS: point-to-point or publish-subscibe, dostępne typy wiadomości (tu pojawiła się uwaga: aby zapewnić interoperability można zapomnieć o ObjectMessage) oraz budowa wiadomości. Mark zwrócił także dodatkowo na ważną cechę związaną z używaniem JMS API: w odróżnieniu od JDBC, transakcyjna jest obiekt session a nie connection. Zazwyczaj optymalnym rozwiązaniem ma być użycie pojedynczego connection i puli obiektów session. Po prezentacji rozmawiałem z Markiem i uświadomił mnie ,że 1 MessageListener= 1 session = 1 TCP connection (to ostanie sam zamierzam sprawdzić ). Oznacza to, że nie można przesadzać z liczbą równolegle odpalonych listnerów - Mark stwierdził. że dla mocno obciążonych systemów ma byc to około 20. Jeśli chodzi o technikalia to polecił używanie Jencks wraz z ActiveMQ lub CachingConnectionFactory.
Bardzo podobał mi się slajdy przedstawiające różne considerations związane z wykorzystywaniem JMS:
- trwałość komunikatów - wiadomości mają byc domyślnie persystentne co oznaczą, że są trzymane w persystentnym storage. Ma to znaczący wpływ na wydajność - przedstawił wykres prezentujący 4 000 persystentych komunikatów na sekundę do 11 000 nie persystentnych. JMSDeliveryMode można ustawić na MessageProducer lub bezpośrednio na Message
- użycie pojedynczej kolejki dla całego przetwarzania - architektura w której to wszystkie komponenty wrzucają swoje komunikaty do pojedynczej kolejki. Wiadomości z kolejki są odczytywane przez pojedynczy komponent pełniący rolę routera, który na podstawie "magicznego dyskryminatora" przechowanego w property wiadomości (a nie w treści wiadomości) deleguję wywołanie (wywołuję metodę) odpowiedniego komponentu. Problem w takim podejściu polega na tym, że pewne komponenty (potencjalnie o różnym znaczeniu) mogą wrzucać z różną częstotliwością swoje wiadomości (potencjalnie o różnej charakterystyce przetwarzania) do wspólnej kolejki. Może to bardzo negatywnie wpływać na response time oraz dodatkowo utrudni skalowania takiego systemu - nie za wiele pomogą tutaj triki z ustawieniami różnych priorytetów dla wiadomości, tym bardziej, że nie można wywłaszczać aktualnie przetwarzanych komunikatów. Idąc dalej, Mark stwierdził, że nie jest niczym egzotycznym definiowanie więcej niż 1 kolejki dla tych samych wiadomości - by zapewnić QoS
Na końcu tej części stanowczo stwierdził, że JMS bardzo dobrze się nadaje gdy mówimy o technologiach związanych z integracją szczególnie pod kątem interoperability. Stwierdził, że dla rozwiązań działających w środowisku "inside firewall" JMS nadaję się o wiele bardziej niż web services, głównie ze względu na większą możliwość tuningu, niezawodność i mniejszą złożoność tworzenia takich systemów (?).
Na końcu pojawiła się wzmianka o REST w świecie JMS i pewna technlogiczno-syntaktyczna niespójność: co powinna robić metoda GET ? czy ma pobierać wiadomość z kolejki ? A jeśli tak to pobranie wiadomości jednocześnie usuwa ją z kolejki, a przecież wywołanie GET powinno być safe. Z tego co zapamiętałem to Active MQ oraz Websphere MQ mają posiadać pseudo REST API do swoich systemów
“Obsługa sytuacji wyjątkowych w systemach budowanych w technologii JEE”
Prezentacja sponsora konferencji, na szczęści wyglądało to duże lepiej niż rok temu. Zaprezentowany materiał całkiem fajny, oparty na doświadczeniu, ale trochę mało świeży, szczególnie gdy ktoś ma do czynienia z lekkimi frameworkami, które stawiają na unchecked exceptions. Oprócz podstawowych informacji o tym jakie wyjątki logować, w jaki sposób logować, co logować itd mnie bardziej zainteresowały następujące zagadnienia:
- transakcyjność a pamięć podręczna - w sytuacji gdy nasz cache nie jest transakcyjny (czyli zawsze, chyba że się mylę ) to trzeba zadbać aby w przypadku rollback wycofać to co w ramach transakcji zmodyfikowaliśmy w cache. Sprawa wydaję się w ogólności dość skomplikowana , a z tego co się orientuję to w hibernate 2nd level cache potrafi sobie z czymś takim radzić out-of-box
- transakcyjność a sesja - w przypadku gdy nasze przetwarzanie na serwerze zakończy się wyjątkiem - sesja może być niespójna - wyjątek mógł polecieć po tym jak coś z sesji zmodyfikowaliśmy. Rozwiązanie ma być oparte o filtr opakowywujący oryginalną sesje w wrapper, dostępny dla aplikacje, a faktyczny zapis do sesji jest realizowany w tym samym filtrze po zakończeniu przetwarzania
- W przypadku standardowego logowania SQLException stacktrace/message wyjątku nie zawierają ani SQLState ani ErrorCode
- W przypadku ServletException nie jest logowany faktyczny powód wystąpienia, który można zobaczyć dobierając się do rootCause
- naruszenie więzów integralności na bazie nie koniecznie jest błędem typu unrecover , a może być po prostu błędem biznesowym - próba stworzenia 2 userów o tym samym login. który to musi być unikalny. W takim przypadku można taki wyjątek złapać i poprawnie obsłużyć.
“Asynchroniczność, współbieżność i rozproszone przetwarzanie w Java EE – przykłady z użyciem technologii middleware Oracle: WebLogic Server, EclipseLink/TopLink JPA i Coherence"
Prezentacja Waldka Kota miała pierwotnie składać się z 2 części: omówienie WorkManager API a później przedstawienie Oracle Coherence. Jednak ze względu na to, że widownia miała problemy z zebraniem się z obiadu oraz dużą liczbą pytań o WorkManager API część druga w ogóle się nie odbyła, a Waldek obiecał, że opiszę to co miał przygotowanie na temat Oracle Coherence na swoim blogu. Prezentacja zaczęła się od przypomnienia/uświadomienia czemu nie powinno się tworzyć wątków w środowisku JEE. Z WorkManager API miałem styczność jakiś czas temu przy tworzeniu aplikacji JEE uruchamianych na "ulubionym" IBM Websphere. Pierwotnie API to powstała w ramach JSR 236, które aktualnie zostało zaniechane i z tego co opowiadał Waldek są jakieś zawirowania w tej sprawie w związku z JEE 6. Do tego czasu Websphere(min 6.0, w wersji 5.0 ma podobny mechanizm Asynchronous Beans)oraz Weblogic (min 9.0) wspierają CommonJ Timer and Work Manager for Application Servers (oprócz Work Manager API mamy do dyspozycji Timer API). Jest to na prawdę silna broń, ale nie do końca wierzę aby nadawała się do tworzenia aplikacji batchowych. Niespecjalnie wgłębiałem się w dostępne opcje konfiguracyjne WorkManager na Websphere, ale to co pokazywał Waldek na przykładzie serwera Weblogic robi naprawdę wrażenie: przypięcie WorkManager do wielu aplikacji, pojedynczej aplikacji, servletu, ziarna EJB, czy nawet metody EJB, określanie parametrów definiujących min/max ilość wątków, ustawienie stuck time i jeszcze pewnie parę innych.
Co ważne podkreślenia WorkManager API uruchamia zadania w kontekście JEE: same zadanie jest wykonywane w kontekście (security, classpath, naming) w jakim zostało ono zlecone do wykonania.
Specyfikacja wspomina także o Remoteable WorkManager i RemoteWorkItem - delegowanie zadań do zdalnych węzłów w klastrze. Websphere nie wspiera takiej funkcjonalności, jestem ciekaw jak to jest w Weblogic.
Efektywne przeglądy kodu dla developerów Java używających metodologii z rodziny agile
Bardzo ciekawa prezentacja, na temat code review. Wojtek na podstawie własnych doświadczeń, przestawił nie tylko na czym polega nowoczesny proces code review, ale co najważniejsze wiele wskazówek związanych z wprowadzaniem code review do organizacji - nic na siłę, metoda małych kroczków, trzeba dostosowac proces do zespołu (zmotywowany i samo-organizujący się zespół :) ), sposób wybieranie reviewerów. Pomimo wielu zasadniczych zalet: mentoring mniej doświadczonych/nowych członków zespołu, budowanie bazy wiedzy, zwiększenie collective ownership kodu, ewentualnie wykrywanie błędów, wprowadzenie code review niestety daje mało mierzalne rezultaty - co często może powodować opór managementu. Code review nie powinno w żadnym przypadku zastępowac statycznej analizy kodu, które to powinna odbywać sie przed review w celu "wyczyszczenia" kodu z naruszeń. Code review, które miałoby się odbywać "tradycyjnie" w postaci spotkania, na którym obecny miałby być cały zespól przeglądający wydrukowany kod, ma być mało skuteczne i problematyczne w sensie logistycznym, o wiele lepiej wykorzystać do tego narzędzia ,np. Crucible. Przyznam, że narzędzie zrobiło na mnie duże wrażenie - wszystko wyglądało bardzo intuicyjnie i prosto, a jednocześnie dobrze dostosowane na potrzeby developerów. Bardzo ciekawie wyglądało porównanie code review i pair programming- obie techniki dotyczą pracy 2 osób nad kawałkiem kodu, jednak tak na prawdę więcej je od siebie różni niż łączy... Z projektów darmowych podobno warto sprawdzić: rietveld, reviewClipse a sam kiedyś instalowałem jupiter
“Testowanie z Groovy”
Prezentacja kolejnej z gwiazd JDD Scotta Davisa. Prezentacja mnie rozczarowała, po standardowej opowieści o tym, że na JVM można uruchamiać aplikacje napisane w: JRuby, JavaScript, JPython,Java FX, Scala oraz kilu żartach prowadzącego, zostało kilkanaście minut na wpomnienie o tym czym jest BDD i pokazanie trywialnego kodu w Groovy z wykorzystaniem paradygmatu: given... : when... : then ... and ...
AFAIK JBoss Cache jest transakcyjny, aczkolwiek tylko gdy ma pod spodem menadżer transakcji zgodny z JTA (np. w serwerze aplikacyjnym). Natomiast co do transakcyjności w Hibernate: mam wrażenie, że może nastąpić niespójność danych jeśli Hibernate umieszcza coś w cache drugiego poziomu, gdyż inna transakcja może to odczytać pomimo braku commit/rollback. Ale właściwie tylko zgaduję.
OdpowiedzUsuńA'propos prezentacji o wyjątkach: bardzo spodobał mi się pomysł "stampowania" wyjątków unikalnym, losowym ciągiem alfanumerycznym, co ma ułatwić przeszukiwanie logów. Zamierzam wypróbować, ale brzmi sensownie.
Witam
OdpowiedzUsuńNa ostanim DEVOXX Emannuel Bernard przyznał, że to co dotychczas pisano na temat Jboss Cache i jego transakcyjności/niezawdoności nie było prawdą ale właśnie nie dawno to poprawili i teraz to powinno byc cacuś - jakoś nie chcę mi się w to wierzyc, a jeśli nawet, to takiej funkcjonalności nie spodziewałbym się w Jboss Cache w wersji org.
W sprawie tej transakcyjności to ciężko się wypowiadac, bo nie korzystam z 2nd level cache.
Ostatno znalazłem jednak fajny wpis gdzie jest opisany szczegółowo jak to ma działac:
http://clustermania.blogspot.com/2009/07/with-read-write-hibernate-2nd-level.html
A w sprawie stampowania wyjątku to już kiedyś taki mechanizm implementowałem przy korzystaniu z flex.