40
© 2010 SpringSource, A division of VMware. All rights reserved CONFIDENTIAL © 2010 SpringSource, A division of VMware. All rights reserved CONFIDENTIAL Messaging in the Cloud AMQP, RabbitMQ and Spring

Messaging in the Cloud - AMQP, RabbitMQ and Spring

Embed Size (px)

DESCRIPTION

Shows how AMQP and RabbitMQ messaging work with Spring.

Citation preview

Page 1: Messaging in the Cloud - AMQP, RabbitMQ and Spring

© 2010 SpringSource, A division of VMware. All rights reserved

CONFIDENTIAL

© 2010 SpringSource, A division of VMware. All rights reserved

CONFIDENTIAL

Messaging in the Cloud

AMQP, RabbitMQ and Spring

Page 2: Messaging in the Cloud - AMQP, RabbitMQ and Spring

2

Messaging in the Cloud

  Need new levels of scalability

  Need a standardized wire protocol • Won't ship a specific client for each environment

•  Better interoperability

  JMS only defines an API and behavior, but no protocol

  AMQP defines a protocol

Page 3: Messaging in the Cloud - AMQP, RabbitMQ and Spring

3

Why AMQP?

  Interoperability – like TCP and unlike JMS • RabbitMQ leading the 2009 interoperability push around AMQP 0-9-1 towards

AMQP 1.0

 Multiple vendors on one open, royalty-free standard •  You are not locked in

•  Lower risk, lower price because of competition, easier to compare •  Products specialized around different areas of value e.g low latency, high

stability, wide area

  Efficient – designed for today’s pubsub and queueing needs •  Binary wire protocol •  Support in all major languages

•  Supported on most OS platforms

  Already in use by many major companies   Future proof – backed by Cisco, Microsoft, VMware and many more

Page 4: Messaging in the Cloud - AMQP, RabbitMQ and Spring

4

Broad platform and vendor support...

Page 5: Messaging in the Cloud - AMQP, RabbitMQ and Spring

5

RabbitMQ is used a lot in the Amazon Cloud   RabbitMQ preferred to Amazon SQS

Page 6: Messaging in the Cloud - AMQP, RabbitMQ and Spring

6

Key AMQP messaging protocol requirements

  Internet protocol - like HTTP, TCP - but ASYNCHRONOUS

  Ubiquity: Open, easy & low barrier to use, understand and implement

  Safety: Secure and trusted global transaction network   Fidelity: Well-stated message queuing, ordering and delivery

semantics   Applicability: any broker can talk to any client, support common

messaging pattern and topologies   Interoperability  Manageability: Binary, scalable

Page 7: Messaging in the Cloud - AMQP, RabbitMQ and Spring

7

AMQP  in  a  nutshell  

AMQP protocol

AMQP protocol

Different languages Ruby, Java …

X

C

C

C

X

P

P

Page 8: Messaging in the Cloud - AMQP, RabbitMQ and Spring

8

Exchange Types: Matching Algorithms

  Direct • Routes on a routing key

•  Two direct exchanges always exist •  amq.direct and the default exchange (with no public name) are mandatory

  Topic • Routes on a routing pattern

•  amq.direct is mandatory if the server supports topic exchanges •  Which it should according to the spec (whereas direct and fanout must be supported)

  Fanout •  Simple broadcast to all bound queues (no args when binding). Fast

•  amq.fanout is mandatory

Any Exchange that routes Messages to more than one queue will create multiple instances of the Message.

Page 9: Messaging in the Cloud - AMQP, RabbitMQ and Spring

9

AMQP in more detail

Messages are stateless

X

C

C

C

X

P

P

Page 10: Messaging in the Cloud - AMQP, RabbitMQ and Spring

10

AMQP in more detail

Exchanges are stateless routing tables.

Queues buffer messages for push to consumers

Queues are stateful, ordered, and can be persistent, transient, private, shared. Order might change if messages are redelivered

X

C

C

C

X

P

P

X

Page 11: Messaging in the Cloud - AMQP, RabbitMQ and Spring

11

AMQP in more detail

X

C

C

C

X

P

P

Queues are bound to named exchanges Binding can have a pattern e.g. “tony” (direct exchange) or “*.ibm.*” (topic exchange)

Page 12: Messaging in the Cloud - AMQP, RabbitMQ and Spring

12

AMQP in more detail

X

C

C

C

X

P

P

Producers send messages to exchanges with routing key e.g. “tony”, or ordered set of keys e.g. “buy.ibm.nyse”

Exchanges route messages to queues whose binding pattern matches the message routing key or keys

P

X

Page 13: Messaging in the Cloud - AMQP, RabbitMQ and Spring

13

Twi1er  style  pubsub  message  flow  

Tony

Anders

Evan

X

C

C

X

P

P is at work

is at work

is at work

is at work

is at work

Evan and Anders want to follow what Tony says: •  bind queues to a RabbitMQ exchange •  pattern “tony”.

Tony publishes “is at work” to exchange using routing key “tony”. Exchange updates Evan’s and Anders’ queues

Other patterns are possible e.g. for filtering by topic similar to this: http://jchris.mfdz.com/posts/64

Page 14: Messaging in the Cloud - AMQP, RabbitMQ and Spring

14

Producers  and  consumers  logically  interact  through  a  broker  cloud  

X

C

C C

X

P

P P P

P P

C

Page 15: Messaging in the Cloud - AMQP, RabbitMQ and Spring

© 2010 SpringSource, A division of VMware. All rights reserved

CONFIDENTIAL

RabbitMQ and Spring

Page 16: Messaging in the Cloud - AMQP, RabbitMQ and Spring

16

Configuring Rabbit Resources with Spring

  Spring enables decoupling of your application code from the underlying infrastructure

  The container provides the resources   The application is simply coded against the API

Page 17: Messaging in the Cloud - AMQP, RabbitMQ and Spring

17

<bean id="connectionFactory" class="org.sfw.amqp.rabbit.connection.CachingConnectionFactory"> <property name="username" value="guest"/> <property name="password" value="guest"/> <property name="channelCacheSize" value="42"/> <property name="hostName" value="localhost"/> </bean>

Configuring a ConnectionFactory

Caches connection i.e. connection has to be stateless i.e. can only be used for transactional access only (connection is stateful) Otherwise use com.rabbitmq.client.ConnectionFactory

Page 18: Messaging in the Cloud - AMQP, RabbitMQ and Spring

18

Queues in RabbitMQ

 Queue deliver messages to at max one consumer  Messages are sent to an exchange and can be routed to one or

multiple queues  Meta data about RabbitMQ Queues is stored in

org.springframework.amqp.core.Queue: •  String name

•  boolean durable •  boolean exclusive : private to one consumer

•  boolean autoDelete

 Meta data can be used with RabbitAdminTemplate • Call declare() to actually start using the Queue

  Afterwards they are identified by name  Queues are bound to exchanges with routing keys   Default: Bound using the name of the queues as routing key

Page 19: Messaging in the Cloud - AMQP, RabbitMQ and Spring

19

Exchanges in RabbitMQ

 Meta data about RabbitMQ Exchanges is stored • DirectExchange : String as routing key, Queue binds to exchange with key

•  FanoutExchange : No routing, what goes in must go out •  TopicExchange : Pattern as routing key

  String name   boolean durable   boolean autoDelete   Each message received by an exchange will be delivered to each

(qualifying) Queue bound to it

Page 20: Messaging in the Cloud - AMQP, RabbitMQ and Spring

20

Spring’s Templates

  AmqpTemplate: Generic AMQP interface   RabbitOperations: Rabbit specific interface: (adds just a callback)   RabbitTemplate: Implementation

  Spring might provide support for other AMQP implementations later   Common interface

Page 21: Messaging in the Cloud - AMQP, RabbitMQ and Spring

21

Spring’s Templates

  Central point to send and receive messages  Manages resources transparently   Throws runtime exceptions   Provides convenience methods and callbacks

public Message receive() public Message receive(final String queueName)

public void send(MessageCreator messageCreator) public void send(String routingKey, MessageCreator messageCreator) public void send(String exchange, String routingKey, MessageCreator

messageCreator)

Page 22: Messaging in the Cloud - AMQP, RabbitMQ and Spring

22

MessageConverter

  The RabbitTemplate uses a MessageConverter to convert between objects and messages

  The default SimpleMessageConverter handles basic types •  byte[] directly transfered

•  String converted to byte[] •  Serializable serialized to byte[]

• Content type set accordingly

  JsonMessageConverter converts from / to JSON using Jackson  MarshallingMessageConverter converts from / to XML using

Spring's OXM mapping

Page 23: Messaging in the Cloud - AMQP, RabbitMQ and Spring

23

<bean id=“rabbitTemplate” class=“org.springframework.amqp.rabbit.core.RabbitTemplate”> <property name=“connectionFactory” ref=“connectionFactory”/> <property name=“messageConverter” ref=“messageConverter”/> <property name=“routingKey” value=“app.stock.request”/> </bean>

Defining a RabbitTemplate Bean

  Provide a reference to the ConnectionFactory  Optionally provide other references

• MessageConverter

• Routing key and exchange to be used if none is specified

Page 24: Messaging in the Cloud - AMQP, RabbitMQ and Spring

24

Sending Messages

  The template provides options • One line methods that leverage the template’s MessageConverter

• Callback-accepting methods that offer more flexibility

  Use the simplest option for the task at hand

Page 25: Messaging in the Cloud - AMQP, RabbitMQ and Spring

25

public void convertAndSend(Object object);

public void convertAndSend(String routingKey, Object object);

public void convertAndSend(String exchange, String routingKey, Object object);

Sending Messages with Conversion

  Leveraging the template’s MessageConverter

Page 26: Messaging in the Cloud - AMQP, RabbitMQ and Spring

26

 When more control is needed, use callbacks

public void convertAndSend(String routingKey, Object message, MessagePostProcessor messagePostProcessor);

public void send(MessageCreator messageCreator); public void send(String routingKey, MessageCreator messageCreator); public void send(String exchange, String routingKey, MessageCreator messageCreator);

Message createMessage() {…}

Sending Messages with Callbacks

Page 27: Messaging in the Cloud - AMQP, RabbitMQ and Spring

27

getRabbitTemplate().convertAndSend(tradeRequest, new MessagePostProcessor() {

public Message postProcessMessage(Message message) throws AmqpException { message.getMessageProperties().setReplyTo( new Address(defaultReplyToQueue)); try { message.getMessageProperties().setCorrelationId( UUID.randomUUID().toString().getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { throw new AmqpExcpetion(e); } return message; }

});

Setting the reply to / correlation ID

  Allows request / reply schema i.e. wait for the reply to the specific message

  Planned: sendAndReceive() as a direct implementation of this pattern

Page 28: Messaging in the Cloud - AMQP, RabbitMQ and Spring

28

  The RabbitTemplate can receive messages also •  receive() : Message

•  receive(String queueName) •  receiveAndConvert()

•  receiveAndConvert(String queueName)

  If no message is on the queue null is returned   If no queueName is provided the queue name or queue set at the

template will be used   The MessageConverter can be leveraged for message reception as

well Object someSerializable = rabbitTemplate.receiveAndConvert();

Synchronous Message Reception

Page 29: Messaging in the Cloud - AMQP, RabbitMQ and Spring

29

  The API defines this interface for asynchronous reception of messages

public void onMessage(Message) { // handle the message }

The MessageListener

Page 30: Messaging in the Cloud - AMQP, RabbitMQ and Spring

30

Spring’s MessageListener Containers

  Spring provides lightweight containers to call MessageListeners   SimpleMessageListenerContainer   Advanced scheduling and endpoint management options available

Page 31: Messaging in the Cloud - AMQP, RabbitMQ and Spring

31

Defining a plain Message Listener

<bean id="messageListenerContainer" class="org.sfw.amqp.rabbit.listener.SimpleMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory" /> <property name="queueName" value="#{marketDataQueue.name},#{traderJoeQueue.name}"/> <property name="concurrentConsumers" value="5" /> <property name="messageListener" ref="messageListenerAdapter" /> </bean>

Page 32: Messaging in the Cloud - AMQP, RabbitMQ and Spring

32

Spring's message-driven objects

  Spring also allows you to specify a plain Java object that can serve as a listener

  Parameter is automatically converted using a MessageConverter   Return value sent to response-destination or the reply to  Method with matching parameters is automatically called

<bean id="messageListenerAdapter" class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter"> <property name="delegate" ref="clientHandler" /> <property name="messageConverter" ref="jsonMessageConverter" /> </bean>

Page 33: Messaging in the Cloud - AMQP, RabbitMQ and Spring

33

Demo: Hello World

  Producer send message using the RabbitTemplate   Routing key : helloWorldQueue name "hello.world.queue"  Goes to Default Exchange  …and therefore to the helloWorldQueue (routing by name)   Consumer receives message using the default receive queue

(helloWorldQueue)

P X

Default Exchange

Routing key: hello.world.queue

helloWorldQueue "hello.world.queue"

C

Page 34: Messaging in the Cloud - AMQP, RabbitMQ and Spring

34

Demo: Stock Exchange

  Server sends stock prices   Client receives stock prices   Client can issue orders  Orders are processed by the server   Client receives confirmation of the trade

 Queues are private for one client

Page 35: Messaging in the Cloud - AMQP, RabbitMQ and Spring

35

Server sends stock prices

P X

Topic Exchange app.stock.marketdata

Routing key: app.stockes.quote.?.? e.g. app.stockes.quote.nasdaq.ORCL

RabbitMarketDataGateway called periodicaly

Page 36: Messaging in the Cloud - AMQP, RabbitMQ and Spring

36

Client receives stock prices

  Binding is created to attach the exchange to the queue using the routing key

X

Topic Exchange app.stock.marketdata

Routing key: app.stock.quotes.nasdaq.*

marketDataQueue (private per consumer)

C

ClientHandler in SimpleMessageListenerContainer with jsonMessageConverter and a MessageListenerAdapter

Page 37: Messaging in the Cloud - AMQP, RabbitMQ and Spring

37

Client can issue orders

  traderJoeQueue is set as reply to for the message

P X

Default Exchange

Routing key: app.stock.request

Page 38: Messaging in the Cloud - AMQP, RabbitMQ and Spring

38

Server processes order

  Reply (i.e. confirmation) is sent to the reply to (trader Joe queue)

X

Default Exchange

stockRequestQueue "app.stock.request"

C

ServerHandler in SimpleMessageListenerContainer with jsonMessageConverter and a MessageListenerAdapter

Page 39: Messaging in the Cloud - AMQP, RabbitMQ and Spring

39

Client receives confirmation of the trade

  Binding is created to attach the exchange to the queue using the routing key

X

Default Exchange traderJoeQueue

C

ClientHandler in SimpleMessageListenerContainer with jsonMessageConverter and a MessageListenerAdapter

Page 40: Messaging in the Cloud - AMQP, RabbitMQ and Spring

40

Conclusion

  Ubiquitous Messaging   AMQP: Protocol standard   Better scalability

  http://springsource.org/spring-amqp   Also a .NET version available