Upload
sridhar-reddy
View
156
Download
1
Embed Size (px)
Citation preview
JMS 1.1 & 2.0 with ActiveMQ and WebSphere MQ
Sridhar Reddy Ratna
1. Messaging introduction2. JMS API Basics3. P2P messaging4. Publish / Subscribe Messaging5. Message Headers6. Request – Reply Messaging7. Message Types8. Message Selectors (filtering)9. Acknowledge modes10. Message Groups11. Transacted Sessions12. Browse Queues and Metadata13. Durable subscribers and Load Balancing14. Internal Broker (Embedded Broker)15. Spring JMS16. Restful JMS17. Design Considerations18. Performance Techniques19. JMS 2.020. JMS 2.0 implementations
Course Contents
Integration
Application 1 Application 2
Application 1 Application 2
export
data
File Sharing
Application 1 Application 2 Application 3
Common Database
import
Application 1 Application 2
stub
skelton
Function call
result
RPC (Remote Procedural call)
RPC model is most successful in multi-tier, applications. In this model, a presentation layer (first tier) communicates using RPC with business logic on the middle tier (second tier), which accesses data housed on the backend (third tier). J2EE platform and .NET platform are the most modern examples of this architecture.
RMI, CORBA, and EJB and Web Services falls into RPC style of communication.
RPC attempts to mimic the behavior of a system that runs in one process. When a remote procedure is invoked, the caller is blocked until the procedure completes and returns control to the caller. This synchronized model allows the developer to view the system as if it runs in one process.
The tightly coupled nature of RPC creates highly interdependent systems where a failure on one system has an immediate and debilitating impact on other systems. In J2EE, for example, the EJB server must be functioning properly if the servlets that use enterprise beans are expected to function.
RPC (Remote Procedural Call)
RPC (Remote Procedural Call)
A change of Address in Customer records subsequent changes in Policy subsystem for policy amendments, may require a change of Quote for the new address, Claims system and so on.
Failure to update in any of the sub system, results in failure of the address change in the system or leaves the system with stale information.
Any new subsystem introduced, requires an update to all the subsystems with which it will interact with the location information.
Advantages of MessagingHeterogeneous IntegrationDecoupled solution allowing both data and functionality to be shared across applications or subsystems.
Reduce System Bottlenecks• Application is getting requests that your application can handle • Database is slow and unable to handle the volumes • Disk is out of space as the inflow is too high
Increase Scalability• Increasing the number of message producers• Increasing the number of message consumers• Increase the queue depth• Design system in asynchronous as possible
Architecture Flexibility and Agility Architectural agility is the ability to respond quickly to a constantly changing environment. • quickly respond to changes in software, hardware, and even business changes. • swap out one system for another• change a technology platform, or even change a vendor solution
RPC Converted to Message Model
Hybrid systems
Messaging History
In 1.02b, Queues and Topics are separate transactional units. So cannot have both Queues and Topics involved in single transaction.
JMS 1.1 unified the two APIs into a Single generic API.
Spring JMS came out just after JMS 1.1 release which simplified JMS development on the top of JMS API.
There were many ESBs developed on the top of Messaging Platform
Messaging Wire Level ProtocolsAMQP Advanced Message Queuing Protocol
AMQP mandates the behavior of the messaging provider and client to the extent that implementations from different vendors are interoperable, in the same way as SMTP, HTTP, FTP, etc. have created interoperable systems.
Unlike JMS, which defines an API and a set of behaviors that a messaging implementation must provide, AMQP is a wire-level protocol. A wire-level protocol is a description of the format of the data that is sent across the network as a stream of octets.Any tool that can create and interpret messages that conform to this data format can interoperate with any other compliant tool irrespective of implementation language.
MQTT Message Queue Telemetry TransportThe MQ Telemetry Transport (MQTT) protocol is a lightweight publish/subscribe protocol flowing over TCP/IP for remote sensors and control devices through low bandwidth, unreliable or
intermittent communications.
STOMP Simple/Streaming Text Oriented Messaging ProtocolSTOMP is a protocol, coming from the HTTP school of design. It is very easy to write a client to get yourself connected. For example you can use Telnet to login to any STOMP broker and interact with it!
Messaging Application
ConnectionFactory
Destination
JMS Provider(JNDI)
JMS Provider(JNDI)
Connection Session
Message
Message Producer
Message Consumer
JMS 1.1 API Basics
ConnectionFactory
Destination
JMS Provider(JNDI)
JMS Provider(JNDI)
Connection Session
Message
Message Producer
Message Consumer
Queue Connection
Factory
Queue
Queue Connection
Queue Session
Message Sender
Message Receiver
JMS 1.1 API Basics
ConnectionFactory
Destination
JMS Provider(JNDI)
JMS Provider(JNDI)
Connection Session
Message
Message Producer
Message Consumer
Topic Connection
Factory
Topic
Topic Connection
Topic Session
Topic Publisher
Topic Subscriber
JMS 1.1 API Basics
TerminologyQueue Is a channel through which messages are exchanged. Sender The message producer who sends messages to queue is called Sender.Receiver The consumer who consumes messages from Queue is called Receiver.
P2P Messaging
P2P Messaging Model
Receiver Receiver
Sender
P2P Messaging
Receiver Receiver
Sender
busy busy
Queue Depth
P2P Messaging
Interactive Coding
Demonstrate Message SenderDemonstrate Synchronous Message ReceiverDemonstrate Asynchronous Message ReceiverMultiple Message Receivers
P2P Messaging
• Each message is delivered to only one receiver. Multiple receivers may listen on a queue, but each message in the queue may only be consumed by one of the queue’s receivers.
• Messages are ordered. A queue delivers messages to consumers in the order they were placed in the queue by the message server. As messages are consumed, they are removed from the head of the queue (Exception to Priority messages).
• Receivers and senders can be added dynamically at runtime, allowing the system to grow or shrink in complexity over time.
• With the p2p messaging model, the p2p receiver can either push or pull messages, depending on whether it uses the asynchronous onMessage() callback or a synchronous receive() method.
• Messages intended for a p2p queue can be either persistent or non-persistent. Persistent messages survive JMS provider failures, while non-persistent messages do not.
• Messages may also have a priority and an expiration time.• P2P messages are always delivered, regardless of the current connection status of the receiver. Once a message
is delivered to a queue, it stays there even if no consumer is currently connected• There are two types of point-to-point messaging: asynchronous fire-and-forget processing and (a)synchronous
request/reply processing.• Point-to-point messaging tends to be more coupled model that the sender generally knows how the message is
going to be used and who is going to receive it. • supports load balancing, which allows multiple receivers to listen on the same queue, therefore distributing the
load• Point-to-point also offers other features, such as a queue browser that allows a client to view the contents of a
queue prior to consuming its messages.
P2P Messaging Review
TerminologyTopic Is a virtual channel through which messages are exchanged. In P2P world it is similar to Queue.Publisher The message producer who puts the messages into this topic is called publisher (In P2P world it is called
Message Sender). Posting of message to topic is called publishing.Subscriber The consumer who consumes messages from topic is called Subscriber (In P2P world it is Message
Receiver). And registering to topic as listener is called subscription.
Publish Subscribe Model
P2P Messaging Model
Subscriber A Subscriber B
Publisher
Publish Subscribe Model
Durable Vs Non-Durable Subscribers
Subscriber A Subscriber B
Publisher1
1
1 1
2
2
2
3
3
3 3
4
4
Non-Durable Subscribers
Subscriber A Subscriber B
Publisher1
1
1 1
2
2
2
2
2
Durable Subscribers
Interactive Coding
Demonstrate Message PublisherDemonstrate Non-Durable Message SubscriberDemonstrate Multiple SubscribersDemonstrate Subtopic with ActiveMQDemonstrate Subtopic with WebSphere MQ
Publish Subscribe Model
• Each message is delivered to all the active subscribers. Non active durable subscribers receive messages when they become active.
• messaging model is by and large a push-based model, where messages are automatically broadcast to consumers without them having to request or poll the topic for new messages.
• Subscribers can be durable or Non-Durable.
• More decoupled than P2P model that the message publisher is generally unaware of how many subscribers there are or what those subscribers do with the message.
• Does not supports load balancing
• Like P2P model, pub/sub model do not have the concept of message browsing.
Pub/Sub Messaging Review
Publish/Subscribe Point-to-PointEach message is delivered to multiple message consumers.
Each message is delivered to single message consumer
Topics can be durable, non-durable and temporary /dynamic. This is actually based on the subscription type.
Queues can persistent, non-persistent and temporary /dynamic. This based on the Queue creation/configuration type.
Publisher is not aware of which subscribers are receiving the topic messages
Message Sender generally knows how the message is going to be used and who is going to receive it. . For example, a sender may send a stock trade order to a queue and wait for a response containing the trade confirmation number.
You cannot browse topic messages. But consuming messages on a topic does not affect any other consumers, so you don't need to 'browse' per se, just subscribe.
Browsing is necessary on queues as you would like to see what messages there are without removing them.
Publishers can be added at runtime, to handle publish loads. As subscribers are not load balanced not much use of adding more subscribers
Producers and Receivers can be added at runtime, which allows the system to grow or shrink in complexity over time.
Message selectors are applied when the message is copied to each subscriber.
Message selectors are applied after the message has been added to the queue.
Nondurable subscribers receive messages only when that subscriber is active and connected to the topic.durable subscribers receive all desired messages sent to that topic, regardless of subscriber is active
Queues keep messages around for any suitable consumer to consume them. Message alive though there is no active consumer and delivered when a consumer active for that queue.
P2P Vs Pub/Sub
Anatomy of a JMS Message
Text PayloadJava Object payloadMap payloadByte payloadStream payloadEvent payload
HeaderJMS Standard Header PropertiesJMS extended Header PropertiesApp-specific Header Properties
Vendor/Provider specific HeadersBody
JMSMessageIDJMSTimestampJMSDestinationJMSRedeliveredJMSExpirationJMSPriorityJMSDeliveryModeJMSReplyToJMSCorrelationIDJMSType
Header Property Set method Default Value
JMSDeliveryMode setDeliveryMode() PERSISTENT (2)
JMSExpiration setTimeToLive() 0
JMSPriority setPriority() 4
JMSCorrelationID setJMSCorrelationID() null
JMSType setJMSType() null
JMSReplyTo setJMSReplyTo null
JMSMessageID none null
JMSTimestamp none null
JMSDestination none null
JMSRedelivered none false
JMS Message Headers
JMS Extended HeadersJMSXUserIDJMSXAppIDJMSXProducerTXIDJMSXConsumerTXIDJMSXRcvTimestampJMSXDeliveryCountJMSXStateJMSXGroupIDJMSXGroupSeq
JMSXGroupID and JMSXGroupSeq are required to be supported by all JMS providers and only these header values are set by developer. Other headers are set by broker. These optional properties are used to group messages.
There is no corresponding setJMSX<PROPERTY>() and getJMSX<PROPERTY>() methods defined in Message.They must be set in the same manner as application-specified properties:
message.setStringProperty("JMSXGroupID", "ERF-001");message.setIntProperty("JMSXGroupSeq", 3);
Application Specific PropertiesProperty values can be any boolean, byte, short, int, long, float, double, or String. The javax.jms.Message interface provides accessor and mutator methods for each of these property value types.
Property Names cannot be of the following
message.setStringProperty("and","error");
message.setStringProperty("or","error");
message.setStringProperty("not","error");
message.setStringProperty("like","error");
message.setStringProperty("in","error");
message.setStringProperty("between","error");
message.setStringProperty("is","error");
message.setStringProperty("null","error");
message.setStringProperty("true","error");
message.setStringProperty("false","error");
message.setObjectProperty() must only be used to set Strings or primitive wrappers but not java objects. Attempt to violate this will get com.sun.messaging.jms.MessageFormatException: Invalid ObjectType Property.
Application Specific Properties
• Casting can be wider but cannot be narrow i.e., int can be casted to long (read as long), but long cannot be casted to int.
• Most primitive accessors throw the NumberFormatException if a null value or nonexistent property is read. For ex., read a double property with non-existing property will through NullPointerexception.
setProperty getPropertyboolean boolean, Stringbyte byte, short, int, long, stringshort short, int, long, stringint int, long, stringlong long, stringfloat float, double, Stringdouble double, StringString all types
Conversions
Vendor Specific PropertiesEvery JMS provider can define a set of proprietary properties that can be set by the client or the provider automatically. Provider-specific properties must start with the prefix JMS followed by the property name (JMS_<vendor-property-name>). The purpose of the provider-specific properties is to support proprietary vendor features.
Interactive Coding
Demonstrate JMS Message Headers (Expiry, Priority, Delivery Mode,..) Demonstrate Developer Assigned Message headersDemonstrate Temporary QueueDemonstrate Request Reply MessagingDemonstrate Request Reply with QueueRequestor
JMS Message Headers
JMS defined six message types
TextMessageObjectMessageMapMessageByteMessageStreamMessageMessage
Message Types
This type carries a java.lang.String as its payload. It’s useful for exchanging simple text messages and more complex character data like XML documents
Portable with other protocols namely STOMP Simple Text Oriented Message Protocol
General purpose massage such as with payload as XML.
TextMessage
BUY AAPL 1000
BUY AAPL 100 BUY AAPL 100
msg.setText() msg.getText()
Javax.jms.TextMessage
This type carries a serializable Java object as its payload. It’s useful for exchanging Java objects.
using Object Message, both the message producer and the message consumer must be JMS-compatible. Furthermore, the class definition of the object payload has to be available to both the JMS producer and JMS consumer.
Java Object must implement java.io.Serializable interface.
ObjectMessage
TradeOrderorder.setType(“SELL”)order.setStock(“AAPL”)order.setCount(100)
TradeOrderorder.setType(“SELL”)order.setStock(“AAPL”)order.setCount(100)
msg.setObject() msg.getObject()
TradeOrderorder.setType(“SELL”)order.setStock(“AAPL”)order.setCount(100)Javax.jms.ObjectMessage
MapMessage works similarly to JMS properties: any name-value pair can be written to the payload. The name must be a String object, and the value may be a String or a primitive type.
Producer and Consumer Must agreed upon contract of property name and property types. Property names are case sensitive.
This is best suitable for contract extendibility. New properties can be added without affecting existing consumers who may not be interested in those properties.
Attempt to read a name-value pair that doesn’t exist, the value is treated as if it was null.
Most primitive accessors throw the NumberFormatException if a null value or nonexistent mapping is read.
The getBoolean() method returns false for null values; the getString() returns a null value or possibly an empty String (""), depending on the implementation; and the getChar() method throws a NullPointerException.
To avoid reading nonexistent name-value pairs, the MapMessage provides an itemExists() test method. In addition, the getMapNames() method lets a JMS client enumerate the names and use them to obtain all the values in the message.
MapMessage
“operation”, “SELL”“Stock” “AAPL”)“Count” 100)
msg.setString(“operation”,“SELL”)
msg.setString(“Stock”,“AAPL”)msg.setInt(“Count”,100)
msg.setString(“operation”,“SELL”)
msg.setString(“Stock”,“AAPL”)msg.setInt(“Count”,100)
Javax.jms.MapMessage
This type carries an array of primitive bytes as its payload. It’s useful for exchanging data in an application’s native format, which may not be compatible with other existing Message types.
The payload is a raw byte stream, so it is possible to read the stream using arbitrary types, but this will probably result in erroneous data.
Producer and Consumer must be agreed upon the contract for order of bytes.
Must read the BytesMessage’s payload in the same order, and with the same types, with which it was written.
ByteMessage interface provides writeObject() interface to work with primitive wrappers.
The BytesMessage is one of the most portable of the message types, and is therefore useful when communicating with non-JMS messaging clients
The reset() method returns the stream pointer to the beginning of the stream and puts the BytesMessage.
ByteMessage
[B@12b334
msg.writeUTF( “SELL”)msg.writeUTF( “AAPL”)msg.writeInt(100)
msg.readUTF()msg.readUTF()msg.readInt()
Javax.jms.ByteMessage
The StreamMessage carries a stream of primitive Java types (int, double, char, etc.) as its payload.
Primitive types are read from the Message in the same order they were written.
Instream message we write and read as java data types and allows type conversion whereas ByteMessage do not. So it is same as ObjectMessage
The reset() method returns the stream pointer to the beginning of the stream and puts the message in a read-only mode. It is called automatically when the message is delivered to the client. However, it may need to be called directly by the consuming client when a message is redelivered:
if ( strmMsg.getJMSRedelivered() )strmMsg.reset();
StreamMessage
[B@12b334
msg.writeString( “SELL”)msg. writeString( “AAPL”)msg.writeInt(100)
msg.readString()msg.readString()msg.readLong()
Javax.jms.StreamMesage
StreamMessage strongly resembles the BytesMessage, but they are not the same. The StreamMessage keeps track of the order and types of primitives written to the stream, so formal conversion rules apply.
A BytesMessage would write the long as 64 bits (8 bytes) of raw data, so that you could later read some of the data as a short, which is only 16 bits (the first 2 bytes of the long). So you can read a long as two shorts as shown below and the values for shorts.
msg.writeLong(System.currentTimeMillis()) 1423060887647msg.readShort() 0msg.readShort() 331
The same in the above will throw JMSException
ByteMessage Vs StreamMessage
Event Message can be created by session.createMessage() API Call.
No Payload – only message header data.
This is kind is suitable for event notifications with optional header fields
EventMessage
Stock = AAPLPrice = 110.50
msg.setStringProperty( “Stock”,“AAPL”)msg.setDoubleProperty( “Price”,“110.50”)
msg.getStringProperty( “Stock”)msg.getDobleProperty( “Price”)
Javax.jms.Message
This is the most confusing and subject of conflict. Some argue that Dynamic and Temporary Destinations are the same.
Administered destinations are created by administrative tools and/or configuration files outside the application.
Have well-known identities (resolved with JNDI) with both consumers and producers
Creation and Configuration is vendor specific.
Dynamic destinations are created by the applications.
These destinations do not have identities and hence cannot be resolved with JNDI lookup.
Applications using dynamic destinations are not portable.
JMS provides QueueSession.createQueue(String queueName) to create dynamic queue and TopicSession.createTopic(String topicName) for creating dynamic topic
“This facility is provided for the rare cases where clients need to dynamically manipulate queue identity. It allows the creation of a queue identity with a provider-specific name. Clients that depend on this ability are not portable.Note that this method is not for creating the physical queue. The physical creation of queues is an administrative task and is not to be initiated by the JMS API”.
Temporary queues are created by the applications using QueueSession.createTemporaryQueue(String queueName) to create temporary queue and TopicSession.createTemporaryTopic(String topicName) for creating temporary topics.
Only JMS Client application that created temp queues can consume messages from temp queue,however in case of Dynamic destination any client can consume the messages
You cannot create durable subscriber to a temporary topic.
Temporary queue do not support CLIENT_ACKNOWLEDGE and transaction as the life time of the queue is till the connection is active. Once the connection is closed, then queue will get deleted.
Administered Vs Dynamic Vs Temporary Destinations
There is nothing such as Durable and Nondurable queues. Even Persistent and non-persistent literature is also not suggestable.
Persistent and non-persistent is the nature of the messages inside a Queue. As per the JMS specification, the default delivery mode is persistent.
The persistence flag is set on the MessageProducer for all messages using the setDeliveryMode. It can also be specified on a per message basis using the long form of the send method.
Persistence is a property of an individual message.
One argue that Persistence/Durable queues are Administered queues as they survive JMS Server restarts and Dynamic/Temporary queues are non-persistent/non-durable queues.
Durable Vs Non-Durable Queues
A message selector provides a facility to filter the messages that a queue receiver or a topic subscriber receives.• Message selectors are to selectively receive the messages• Based on SQL-92 conditional expression syntax• Criteria based on header properties
Message Selectors are made up of three elements Identifiers, Literals & Operators
Message Selectors
Gender = ’Female’ and Age > 40Gender = ’Female’ and Age > 40Gender = ’Female’ and Age > 40Gender = ’Female’ and Age > 40
Identifiers Literals Operators
Identifiers• Identifiers exact match of header properties (case sensitive)
• Identifier cannot be one of the “not, or like, is, true, and, between, in, null, false” as message selectors are part of SQL-92 where clause
Literals• Contains numbers, Strings and Boolean
• Strings must be enclosed in single quotes. If apostrophe (‘) is part of the string then escape it with another apostrophe. For ex O'Reilly is represented as ‘O'’Reilly’
• Boolean true/false and case insensitive
Operators• Logical : and , or
• Algebra : =, <, >, <=, >=, <>
• Arithmetic: +, -, / , %
• Comparison: like between, not, is null, is not null
Examples:• JMSPriority in (5,7)
• Name like ‘SR%’ or AreaCode like ‘HY_’
• Commison = (price * count * 0.25)
• Age between 45 and 55 (inclusive)
JMS Headers That can be part of message selector are• JMSDeliveryMode
• JMSPriority
• JMSMessageID
• JMSCorrelationID
• JMSType
A reference to non-existing message header will result in null value and a conditional evaluation on such result as unknown.
Message Selectors
Message Selectors
public interface Session extends Runnable {public MessageConsumer createConsumer(Destination dest,String messageSelector)throws JMSException,InvalidSelectorException,InvalidDestinationException; public MessageConsumer createConsumer(Destination dest,String messageSelector,boolean noLocal) throws JMSException,InvalidSelectorException,InvalidDestinationException;} public interface QueueSession extends Session {public QueueBrowser createBrowser(Queue queue, String messageSelector)throws JMSException, InvalidSelectorException, InvalidDestinationException; public QueueReceiver createReceiver(Queue queue, String messageSelector)throws JMSException, InvalidSelectorException, InvalidDestinationException;} public interface TopicSession extends Session {public TopicSubscriber createSubscriber(Topic topic,String messageSelector,boolean noLocal)throws JMSException,InvalidSelectorException,InvalidDestinationException; public TopicSubscriber createDurableSubscriber(Queue queue,String name,String, messageSelector,boolean noLocal)throws JMSException,InvalidSelectorException,InvalidDestinationException;}
Using Message Selectors
JMS Provider Message Consumer
deliver onMessage : start
delivered
acknowledged
removed
onMessage : End
AUTO ACKNOWLEDGE MODE
Guaranteed Message Delivery
JMS Provider Message Consumer
deliver onMessage : start
delivered
acknowledged
CLIENT ACKNOWLEDGE MODE
msg.acknowledge()
removed onMessage : End
Guaranteed Message Delivery
JMS Provider Message Consumer
deliver onMessage : start
delivered
acknowledged
removed
onMessage : End
DUPS_OK ACKNOWLEDGE MODE
Marks the message as delivered when received by client
Guaranteed Message Delivery
Message Groups provide a facility to process all the messages in the batch or process none. In case of exception you would like to process all the messages again.Client cannot selectively consume the messages in a batch.
Message Groups
Sender
Receiver 1
Receiver 2JMXGroupId = grp1
JMXGroupId = grp1
JMXGroupId = grp2
JMXGroupId = grp2
To identify the groups of messages each group is assigned a unique group id to the JMSXGroupID message header property.
To identify the sequence of the message in each group “JMSXGroupSeq” which is an optional property used to sequence each message in the group
Using the JMSXgroupId the messages in a group will get delivered to a single consumer and is called sticky sessions.
If any message is acknowledged in the batch then all the messages delivered before in the batch are acknowledged implicitly. It is always a good practice to acknowledge the only the last message in the group and call session.recover() to get the messages redelivered.
To find if the message is redelivered due to failure in earlier delivery can be known by Messsage.isJMSRedelivered() call.
Interactive Coding
Demonstrate Image upload with Group Message
Message Groups
JMS Producer
JMS Provider
JMS Receiver
Persistent store
send1
persist2
Ack3Send() returns4
receive5
Ack6
Remove from persistent store7
Persistent Message Delivery
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
Persistent store
send1
Persistent Message Delivery – Sender fails
Exception2
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
Persistent store
send1
persist2
Ack3Send() returns4
Provider Fails
Persistent Message Delivery – Provider failure
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
Persistent store
Recover from persistent Store1
receive2
Ack3
Remove from persistent store4
Persistent Message Delivery – Provider Recovery
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
Persistent store
send1
persist2
Ack3Send() returns4
receive5
Consumer Fails6
Persistent Message Delivery – Receiver Fails
7 Message Still in Persistent Store
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
Persistent store
redliver1
Ack2
Remove from persistent store3
Persistent Message Delivery – Redelivery
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
send1
Ack3Send() returns4
receive5
Ack6
Non Persistent Message Delivery
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
send1
Non Persistent Message Delivery – Sender fails
Exception2
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
send1
Ack2Send() returns3 Provider Fails4
Non Persistent Message Delivery – Provider failure
Message Lost
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
send1
Ack2Send() returns3
receive4
Consumer Fails5
Non Persistent Message Delivery – Receiver Fails
Message Still in memory of Provider
Transacted Sessions
JMS Producer
JMS Provider
JMS Receiver
redliver1
Ack2
Non Persistent Message Delivery – Redelivery
Transacted Sessions
Sender JMS Provider Receiver
send
send
receive
exception
First message is already consumed and processed by receiver. Resending will result duplicate message.
Second message might have processed by another receiver or by the time you try to remove it.How to overcome this?
Transacted Sessions
Sender JMS Provider Receiver
send
send
1
122
rollback
exception
Transacted Sessions
Sender JMS Provider Receiver
send
send
1
122
commit
12
receive1
1
receive2
2
exception
rollback
When a rollback issued, JMS provider marks the messages for redeliver and updates the retry count headerJMS provider will attempt to redeliver the messages.
What to do with poison messages and handling poison messages is vendor specific.
Transacted Sessions
Sender JMS Provider Receiver
send
send
1
122
commit
12
receive1
1
receive2
2
commit
Transacted Sessions
Sender JMS Provider Receiver
send
send
1
122
Send process completed normally, but didn’t issued commit() or rollback, What happens?JMS provider do not make any attempt to deliver the messages and they are not marked for deliver.JMS provider eventually removes the messages, but the process is vendor specific.
Transacted Sessions
Sender JMS Provider Receiver
12
receive1
1
receive2
2
Transacted Sessions
Send process completed normally, but didn’t issued commit() or rollback, What happens?
JMS Provider do not mark the messages as delivered and these messages will be redelivered again
Interval at which JMS provider will attempt to redeliver is vendor specific
Client Acknowledge Vs Session Transacted
CLIENT_ACKNOWLEDGE SESSION TRANSACTED
Acknowledge is for each message Acknowledge is on session
Unacknowledged messages is attached to same consumer. Any redeliver attempt will send to same consumer
Unacknowledged messages is available to any consumer.
Applicable to consumer only Applicable for both sender and receiver
Interactive Coding
Demonstrate receiver without transactionDemonstrate receiver with exceptionDemonstrate receiver with transactionDemonstrate receiver with rollbackDemonstrate receiver without commit
Transacted Sessions
QueueBrowser interface provides the facility to browse the queue without consuming the messages.
QueueBrowser browser = session.createQueueBroser(queue);Enumeration<?> e = browser.getEnumeration()
Enumeration is a snapshot of the queue with all messages.
Snapshot is created when the browser is created.
QueueBrowser is only applicable for queues and not available for topics.
What is the use of QueueBrowser?
Programmatic Monitoring queue depth for reporting purposes
Programmatic Monitoring queue depth for self healing
Message auditing
Report on poison messages without consuming them
Metadata
ConnectionMetadata interface provides the information about the provider
JMS version
Provider name and version
JMX/JMSX properties supported
Vendor specific properties
…
Queue Browser & Metadata
For a durable topic subscription, the JMS provider needs to be able to identify when a durable subscriber shuts down and later on in the future reconnects, so it can know what messages to send to it while it was not running.
Each Durable subscriber is identified by the combination of Topic Name, Client-Id and subscription Id. Setting clientID on a JMS connection is vital (along with using a sensible durable consumer name) for durable topic subscription.A
Connection.setClientId(“Client:1”);Session.createDurableSubscriber(topic,”sub:1”);
ClientId can also be set on ConnectionFactory but it is vendor specific.
OpenMQConnectionFactory cf = new ConnectionFactory();cf.setProperty(ConnectionConfiguration.imqConfiguredClientId,”Client:1”)
ActiveMQActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(“tcp://localhost:61616?jms.clientId=Client:1”)
To Stop the messages you must “unsubscribe” . To “unsubscribe” subscription must be closed first.subscriber.close();session.unsubscribe(“sub:1”);
Durable Subscribers
A JMS durable subscriber is created with a unique JMS clientID and durable subscriber name. To be JMS compliant only one JMS connection can be active at any point in time for one JMS clientID, and only one consumer can be active for a clientID and subscriber name. i.e., only one thread can be actively consuming from a given logical topic subscriber.
This means we cannot implement
• Load balancing of messages.
• Fast failover of the subscriber if that one process running that one consumer thread dies.
Durable Subscribers
If the durable subscribers are not unsubscribed and went offline for long time, there the messages pileup and might cause system breakdown.
In ActiveMQ this can be controlled by broker configuration
<broker brokerName=”localhost” offlineDurableSubscriberTimeout=”259200000”offlineDurableSubscriberTaskSchedule=”172800000”dataDirectory=”${activemq.base}/data”>
Remove the subscribers who are offline more than 3 days and run this clean task for every two days.
Using JMX Console<broker brokerName=”localhost” useJmx=”true”
dataDirectory=”${activemq.base}/data”>
Controlling Durable Subscribers
Using JMX Console<broker brokerName=”localhost” useJmx=”true”
dataDirectory=”${activemq.base}/data”>
Controlling Durable Subscribers
Using Admin console
Controlling Durable Subscribers
In publish-subscribe model, we know that each subscriber will get every topic message it is subscribed for.
So starting multiple subscriber will not help for load balancing.
How do we load balance the subscribers?
As JMS specification did not addressed this, each JMS provider addressed this in their different way.
Load balancing subscribers tends to vendor specific.
Load balancing subscribers
Topic SubscriberMessage Processor
Message Processor
Message Processor
Normally message processor are implemented as threads and implemented as not aware of messaging
To participate in transactions, client acknowledge, these processors can also be messaging aware.
This is a approach didn’t bind to any specific vendor.
If the subscriber goes down, then fast failover is not possible.
ActiveMQ support load balancing of subscribers with fast failover using Virtual Topics.
Producers send messages to a topic in the usual JMS way
If the topic is virtual, consumer can consume from a physical queue for a logical topic subscription, allowing many consumers to be running on many machines & threads to load balance the load.
Virtual Topics
Publisher Topic(VirtualTopic.Foo)
Consumer 1
Consumer 2
Consumer 3
Consumer.A.VirtualTopic.Foo
Consumer.B.VirtualTopic.Foo
Virtual topics provides the ability consume messages published when non-durable consumers are offline.
The out-of-the-box defaults as described, virtual topics available must be within the VirtualTopic.> namespace and that the consumer queues are named Consumer.*.VirtualTopic.>.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<broker xmlns="http://activemq.apache.org/schema/core"> <destinationInterceptors> <virtualDestinationInterceptor>
<virtualDestinations><virtualTopic name=">" prefix="VirtualTopicConsumers.*." selectorAware="false"/>
</virtualDestinations> </virtualDestinationInterceptor>
</destinationInterceptors> </broker>
</beans>
name > to indicate 'match all topics'. You could use this wildcard to apply different virtual topic policies in different hierarchies.
Virtual Topics Configuration
Broker Topologies
• Restrict the producers and consumers to java only. This does not support heterogeneous integration. • Application server play dual role as hosting server and JMS provider. • Messaging server consumes lot or Memory, CPU resources and Threads. This may cause slowdown of the
application server resulting a crash • When application server is down, prevents the external message producers and consumers from sending and
receiving messages• useful, in a self-contained Java-based application which utilizes messaging to decouple internal components to
reduce bottlenecks and increase scalability and throughput. It is unlikely that queues and topics used outside the application.
The Internal Destination topology refers to queues and topics that are administered by an application server (e.g., WebLogic) that also hosts web-based or server-based applications.
Broker Topologies
• External Destination Topology refers to queues and topics that are administered on a dedicated system outside of the context of web-based or server-based applications.
• External JMS provider can be deployed inside a dedicated application server, the limitation of JMS only messaging still applicable.
• JMS providers will expose JMS and as well native APIs making it possible for heterogeneous integration.
• Application server down will not impact the message producers and consumers.
• JMS provider can be located on the same machine on which application server deployed based on the server hardware capabilities.
The Internal Destination topology refers to queues and topics that are administered by an application server (e.g., WebLogic) that also hosts web-based or server-based applications.
Broker Topology – Internal /Embedded Broker
This is a standalone broker (application may be a standard java, spring or may be a web application) and not managed by any server but managed by the application started it.
This topology is Useful when you need localized messaging and do not want or need the external broker hassles.• Decouple components inside the application without instantiation• Resolve application bottlenecks• Alternative to Threads inside a container• Increase the scalability of components
Application itself starts a message broker in the same JVM as that of the application is running.
Application Server
Internal JMS Provider
Internal /Embedded BrokerApplication
(Core Java, J2ee, Spring,…)
Internal Broker
(broker1)
classvm://broker1
classvm://broker1
class
class vm://broker1
class
Internal /Embedded Broker
Application 1(Core Java, J2ee, Spring,…)
Internal Broker
(broker1)
classvm://broker1
classvm://broker1
class
Application 2(Core Java, J2ee, Spring,…)
classtcp://broker1:61999
class
classtcp://broker1:61999
tcp://broker1:61999
Internal /Embedded BrokerNot all the JMS providers support embedded broker topology. ActiveMQ and HornetQ are some of the JMSProvider that supports this model.
There are three ways in which the broker can be started in embedded way in ActiveMQ.
Option 1: BrokerService broker = new BrokerService();Broker.addConnector(“tcp://localhost:61888”);Broker.setBrokerName(“Embedded”);Broker.start()
Option 2:
BrokerService broker = BrokerFactory.createBroker(new URI(“broker:tcp://localhost:61888”));
Broker.setBrokerName(“Embedded”);Broker.start()
Internal /Embedded BrokerOption 3:
BrokerService broker = BrokerFactory.createBroker(new URI(“xbean:activemq.xml”));
Broker.start()
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="embedded1" dataDirectory="./data">
<persistenceAdapter> <kahaDB directory="./data/kahadb"/></persistenceAdapter>
<transportConnectors><transportConnector name="openwire“ uri="tcp://0.0.0.0:61888?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/></transportConnectors>
</broker></beans>
Internal /Embedded BrokerAccessing Embedded Broker
Connection con = new ActiveMQConnectionfactory(“vm://embedded”).createConnection();
Connection con = new ActiveMQConnectionfactory(“tcp://localhost:61888”).createConnection();
Limitations on Embedded Broker Topology
Receivers cannot start until embedded broker starts
If persistency not specified on startup, all destinations will get removed when application exits.
Prefer non-persistent messages while using this approach
Careful about the other applications depends on the embedded broker. When the main application terminates, then all the dependent applications are impacted.
Application Code
Spring JMS Framework
JMS API
JMS Provider
Spring JMSSpring Framework provides the support for JMS that greatly simplifies the development of JMS messaging application for sending and receiving messages.
Spring provides an abstraction layer above JMS API
Application Spring Framework JMS Provider
connection factory
Spring JMS Primary Components
destinations
jms template
listener container
message producer
message consumer
jms template
Used for send and receive messages synchronously
Encapsulates the connection, session, producer and consumer functionality
listener container
Used for receiving messages asynchronously
Main component for Message driven Pojos (MDP)
Spring JMS
Spring JMSJMS Provider
Connection factory
Destinations
JndiTemplete
JndiObject FactoryBean
CachingConnection factory
JndiDestination Resolver JmsTemplate
Synchronous Send and receive using JNDI
Spring JMS
ConnectionfactoryNames = connectionFactoryqueue.jms_springQ = jms.spring.q
activemq.xml
<destinations> <queue name=“jms.spring.q” physicalName=“jms.spring.q” /></destinations>
Jndi.properties
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> <property name="environment"> <props> <prop key="java.naming.factory.initial">
org.apache.activemq.jndi.ActiveMQInitialContextFactory</prop> <prop key="java.naming.provider.url">tcp://localhost:61616</prop> <prop key="java.naming.security.principal">system</prop> <prop key="java.naming.security.credentials">manager</prop> </props> </property></bean>
JNDI template
<bean id="jndiConnectionFactory"class="org.springframework.jndi.JndiObjectFactoryBean"><property name="jndiTemplate" ref="jndiTemplate"/><property name="jndiName" value="connectionFactory"/>
</bean>
JNDI Connection Factory
<bean id="connectionFactory"class="org.springframework.jms.connection.CachingConnectionFactory"><property name="targetConnectionFactory" ref="jndiConnectionFactory"/><property name="sessionCacheSize" value="1"/>
</bean>
Caching Connection Factory
<bean id="destinationResolver"class="org.springframework.jms.support.destination.JndiDestinationResolver"><property name="jndiTemplate" ref="jndiTemplate"/><property name="cache" value="true"/><property name="fallbackToDynamicDestination" value="false"/>
</bean>
JNDI Destination Resolver
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"><property name="connectionFactory" ref="connectionFactory"/><property name="destinationResolver" ref="destinationResolver"/><property name="defaultDestinationName" value="queue1"/><property name="receiveTimeout" value="30000"/><property name="pubSubDomain" value="false"/>
</bean>
JMS Template
Spring JMSJMS Template have around 75 methods and most commonly used are the following variants of send and receive methods.
convertAndSendThe convertAndSend methods will invoke a message converter to automatically convert a String object into a JMS TextMessage, a Java object into an JMS ObjectMessage, a byte[] array into a JMS
BytesMessage, and a java.util.Map object into a JMS MapMessage.
SendIf needed to customize the message creation, for ex StreamMessage, then you will create an instance of MessageCreator and use any variants of these methods.
ReceiveThe receive methods are used to block and wait for a message from a specified queue or topic. You can set the receive timeout by setting the receiveTimeout property on the JmsTemplate bean or by invoking the setReceiveTimeout method directly.
receiveAndConvertUsing the default message converter, the receiveAndConvert method will return a String object when receiving a TextMessage, a byte[] array when receiving a BytesMessage, a java.util.Map object when receiving a MapMessage, and finally a Java Object when receiving an ObjectMessage.
receiveSelectedAndConvertTo receive the messages by applying message selector use any variant of these methods.
Interactive Coding
Demonstrate message sender with JMSTemplateDemonstrate message receiver with JMSTemplateDemonstrate MessageCreatorDemonstrate MessagePostProcessorDemonstrate MessageSelectors with JMSTemplateDemonstrate JMSTemplate with native API.
Spring JMS
Spring JMS - MDPSpring framework supports asynchronous receivers through MDPs. Message-driven POJOs are created within the context of a message listener container.
Spring provides two message listener containers:
• DefaultMessageListenerContainer
• SimpleMessageListenerContainer
The only configuration change is to add message listener POJO and container listener
<bean id="messageListener" class="SimpleJMSReceiver"/>
<bean id="jmsContainer” class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="queueConnectionFactory"/><property name="destinationResolver" ref="destinationResolver"/><property name="concurrentConsumers" value="3" /><property name="destinationName" value="queue1"/><property name="messageListener" ref="messageListener" />
</bean>
Asynchronous message listeners can be configured
Implementing javax.jms.MessageListener interface Implementing Spring’s SessionAwareMessageListener Wrapping POJOs in Spring’s MessageListenerAdapter
Spring JMSJMS Provider
Connection factory
Destinations
JndiTemplete
JndiObject FactoryBean
CachingConnection factory
JndiDestination Resolver
DefaultMessageListenerContainer
Spring JMS - MessageListener Interface
POJO Receiver
DefaultMessageListenerContainer
implements
Spring JMSJMS Provider
Connection factory
Destinations
JndiTemplete
JndiObject FactoryBean
CachingConnection factory
JndiDestination Resolver
DefaultMessageListenerContainer
Spring JMS - SessionAwareMessageListener
POJO Receiver
DefaultMessageListenerContainer
implements
SessionAwareMessageListener
Spring JMSJMS Provider
Connection factory
Destinations
JndiTemplete
JndiObject FactoryBean
CachingConnection factory
JndiDestination Resolver
DefaultMessageListenerContainer
Spring JMS - MessageListenerAdapter
POJO Receiver
DefaultMessageListenerContainer
implements
POJO Receiver
MessageListenerAdapter
Spring JMS - MDP
DefaultMessageListenerContainer SimpleMessageListenerContainer
Supports concurrent listeners Supports concurrent listeners
Can dynamically adjust the no of listeners during runtime
Cannot add or remove listeners during runtime
Allows integration with XA transaction managers
Do not support XA transaction mangers but support local transactions.
Interactive Coding
Demonstrate Spring MDP with MessageListenerDemonstrate Spring MDP with SessionAwareMessageListenerDemonstrate Spring MDP with MessageListenerAdapterDemonstrate Spring MDP custom message handlersDemonstrate configure multiple listeners inside a listener-containerDemonstrate Spring JMS embedded broker.
Spring JMS MDP
Restful JMS
Application 1 Applications 2
export
data
File Sharing
Application 1 Application 2 Application 3
Common Database
import
Application 1 Application 2
stub
skelton
Function call
result
RPC (Remote Procedural call)
Application 1 JMS Application 1
Messaging System
Restful JMS
Capability Messaging Web Services Asynchronous Request process Monitoring messages
Guaranteed delivery
Exception Handling
Performance
External Firewall access
Web services Vs. Messaging
Restful JMS is approach to combine the best of breed of messaging and web services to build a hybrid system.
It is always recommended to use the web services if it is required external i.e., outside the firewall remote capability.
If it is internal i.e., inside the firewall remote capability then messaging system is recommended.
Restful JMSNot all the JMS providers support Restful support. Some of the Restful JMS supporting vendors are
• Apache ActiveMQ
• IBM WebSphere MQ
• Jboss HornetQ
Restful JMS url pattern with “myqueue” as the queue name
WebSphere MQ : http://myhost/msg/queue/myqueue
ActiveMQ : http://myhost/approot/message/myqueue?type=queue
HornetQ : http://myhost/approot/queues/myqueue
A couple of questions before dig into details
• Does a GET removes the next message from queue and returns the message or just browse the queue and return first message
• Does a DELETE removes the next message or delete the queue itself
• Does a POST sends a message to the queue or creates the new queue or a temporary queue. If it sends a message, how a queue or temporary queue is created.
Restful JMSWebSphere MQ
HTTP Headers MQMD HeadersText/Plain or Text/Html MQFMT_STRING (string msg)Other media types MQFMT_NONE (binary msg)
HTTP GET MQGET with BrowseHTTP POST MQPUTHTTP DELETE MQGETHTTP PUT no mapping
ActiveMQ
Hidden post variable message header propertiesAny content type TextMessage
HTTP GET receive()HTTP POST send()HTTP DELETE receive()HTTP PUT no mapping
ActiveMQ supports only TextMessage
Restful JMSHornetQ
Jboss HornetQ supports more extended features thru REST interface such as
• Duplicate detection when producing messages• Pull and Push consumers• Acknowledgement and Auto-acknowledgement protocols• Create new queues and topics• Mix and match JMS and REST producers and consumers• Simple transformations
For Restful JMS capabilities of HornetQ visit http://docs.jboss.org/hornetq/2.4.0.Final/docs/user-manual/html/rest.html
Design ConsiderationsMessage Selector / Message Filters
There is a possibility of messages stuck because these messages do not qualify for any message selector criteria defined by the consumers on that queue and then the messages live forever in the queue.
Producer Consumer
Percentage > 70
Producer Consumer
Percentage < 70
What about messageswith percentage = 70
One way to solve the problem is that to specify a message expiry time to each message and let the messages expire if no matching receiver found.
Other way to solve this problem is to have a consumer to have the all negative combinations of existing message selectors defined.
Two Filtering design approaches
• Message Selector
• Multiple Destinations
Filter
Filter
Filter
Design Considerations
Sender
Receiver
Queue Receiver
Receiver
Receiver
Receiver
Receiver
Queue
Queue
Queue
Sender
Receiver/Consumer driven filtering
More “Stuck in Queue” messages
Poor load balancing
Sender/producer driven filtering
Less “Stuck in Queue” messages
Good load balancing
Message Selector / Message Filters
Multiple Destinations
Filter
Filter
Filter
Design Considerations
Sender
Receiver
Queue Receiver
Receiver
ReceiverQueue
A combined approach of Multiple Destinations and Filtering
Message Selector / Message Filters
Design Considerations
Queue Router Multiple Queue
Advantages:Processors are decoupled from messaging infrastructureSupports evolutionary design Processor can be non-aware of JMS
DisadvantagesPoor load balancing, message distribution, concurrency and scalability.
Queue Design Approaches
Advantages:Good message throughput and message distributionScalability, load balancing and performance
DisadvantagesProcessors must be JMS aware, now they are JMS clientsEvolutionary design needs expansion messaging infrastructure
Message Priority
Broker
consumer
consumer
consumer
consumer
msg
msg
Expedited delivery Process time: 5 sec/Msg
Normal delivery Process time: 20 sec/Msg
Design Considerations
Broker
consumer
consumer
consumer
consumer
sender
Message PriorityDesign Considerations
Broker
consumer
consumer
consumer
consumer12345
76
8
5 expedited messages and 3 normal messages received after a second
wait time (sec) Process time (sec)
0000000
1
1
1
10
Message PriorityDesign Considerations
Broker
consumer
consumer
consumer
consumer12345
76
8
wait time (sec) Process time (sec)
19191919191919
20
19
Messages in queue should wait for 19 seconds to get processedAfter 19 seconds the consumers completes the processing
20
20
20
Message PriorityDesign Considerations
Broker
consumer
consumer
consumer
consumer12345
76
8
wait time (sec) Process time (sec)
1919191919191919
Now consumers are free, so expedited messages assigned to consumers
1
3
4
5
1
3
4
5
Message PriorityDesign Considerations
Broker
consumer
consumer
consumer
consumer
2
76
8
wait time (sec) Process time (sec)
242424
24
By the end of 5 seconds, 4 expedited messages processed
1
3
4
5
24
24
24
24
Message PriorityDesign Considerations
Broker
consumer
consumer
consumer
consumer
2
76
8
wait time (sec) Process time (sec)
242424
24
Now receivers are free, expedited message is assigned to a consumerNo more expedited messages, normal messages assigned to remaining consumers
7
2
6
8
7
2
6
8
29
44
44
44
Message PriorityDesign Considerations
1
3
4
5
6
2
8
Processing time (sec) Waiting time (sec)
24
24
24
24
29
44
44
19
19
19
19
24 24
24
When using message priorities, JMS provider will attempt to deliver to available consumer. But there are many chances the message processing might be delayed as experienced aboveIt is suggested to use separate queue for priority messages
7 24 19
Message PriorityDesign Considerations
Broker
consumer
consumer
consumer
268
13457
consumer
consumer
consumer
2
6
8
2
6
8
1
3
4
1
3
4
Processing time (sec)
5
5
5
15 seconds more
15 seconds more
15 seconds more
Message PriorityDesign Considerations
Broker
consumer
consumer
consumer
57
consumer
consumer
consumer
Processing time (sec)
5
7
5
7
15 seconds more
15 seconds more
15 seconds more
2
6
8
10 ( incl 5 sec wait)
10 ( incl 5 sec wait)
10 seconds more
10 seconds more
10 seconds more
Message PriorityDesign Considerations
Separate queuesingle queue
1
3
4
5
6
2
8
Processing time (sec) Waiting time (sec)
24
24
24
24
29
44
44
19
19
19
19
24
24
24
Processing time (sec) Waiting time (sec)
5
5
5
10
10
20
44
0
0
0
5
5
20
24
7 24 19 10 5
When using separate queue, no of concurrent consumers for each queue should be carefully designed.Other wise resources will be misutilized.Browsing queues at periodically you can add or remove consumers at runtime.
Message PriorityDesign Considerations
Performance & ScalabilityPerformance Speed at which JMS Client exchanges the messages thru the JMS Provider.
Scalability Number of concurrent receivers JMS provider support.
Characteristics to Decide
• How many concurrent consumers
Performance_one_jms_client != performance_with_many_clients
• Send rate versus receive rate
• Hardware requirements
• Long duration reliability
• Memory leaks
Performance & ScalabilityHow many concurrent consumers
Concurrent consumers will consume the following resources and all these are limited.
Database connections Memory CPU
Law of diminishing returns
The law of diminishing returns states that in all productive processes, adding more of one factor of production, while holding all others constant, will at some point yield lower incremental per-unit returns.
Performance & Scalability
Performance & Scalability
From the graphs smaller numbers of concurrent consumers return better performance than several hundreds.
High Performance MessagingThough using P2P model we can have concurrent consumers and load balancing, there are times where the JMS infrastructure is not fast enough to handle loads when the velocity and volume of the messages is more.
For ex Telecommunication and E-Commerce applications on special events like New Year, Valentines day, Christmas, Thanks Giving….
Running concurrent consumers on a queue to process multiple messages is some times referred as competing consumers, which will effectively increase the overall throughput of the system.
In Spring MDP, we will specify the number of concurrent consumers as shown below.
<jms:listener-container connection-factory="queueConnectionFactory"destination-resolver="destinationResolver"concurrency=“60"><jms:listener destination="queue1" ref="messageListener1" />
</jms:listener-container>
As expected Spring, do not create 60 concurrent consumers as expected, but very less than 60. This is because spring will create the concurrent consumers considering many aspects.
A small change (specify min-max) will create exactly the required number of concurrent consumers and increases throughput as expected.
<jms:listener-container connection-factory="queueConnectionFactory"
destination-resolver="destinationResolver"concurrency=“60-60"><jms:listener destination="queue1" ref="messageListener1" />
</jms:listener-container>
High Performance Messaging
P2P Vs. Pub/Sub Model
Pub/Sub messaging is significantly faster compared to P2P model especially when increased loads. The main reason for this is because of the architectural difference. Pub/Sub model is push based and P2P is pull model.
The JMS specification does not specifically state how the p2p and pub/sub models must be implemented. Either one may use push or pull, but at least conceptually pub/sub is push and p2p is pull.
Though P2P model have competing consumers and load balancing, there are many times where you can not process messages in parallel and forced to process sequentially. In such cases you have only option to one consumer per queue, which will slowdown the performance.
High Performance Messaging
This graph is by Mark Richards analysis on WebSphere MQ.
As the number of messages per second increases there is significant difference between p2p and pub/sub
These results vary based on how P2P and Pub/Sub model is implemented by provider.
It is advised to do the similar exercise with the JMS provider you plan to use.
High Performance MessagingUsing multiple queues
As we seen in previous slides and labs, increase the concurrent consumers overall increase of system throughput.
Each message consumer consumes resources such as memory, CPU, Threads and database connections and so on.
There is a practical limit on the number of concurrent consumer that can be used. As we learned “Law of diminishing returns”, there is a point where adding consumer will decrease the system performance.
SenderConsumer
Sender
Consumer
Consumer
Consumer
Keeping the same number of concurrent consumers and using multiple queues, you can see the significant performance improvement.
High Performance Messaging
High Performance MessagingUsing multiple queues
How do we implement Multiple Queues mechanism?
String[] queues = { “ORDER1.Q”, “ORDER2.Q”, “ORDER3.Q” }
queueIndex = (queueIndex == queues.length – 1) ? 0 : queueIndex + 1
Jms.convertAndSend( queues [queueIndex], msg)
High Performance MessagingMessage Persistence overhead
JMS by default persist the messages before any consumer consumes message. The main reason for doing so is to provide guaranteed message delivery
Guaranteed message delivery is associated with a COST of performance.
JMS 2.0 – Specification Summary
Simplified API Classic API Updates
MDB config updates
API Changes
Async Send Shared subscribers
Delivery Delay
New Features
Delivery Count
JMS 2.0 – Simplified API
JMS 2.0 introduced three new interfaces
javax.jms.JMSContext implements java.lang.AutoCloseable
javax.jms.JMSProducer
javax.jms.JMSConsumer implements java.lang.AutoCloseable
JMS 2.0 – JMSContextCombines the Connection and Session functionalityCreated from ConnectionFactory
void start()
void commit()
void rollback()
JMSConsumer createConsumer()
JMSConsumer createDurableConsumer()
JMSConsumer createSharedConsumer()
JMSConsumer createSharedDurableConsumer()
JMSProducer createProducer()
Message createMessage() (and other message types as well)
Queue createQueue()
Topic createTopic
JMSContext createContext()
JMS 2.0 – JMSProducerReplaces MessageProducer
Created from JMSContext
Allows to send messages without creating Message object except stream message
jmsContext.createProducer().send(queue, “Welcome to JMS 2.0”)
Uses builder pattern to string methods together (dsl like building)
void send()
void setAsync()
void setDeliveryMode()
void setDeliveryDelay()
void setTimeToLive()
void setProperty(String propertyName, <T> propertyValue)
<T> get<T>Property()
void setJMS…() set JMS header properties
JMS 2.0 – JMSConsumerReplaces MessageConsumer
Created from JMSContext
Allows to receive payload without having Message object
String payload = jmsConsumer.createConsumer(queue).receiveBody(String.class)
Uses builder pattern to string methods together (dsl like building)
Message receive()
<T> T receiveBody()
<T> T receiveBodyNoWait()
Message receiveNoWait()
void setMessageListener()
JMS 1.1 – Classic API Issues
Context context = new InitialContext();
ConnectionFactory factory = context.lookup("ConnectionFactory");
Connection connection = factory.createConnection("system","manager");
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue requestQ = (Queue)context.lookup("jms-queue");
qConnect.start();
TextMessage message = qSession.createTextMessage("Hello World");
MessageProducer producer = qSession.createProducer(requestQ);
producer.send(message);
connection.close();
Interactive Coding
Simple Message ProducerSimple Message ReceiverSetting Header properties
JMS 2.0
JMS 2.0 - Shared Subscriptions
Publisher
Subscriber Subscriber
Publisher
Subscriber
Subscriber
Subscriber
Subscriber
JMS 1.1 JMS 2.0
JMS 2.0 – Delivery Delay
Sender JMSProvider Receiver
setDeliveryDelay(10000) Message will wait for 10000 seconds from time it received before attempted to deliver
send() receive()
JMS 2.0 – Delivery Count
Sender JMSProvider Receiver
send()receive()
1
2 Processing failed
receive()
delivery count 1
delivery count 2
Backout Q Failed twice, move to backout Q
Interactive Coding
Demonstrate shared subscriptionsDemonstrate Delivery DelayDemonstrate Delivery Count
JMS 2.0