event-driven architecture with java technology stack

Post on 18-Jan-2017

29.695 Views

Category:

Software

4 Downloads

Preview:

Click to see full reader

TRANSCRIPT

www.luxoft.com

EVENT-DRIVEN ARCHITECTURE WITH JAVA TECHNOLOGY STACKEvgeniy Khyst29.10.2015

www.luxoft.com

Event-Driven Architecture with Java Technology Stack1. Event-Driven Architecture 2. Using Events in Java EE CDI Applications3. Message-Oriented Middleware4. Java Message Service5. Message Queue and Publish-Subscribe Patterns6. Reliable Message Delivery7. Message Priority and Scheduled Delivery8. Distributed Transactions

www.luxoft.com

Why Do We Need Event-Driven Architecture?

Let’s consider checkout shopping cart functionality for e-commerce framework.

public void checkoutShoppingCart(ShoppingOrder order) { persistInDatabase(order); sendEmailNotification(order); shipToTheNearestWarehouse(order); scheduleShippingToCustomer(order); exportToERP(order);}

Method checkoutShoppingCart becomes unmaintainable mess.

www.luxoft.com

Why Do We Need Event-Driven Architecture?

• The growing complexity of enterprise applications often result in bad architecture, and organization is spending more and more money building IT systems;

• Event-driven architecture is designed to solve these problems by decoupling software components and services.

www.luxoft.com

Why Do We Need Event-Driven Architecture?

The goal of event-driven architecture is to allow to loosely couple system components together.

www.luxoft.com

What Is Event?

• Event is a significant change in state;• Events are transmitted among loosely coupled services;• Events represent milestones in business process;• Services observe events and react on them.

www.luxoft.com

Observer Pattern• Observer pattern helps to understand event-driven architecture concepts;• In observer pattern an object, called the subject, maintains a list of its

dependents, called observers, and notifies them of any state changes;• Making use of events and observers makes services even more loosely

coupled.

www.luxoft.com

Loose Coupling

• Components are loosely coupled if they have little or no direct knowledge of each other;

• Coupling refers to classes, interfaces, services, software components;

• When a dependent class contains a pointer directly to a concrete class which provides the required behavior, they are tightly coupled;

• When events and observers are used, class firing the event has no knowledge of class observing and reacting on this event.

www.luxoft.com

Performance

• Designing systems to be asynchronous from end-to-end allows to minimize the amount of threads blocking on IO operations, and to use network bandwidth to its full capacity;

• All observers will react in parallel on notification about event, making multi-core CPUs and clusters work on its highest capacity;

• When distributed system runs in cluster, events can be delivered to any host of the cluster providing transparent load-balancing and failover.

www.luxoft.com

Performance

Event-driven architecture allows to create much higher performance applications.

www.luxoft.com

Using Events in Java EE CDI Applications

ShoppingOrderEvent bean defines an event using properties, which has setter and getter methods.

private ShoppingOrder order;...public ShoppingOrderEvent() {}

www.luxoft.com

Using Events in Java EE CDI ApplicationsEvents are handled using an observer method.

public void persistInDatabase(@Observes ShoppingOrderEvent event) { ...}

public void sendEmailNotification(@Observes ShoppingOrderEvent event) { ...}

public void shipToTheNearestWarehouse(@Observes ShoppingOrderEvent event) { ...}

public void scheduleShippingToCustomer(@Observes ShoppingOrderEvent event) { ...}

public void exportToERP(@Observes ShoppingOrderEvent event) { ...}

www.luxoft.com

Using Events in Java EE CDI Applications

To fire an event and notify any observer method, call the javax.enterprise.event.Event.fire method.

@Injectprivate Event<ShoppingOrderEvent> orderEvent;

public void checkoutShoppingCart(ShoppingOrder order) { ShoppingOrderEvent orderEventPayload = new ShoppingOrderEvent(); ... orderEvent.fire(orderEventPayload);}

www.luxoft.com

Using Events in Java EE CDI Applications

• Each observer method as well as method firing event can be located in different classes and packages;

• The senders and consumers of messages are completely independent and know nothing of each other;

• Maximum loose coupling is achieved.

www.luxoft.com

Message-Oriented Middleware

• Events can be presented as messages;• Message-oriented middleware (MOM) is software

supporting sending and receiving messages between distributed systems;

• MOM is sometimes called messaging system or message broker and is an extra component in the architecture.

www.luxoft.com

Message-Oriented Middleware

Messaging systems usually provide protocol or API for sending and receiving messages:• JMS - Java Message Service• AMQP - Advanced Message Queuing Protocol• STOMP - Simple Text Oriented Messaging Protocol• RESTful API• System specific APIs

www.luxoft.com

Message-Oriented Middleware

Messaging systems usually support two styles of asynchronous messaging: • Point-to-Point• Publish-Subscribe

www.luxoft.com

Java Message Service

• Java Message Service (JMS) is a standard of middleware for sending messages, that allows applications, running on Java EE platform, to create, send, receive and read messages;

• JMS is a Java API, part of Java EE specification.

www.luxoft.com

JMS 2.0 Example

Sending messages using JMS.@Resource(mappedName = "java:jboss/jms/queue/exampleQueue")private Queue exampleQueue;@Injectprivate JMSContext context;...public void sendMessage(String text) { context.createProducer().send(exampleQueue, text);}

www.luxoft.com

JMS 2.0 Example

Synchronous receiving messages using JMS.@Resource(mappedName = "java:jboss/jms/queue/exampleQueue")private Queue exampleQueue;@Injectprivate JMSContext context;...public String receiveMessage() { return context.createConsumer(exampleQueue) .receiveBody(String.class);}

www.luxoft.com

Message-Driven Bean ExampleReceiving messages with message-driven bean (MDB) an EJB that allows Java EE applications to process messages asynchronously.

@MessageDriven(name = "ExampleMDB", activationConfig = { @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "java:jboss/jms/queue/exampleQueue"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})public class ExampleMDB implements MessageListener { public void onMessage(Message message) { try { if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; ... } } catch (JMSException e) { throw new RuntimeException(e); } }}

www.luxoft.com

Message Queue Pattern

1. Message is sent to queue;2. Message is persisted to provide a guarantee of delivery;3. Messaging system delivers the message to a consumer;4. Consumer processes and acknowledges the message;5. Message is removed from the queue and is not available to be

delivered again;6. If the system crashes before the messaging server receives an

acknowledgement from the consumer, then on recovery, the message will be delivered to a consumer again.

www.luxoft.com

Publish-Subscribe Pattern

• Message is sent to topic;• Each subscription receives a copy of each message sent

to the topic;• Durable subscriptions receives all messages sent to the

topic even if consumer was not available for some time;• Non durable subscriptions receives only those messages,

that were sent while consumer was available.

www.luxoft.com

Reliable Message Delivery

Message delivery occurs in two hops: • the first hop takes the message from the producer to a

physical destination on the broker• the second hop takes the message from that destination

to the consumer

www.luxoft.com

Reliable Message Delivery

A message can be lost in one of three ways: • on its hop from the producer to the broker• on its hop from the broker to the consumer• while it’s in broker memory (if the broker fails)Reliable delivery guarantees that delivery will not fail in any of these ways.

www.luxoft.com

Reliable Message Delivery

Two mechanisms are used to ensure reliable delivery:• acknowledgments or transactions are used to make

sure message was successfully consumed• messaging system stores messages in a persistent store

called journal so that if the broker fails before the message is consumed, the stored copy of the message can be redelivered on recovery

www.luxoft.com

Reliable Message Delivery

Messages are either durable or non-durable. • Durable messages will be persisted in permanent storage

and will survive server failure or restart;• Non durable messages will not survive server failure or

restart.

www.luxoft.com

Message Redelivery

• Messages can be delivered unsuccessfully (if the broker fails);

• Such a message goes back to the JMS destination ready to be redelivered.

www.luxoft.com

Message Redelivery

• To prevent clogging the system with messages that are delivered again and again without success, messaging systems define dead letter concept;

• After a specified unsuccessful delivery attempts, the message is removed from the destination and put instead in a dead letter queue.

www.luxoft.com

Message Redelivery

• Messaging systems also defines delayed redelivery concept;

• Redelivery will be scheduled with a delay;• Delay between delivery attempts can increase

exponentially.

www.luxoft.com

Message Expiration

• The time messages are retained in messaging system before it will be removed can be limited;

• JMS providers set JMSExpiration field when a message is sent;

• When messages are expired, they are removed from the queue and sent to the expiry queue.

www.luxoft.com

Message Priority

• By default messaging system queues operates as FIFO queues;• Explicitly specifying message priority will make messaging queue

operate as priority queue;• Message priority can be used to influence the delivery order

for messages;• The message priority value is of type integer, ranging from 0

(the lowest) to 9 (the highest);• Messages of higher priorities will likely be delivered before those

of lower priorities.

www.luxoft.com

Message Priority

• If business process can be decomposed into set of tasks or activities, message priority can be used to interrupt low priority business processes if higher priority business process was started;

• High priority requests will be processed as fast as possible and low priority requests will be processed when there will be free computing resources.

www.luxoft.com

Message Priority

1. Send message with appropriate priority to the queue to start business process;

2. Service consuming the message should perform corresponding activity and at the end send another message into the queue propagating initial priority to proceed business process;

3. If there are messages with higher priorities in the queue and there are not enough computing resources, messages with higher priorities will be processed first and after that messages with lower priority;

4. Business process with lower priority will be “interrupted” to let higher priority business process complete.

www.luxoft.com

Scheduled Delivery

Most messaging systems provide a way to schedule message delivery. This feature will be useful when:• Business process should not be started immediately after

message was sent;• Business process should be cancelled after some timeout.

www.luxoft.com

Scheduled Delivery

HornetQ example of scheduled delivery....TextMessage message = session.createTextMessage( "This is a scheduled message message which will be delivered in 5 sec.");message.setLongProperty("_HQ_SCHED_DELIVERY", System.currentTimeMillis() + 5000);producer.send(message);...// message will not be received immediately but 5 seconds laterTextMessage messageReceived = (TextMessage) consumer.receive();...

www.luxoft.com

JMS Limitations

●2001 – JMS 1.0.2b●2002 – JMS 1.1●2013 – JMS 2.0

JMS 2.0 still has some limitations.

www.luxoft.com

JMS Limitations

Some limitations of the JMS:● JMS misses ability to acknowledges only the individual message,

rather than all messages received;● JMS misses negative acknowledgment (NAK, NACK) feature.

www.luxoft.com

Individual Message Acknowledgment

In CLIENT_ACKNOWLEDGE mode javax.jms.Message#acknowledge() acknowledges all messages consumed by javax.jms.Session at when acknowledge() is called.

www.luxoft.com

Extension to JMS Acknowledge Modes

Extension to JMS acknowledge modes to acknowledge only the individual message:● TIBCO Enterprise Message Service –

EXPLICIT_CLIENT_ACKNOWLEDGE;● ActiveMQ – INDIVIDUAL_ACKNOWLEDGE.

www.luxoft.com

Negative Acknowledgment

● If message causes exception it will not be re-delivered until javax.jms.Session disconnects;

● Negative acknowledgment to redeliver message to the same or other session is convenient but absent in JMS;

● JMS provides javax.jms.Session#recover() which stops message delivery in this session, and restarts message delivery with the oldest unacknowledged message;

● recover() doesn’t allow to return individual message back to destination on JMS broker.

www.luxoft.com

Negative Acknowledgment

RabbitMQ that implements AMQP allows to perform negative message acknowledgment (NACK) using basic.reject and basic.nack methods.

www.luxoft.com

Distributed Transactions

• The JMS specification supports distributed transactions;• The production and consumption of messages can be part

of a larger, distributed transaction that includes operations involving other resource managers, such as database systems;

• A distributed transaction manager, like the one supplied by the application server, must be available to support distributed transactions.

www.luxoft.com

Two-Phase Commit

• Distributed transactions with two-phase commit (2PC) are also called XA transactions;

• Support for distributed transactions means that messaging clients can participate in distributed transactions through the XAResource interface defined by JTA;

• This interface defines a number of methods used in implementing two-phase commit.

www.luxoft.com

Two-Phase Commit

• Phase 1 - Prepare. Transaction coordinator, asks participating resources to promise to commit or rollback the transaction. If any resource cannot prepare, the transaction is rolled back;

• Phase 2 - Commit or Rollback. If all participants respond to the coordinator that they are prepared, then the coordinator asks all resources to commit the transaction.

2PC is done automatically by transaction manager (typically a part of Java EE application server) and requires no actions from developer.

www.luxoft.com

Best Effort One-Phase Commit

The best efforts 1PC pattern is synchronized single-phase commit of a number of resources.The message transaction is started before the database one, and they end (either commit or rollback) in reverse order.1. Start messaging transaction2. Receive message3. Start database transaction4. Update database5. Commit database transaction6. Commit messaging transaction

www.luxoft.com

Best Effort One-Phase Commit

• If the commit of the database resource fails, messaging transaction will be rolled back;

• If the commit of the database resource success but the commit of the messaging transaction fails, it will result in duplicate message (message will be redelivered);

• Best effort 1PC commit can be used if system is able to appropriately handle duplicate messages.

www.luxoft.com

Best Effort One-Phase CommitBest effort 1PC example in Spring.<bean id="nonTransactionalConnectionFactory"class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter"> <property name="targetConnectionFactory" ref="hornetQConnectionFactory"/> <property name="username" value="guest"/> <property name="password" value="guest"/></bean>

<bean id="connectionFactory" class="org.springframework.jms.connection.TransactionAwareConnectionFactoryProxy"> <property name="targetConnectionFactory" ref="nonTransactionalConnectionFactory"/> <property name="synchedLocalTransactionAllowed" value="true"/></bean>...

www.luxoft.com

Best Effort One-Phase Commit

...<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource"/></bean>

<tx:annotation-driven transaction-manager="transactionManager"/>...

www.luxoft.com

Best Effort One-Phase Commit

...<jms:listener-container connection-factory="connectionFactory" transaction-manager="transactionManager" concurrency="10"> <jms:listener destination="exampleQueue" ref="myListener"/></jms:listener-container>...<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory"/> <property name="sessionTransacted" ref="true"/></bean>...

www.luxoft.com

Transactions and Redelivery

• It is a common practice to rely on message redelivery in case of distributed transaction failure;

• If it is acceptable for business process to be repeated, exception handling in code can be skipped;

• Whole distributed transaction can be rolled back, message will be returned to queue and delivered to available consumer to be processed again.

www.luxoft.com

THANK YOU

top related