messaging. objectives understand the basics of messaging-based communication – what messaging is...

80
Messaging

Upload: dorthy-atkinson

Post on 13-Dec-2015

225 views

Category:

Documents


6 download

TRANSCRIPT

Messaging

Objectives• Understand the basics of messaging-based

communication– what messaging is– how messaging works

• Recognize when to use it– what messaging offers– what complications messaging presents

• Learn some of the patterns around messaging– message-exchange patterns– architectural communication approaches

• See some concrete messaging plumbing

The Goal

• Applications need to talk to one another– no violations of the "Once and Only Once" rule– processing sometimes needs centralization for correctness– processing sometimes needs distribution for scale– either way, machines need to talk to machines

• The traditional answer has been RPC– "make it look like a function call"– define an interface (for compilation type-safe

requirements)– write server-side implementation– tools generate the plumbing necessary between the two

RPC Programming Model

public long add(long l1,long l2);

compiler

add method

stub

Method: addParams: 5(long),10(long)

Return: 15(long)

add methodskeleton

Response message

long I = add(5,10);

public long add(long l1,long l2) {

return l1+l2;}

Request message

The Problem• RPC can't solve all communication issues– What if the network connectivity is flaky or periodically

out?traveling salesmen, dial-up connections, wireless …

– What if we get huge burst loads?"the Slashdot effect"

– What if we need to scale out?"today Duluth; tomorrow, the world!"

– What if we need to offer priority to certain clients?"It's the VP on port 34865, and he's in a hurry…"

– What if we need transactional semantics when communicating with multiple recipients?

"When it absolutely, positively has to be there"– What if we evolve?

"We didn't know we needed it when we wrote the spec!"

The Issues

• RPC enables easy communication, at a cost:– request/response communication

• for every request, we expect a response• block caller thread until response is received

– servers and servants must be available and well-known• RPC proxies typically "pin" against a given serverservant object must be up & running to answer• if server or servant dies, RPC proxies will fail

– proxies and stubs are compile-time constants• strong binding/typing makes programming easier• but makes evolution/change harder

• RPC exposes behavior

A Solution: Messaging• Strip the veneer off RPC– RPC == request message + response message– break the messages apart, treat them independently– allows for different message exchange patterns

• request-response• fire-and-forget• solicit-notify• request-async response

• Messaging exposes data– instead of creating contracts based on interfaces (RPC) …– create contracts based on message types (Messaging)– Note: seductively similar to RPC

"On a NewCustomer message, create a new customer…"– strive for context-complete communications

What is messaging?

• Anatomy of a MOM system– Message = headers (routing info) + payload

• Delivery can be asynchronous• Format is unspecified (loosely bound)

– Destination = named message repository• Decouples message producer/consumer• Allows for easier redirection/change of call flow

– Runtime = variety of delivery semantics• Reliable, transacted, prioritized, deadline-based, publish-and-subscribe etc• Provides one or more channels to deliver messages

Messaging System Examples• File transfer

– Messages: files– Destination: filesystem subdirectory– Runtime: operating system

• Shared database– Messages: data tuples– Destination: database tables– Runtime: database

• JMS/MSMQ– Messages: byte, text, object, stream, map– Destination: queues (point-to-point), topics (publish-subscribe)– Runtime: MOM support

• SOAP– Messages: SOAP XML format– Destination: (depends on transport)– Runtime: Axis, WebLogic, etc

Why use messaging?

• Benefits of a MOM system– Use messaging for flexibility– Use messaging to smooth out burst loads– Use messaging for system integration

Why use messaging?• Use messaging for flexibility

– Application now has many more data flow optionsFire-and-forget, multicast, disconnected, load-balancing, flow control, priority routing, etc

– Permits more granular processing logic• Routing Slip [EAI] "routes a message consecutively through a series of processing steps when the sequence of steps is not known at design-time and may vary for each message"• Content-Based Router [EAI] "handles a situation where the implementation of a single logical function (e.g., inventory check) is spread across multiple physical systems"

– Permits easier maintenance and evolution• change message format without recompiling uninterested clients• "flow" data from one side to another without modifying intermediate peers

– Avoid concurrency deadlocks (due to blocking on RPC response)

Why use messaging?

• Use messaging to smooth out burst loads– queues can fill up with messages waiting to be

processed– processors/consumers pull messages as fast as

possible– if processor nodes can't keep up...

• add more processors• wait for the burst load to disperse over time

Why use messaging?

• Use messaging for system integration– messaging doesn't require agreement on type system

• message is the type• no agreement on "object semantics" necessary

– messaging doesn't require strongly-bound APIs– messaging can bridge several systems (Java, .NET, etc)

• XML is absolutely perfect for this• other data representations (CSV, NDR, plain text) work too

– messaging's flexibility permits easier integration• Message Translators [EAI] permit transmutation of message• Message Routers [EAI] enable processing workflow

Why use messaging?

• Complications of a message-based system– communication is with queues, not objects

bidirectional communication requires at least two queues: one for the request message, one for the response

– no sense of conversational state• sequence—messages may arrive out of order• synchronous communication requires addt’l work

– no sense of "object identity"• messages come to queues, not objects• disruption of the usual "client-server" approach• more like "producer-consumer" or "peer-to-peer"

• For request/response communication, stick with RPC!

Simple Messaging

Sometimes you've just gotta get back to basics

Simple Messaging• Messaging systems have long been a part of enterprise systems

– batch file processing (file == message)– email (email message == message)– database (database tuple(s) == message)

• Plus a few new ones have cropped up in recent years– instant messengers (instant message == message)– HTTP request (request body == message)

• When combined with XML (or SOAP) as data payload...• Make use of these!

– in essence, project the RESTful model on the other parts of the systems in your enterprise

REST• Representational State Transfer (REST)– doctoral thesis of Roy Fielding (Apache chair, 2000)– "Using elements of the client/server, pipe-and-filter, and

distributed objects paradigms, this ['representational state transfer'] style optimises the network transfer of representations of a resource. A Web-based application can be viewed as a dynamic graph of state representations (pages) and the potential transitions (links) between states. The result is an architecture that separates server implementation from the client's perception of resources, scales well with large numbers of clients, enables transfer of data in streams of unlimited size and type, supports intermediaries (proxies and gateways) as data transformation and caching components, and concentrates application state within the user agent components."

REST• In other words…– REST takes the position that the Web as it currently exists is all we really

need—why reinvent the wheel?• URIs provide unique monikers on the network • HTTP provides commands and request/response• HTML/XML provides content format

– a RESTful model seeks to establish "resources" and use the basic CRUD methods provided by HTTP (GET, POST, PUT, DELETE)• find an Employee:

GET /employeeDatabase?name='fred' – returned content body will be employee data

• creating a new Employee: PUT /employeeDatabase

– content body is the employee data• modify an existing Employee:

POST /employeeDatabase?name='fred'

REST

• "Resource Modeling"– goal of RESTful system is to model the data elements

• addressable resources (via URIs)• uniform interfaces that apply to all resources• manipulation of resources through representations• stateless self-descriptive messages• 'representations'—multiple content types accepted or sent

– in essence, we're organizing a distributed application into URI addressable resources that provide the full capabilities of that application solely through HTTP

– this is a complete flip from traditional O-O• objects encapsulate data behind processors• REST hides processing behind data elements/structures

REST

• There's something to be said for this model– consider the World Wide Web:

• well-established, well-documented, "debugged"• no new infrastructure to establish• payload-agnostic• well-defined solutions (HTTPS, proxies, gateways)• obviously extensible (WebDAV, explosive growth)• platform-neutral and technology-agnostic

– it's hard to argue with success!

REST

• Advantages– REST provides "anarchic scalability"

• assumes there is no one central entity of control• architectural elements must continue operating when subjected to unexpected load ("the Slashdot effect")

– REST allows for independent deployment• hardware/software can be introduced over time w/o breaking clients (the power of the URI and DNS)• not all participants need change/evolve simultaneously

– REST returns us to simplicityit's all URLs, HTTP, and HTML/XML; nothing else

REST

• Disadvantages– REST depends a great deal on underlying

technology• HTTP uses simple name/value pairs for headers• this leaves out complex headers (a la WS-Sec)

– REST requires a loosely-bound API• “interface genericity”• no metadata constructs to key from

– REST requires more work on your part

EMail Access

• Simple Mail Transfer Protocol (SMTP)– Internet standard for the better part of a decade

• Post Office Protocol (v3) (POP3)– Internet standard for storing and allowing user email download– widely supported, particularly for web-based email systems

(Hotmail, Yahoo! mail, etc)

• Internet Mail Access Protocol (v4) (IMAP4)– Internet standard for storing and accessing email– more sophisticated than POP3, less widely supported

• All are straight text-based protocols

EMail Access

• JavaMail– "provides a set of abstract classes defining objects that

comprise a mail system."– targets three kinds of developers:

"client, server, or middleware developers interested in building mail and messaging applications…""application developers who need to 'mail-enable' their applciations""service providers who need to implement specific access and transfer protocols" (using JavaMail to contact pagers, for example)

– Java enterprise developers are a little bit of all three!

EMail Access

• System.Web.Mail– specifically geared towards sending SMTP mail– Assembly: System.Web.dll– MailMessage: encapsulates the message itself

• Most properties self-descriptive (To, From, etc)• Attachments property allows for mail file attachments (MailAttachment objects)• custom headers added via Headers property

– SmtpServer: static class encapsulating access to SMTP server• Send sends message to SMTP server• Note: no SMTP authorization capability; be careful when setting this up to avoid creating an open-relay server(!)

• No POP3/IMAP support in .NET 1.1

EMail Access

• Example: Sending mailMailMessage msg = new MailMessage();msg.To = "[email protected]";msg.From = "[email protected]";msg.Subject = "Order-4512345112";msg.Body = "<order> ... </order>";

msg.Headers["X-OrderPriority"] = "Normal"; // could use normal email Priority header, if desired

msg.Attachments.Add( new MailAttachment(@"C:\docs\foo.pdf", MailEncoding.Base64));msg.Attachments.Add( new MailAttachment(@"C:\temp\input4512345112", MailEncoding.Base64));

SmtpMail.SmtpServer = "localhost";SmtpMail.Send(msg);

Other Access

• File Transfer Protocol (FTP)– simple file transfer from one machine to another– well-known/understood security implications

authenticationports & firewall accessibility

– Java: Apache Commons Net– .NET: Support coming in Whidbey FCL

• Straight sockets: TCP, UDP– Java: java.net.*– .NET: System.Net.Sockets

Java Messaging System (JMS)

Messaging-Oriented Middleware,Java style

JMS: Java Messaging Service

• Specification for messaging in Java– currently at 1.1– package javax.jms.*

• Captures essence of messaging– Synchronous or asynchronous operation– Loosely- or strongly-coupled operation– Point-to-point and publish-and-subscribe– Guaranteed or fast delivery– Transacted send/receive– Prioritized delivery– Deadline-based delivery– Delivery filtering

Modes of operation

• JMS defines two modes:– point-to-point: consumer "takes" message– publish-subscribe: consumer "copies" message

• APIs are syntactically and semantically similar– both sets inherit from common base classes

JMS Queues

• Point-to-point:

Queue

sender

Message Message Message

sender

receiver

receiver

receiver

JMS Topics

• Publish-subscribe:

Topic

publisher

Message Message Message

publisher

durable subscriber(attached)

transient subscriber(attached)

transient subscriber(detached)

durable subscriber(detached)

Delivered atre-attachment

Programming Model

• Mostly identical for both P2P and PubSub:– Factories obtained from JNDI for bootstrapping– Connections: physical connection to JMS provider– Sessions: thread-scoped context for sending/receiving msgs– Destinations: obtained from JNDI representing the endpoints– (Examples are all P2P; see docs for PubSub equivalents)

• Factories and Destinations called Administered Objects– intended to be set up by sys admin, not programmers– some JMS providers offer programmatic API

Programming Model

ConnectionFactory

Destination

Connection

Session

creates

MessageProducer

MessageConsumer

creates

creates based on

based oncreates

sync consume(polling)

produce

Administered Objects found via JNDI but created and configured via a provider-specific technique

MessageListenerasyncconsume(callback)

async consume(callback)

Message

Programming Model

• Creating the Connection:– look up ConnectionFactory, create Connection– call start only after all setup is complete: race

condition!– one Connection instance per JVM is usually

enoughString qfname = "jms/MyQueueConnectionFactory"; // Names chosen by system administrator // when setting up the JMS provider

Context ctx = new InitialContext();QueueConnectionFactory qfac = (QueueConnectionFactory)ctx.lookup(qfname);QueueConnection qcon = qfac.createQueueConnection();

// later, after everything else is set up

qcon.start(); // we start receiving messages now

Programming Model

• Establishing the thread-scoped Session:– created from Connection– only safe for this thread—synchronize

accordingly!– should messages be run under transactional (JTA)

semantics?– do you want to acknowledge message receipt

manually?

QueueConnection qcon = ...; // from previous

QueueSession qsession = qcon.createQueueSession(false, // transacted? Session.AUTO_ACKNOWLEDGE); // acknowledgement mode

Programming Model

• Look up the Destination– again, go back to JNDI– name of the Destination selected by administrator– typically prefixed by "jms/" (not required)Context ctx = // from before

String qname = "jms/MyQueue"; // Name chosen by system administrator when installing // JMS software and configuring initial deployment

Queue queue = (Queue)ctx.lookup(qname);

Programming Model

• Senders: Create a Producer– scoped and tied to the Session (and Queue) that

created it– use this Producer object to do the actual message-

sendQueueSession qsession = // from beforeQueue queue = // from before

QueueSender qsender = qsession.createSender(queue);

Programming Model

• Messages– 3 parts: headers, properties, payload

headers are for JMS usageproperties are for app usagepayload is the actual dataHeader Properties Body

Routing and deliveryinfo used by system

Application-levelproperties

Payload - the request, Response or event

Programming Model

MessageProducer send/publish method.Time message was sent/published. Not the time it was actually transmitted

JMSTimestamp

Specified before MessageProducersend/publish method called.

Used to link messages together. Application-specific.

JMSCorrelationID

Specified before MessageProducersend/publish method called.

Used to specify a response destination if one is required. Response is not mandatory.

JMSReplyTo

Specified before MessageProducersend/publish method called.

Message type identifier. Could be used as key to the message definition in some type repository.

JMSType

Set by provider.Message has been redelivered and may have been seen before.

JMSRedelivered

Generated by provider when MessageProducer send/publish method called

Unique id Format of “ID:xxx”. Specified by and limited to one provider.

JMSMessageID

Specified in MessageProducersend/publish method

How quickly it gets where it’s going.

0 – 4 (normal), 5 – 9 (expedited).

JMSPriority

Specified in MessageProducersend/publish method

Message expiry in ms at send time. 0 means no expiry. System silently removes.

JMSExpiration

Specified in MessageProducersend/publish method

NON-PERSISTENT (not reliable, at most once, faster).

PERSISTENT (reliable, only once, slower).

JMSDeliveryMode

Destination that MessageProducer was based on

Message destination.JMSDestination

Set byMeaningName

MessageProducer send/publish method.Time message was sent/published. Not the time it was actually transmitted

JMSTimestamp

Specified before MessageProducersend/publish method called.

Used to link messages together. Application-specific.

JMSCorrelationID

Specified before MessageProducersend/publish method called.

Used to specify a response destination if one is required. Response is not mandatory.

JMSReplyTo

Specified before MessageProducersend/publish method called.

Message type identifier. Could be used as key to the message definition in some type repository.

JMSType

Set by provider.Message has been redelivered and may have been seen before.

JMSRedelivered

Generated by provider when MessageProducer send/publish method called

Unique id Format of “ID:xxx”. Specified by and limited to one provider.

JMSMessageID

Specified in MessageProducersend/publish method

How quickly it gets where it’s going.

0 – 4 (normal), 5 – 9 (expedited).

JMSPriority

Specified in MessageProducersend/publish method

Message expiry in ms at send time. 0 means no expiry. System silently removes.

JMSExpiration

Specified in MessageProducersend/publish method

NON-PERSISTENT (not reliable, at most once, faster).

PERSISTENT (reliable, only once, slower).

JMSDeliveryMode

Destination that MessageProducer was based on

Message destination.JMSDestination

Set byMeaningName

Programming Model

• Senders: Create a Message– use the Session to create one of five kinds of

messages:– ByteMessage: payload viewed as a byte array– TextMessage: payload viewed as a String– ObjectMessage: payload viewed as a Serializable

object– StreamMessage: payload viewed as a

DataOutputStream– MapMessage: payload viewed as a java.util.Map

Programming Model

• Senders: Create a MessageByteMessage bm = qsession.createByteMessage(); byte[] data = ...;bm.writeBytes(data);

TextMessage tm = qsession.createTextMessage(); tm.setText("hello");

ObjectMessage om = qsession.createObjectMessage(); MyObject obj = new MyObject("foo", 7, 2.5);om.setObject(obj);

StreamMessage sm = qsession.createStreamMessage();sm.writeString("foo"); sm.writeInt(7); sm.writeDouble(2.5);

MapMessage mm = qsession.createMapMessage();mm.setInt("num1", 7); mm.setString("name", "foo");mm.setDouble("num2", 2.5);

Programming Model

• Senders: Send the Message– use the Producer object to send the message– delivery mode:

PERSISTENT: msg remains in queueNON-PERSISTENT: msg clears if nobody receives it

– priority: 0 (MIN) – 9 (MAX) value– time to live: when will msg automatically clearMessage msg = // from beforeQueueSender qsender = // from before

qsender.send(msg);

int priority = 0; long timetolive=0; qsender.send(msg, DeliveryMode.PERSISTENT, priority, timetolive);

int priority = 9; long timetolive=10*1000; qsender.send(msg, DeliveryMode.NON-PERSISTENT, priority, timetolive);

Programming Model

• Receivers: Create a Consumer– use the Session object to create the Consumer– scoped to the Session and the DestinationQueueSession qsession = // from beforeQueue queue = // from before

QueueReceiver qreceiver = qsession.createReceiver(queue);

Programming Model

• Receivers: Receive Messages (Synchronously)– poll for messages by blocking in receive on

Consumer– returns generic Message object; downcast as

necessarywhile (true) { Message m = qreceiver.receive(); if (m instanceof ByteMessage) { byte data []; int len = ((ByteMessage)m).readBytes(data); } else if (m instanceof TextMessage) { StringBuffer sb = ((TextMessage)m).getText(); } else if (m instanceof ObjectMessage) { MyObject obj = new MyObject(); obj = ((ObjectMessage)m).getObject(); String s = obj.getFoo(); int i = obj.getNum(); }}

Programming Model

• Receivers: Receive Messages (Asynchronously)– register a MessageListener with the Consumer– NOTE: onMessage calls will be on separate

threadsqreceiver.setMessageListener(new MessageListener() { public void onMessage(Message m) { try { if (m instanceof StreamMessage) { StringBuffer s = m.readString(); int n = m.readInt(); double d = m.readDouble(); } else if (m instanceof MapMessage) { // . . . and so on } } catch (Throwable t) { // Divert message to Dead Letter queue? } }});

Programming Model

• Receivers: Selectively receive messages– use selector to filter messages before consuming– properties used to set predicate criteria– uses subset of SQL-92 syntax (predicate clauses)– full set of relational and boolean operators

availableJMS Spec, section 3.8

// Sender codeTextMessage tm = qsession.createTextMessage();tm.setText("hello");tm.setStringProperty("name", "fred");qsender.send(tm);

// Receiver codeQueueReceiver qr = qsession.createReceiver(q, "name='fred'"); TextMessage tm = (TextMessage)qr.receive();StringBuffer data = tm.getText(); // tm.getStringProperty("name").equals("fred"), guaranteed!

Programming Model

• Request/Response messaging– use Requester to simplify send/block-for-response

pattern– creates TemporaryQueue (or Topic), sets

JMSReplyTo– receiver extracts JMSReplyTo, posts response

there

// Rosencrantz.class:QueueRequester qreq = new QueueRequester(qsession, queue);TextMessage tmin = qsess.createTextMessage();tmin.setText("Hello");TextMessage tmout = qreq.request(tmin); // blocks

// Guildenstern.class:Message msg = ...;Destination reply = msg.getJMSReplyTo()TextMessage tmout = qsess.createTextMessage(); tmout.setText("Hi yourself");QueueSender qs = qsess.createSender((Queue)reply);qs.send(tmout);

Transactional Programming Model

• Group messages into atomic units– delivery guaranteed under ACID conditions– transacted session (specified at creation) scopes

messages– can integrate with JTA (distributed transactions)– no transactional call flow (from sender to receiver)– on commit, all messages delivered, consumed

messages ack'd– on abort, all messages discarded

boolean tx = true; int ackmode = Session.AUTO_ACKNOWLEDGE;QueueSession qsession = qcon.createQueueSession(tx, ackmode);TextMessage tm = qsession.createTextMessage(); tm.setText("hello");qsender.send(tm);tm = qsession.createTextMessage(); tm.setText("world");qsender.send(tm); // Calling qsession.commit() here would send both messages // Calling qsession.abort() here would discard both messages

Microsoft Message Queue (MSMQ)

Messaging-Oriented Middleware, .NET/COM style

MSMQ: Microsoft Message Queueing

• Specification for messaging on Microsoft operating systems– currently at 3.0 (XP, Win2003 Server, client on CE)

2.0 installs on Win2k, 1.0 on NT4, Windows 9x

• Captures essence of messaging– Synchronous or asynchronous operation– Loosely- or strongly-coupled operation– Transacted send/receive– Prioritized delivery– Deadline-based delivery– Delivery filtering

System.Messaging

• .NET bindings for MSMQ– wrappers (more or less) for MSMQ 2.0 COM API– managed API obviates (most) need for

COMInterop access– System.Messaging namespace– System.Messaging.dll assembly– requires full trust to execute; no partially-trusted

caller support

Programming Model

• Fairly straightforward:– Create MessageQueue around queue to use– Set properties/filters on MessageQueue– For sending, create Message, populate, Send()– For receiving, establish Formatter, retrieve

Message, unpack

Programming Model

• Creating the MessageQueue object:– Queue must already exist on machine; object is

just wrapper around native queue– name is case-insensitive (more on this later)using System.Messaging;

string queueName = @".\private$\myqueue";if (MessageQueue.Exists(queueName)){ // MessageQueue is IDisposable--either use "using" or // make sure to call Close() upon completion // using (MessageQueue myQ = new MessageQueue(queueName)) { // . . . }}

Programming Model

• Creating the Message:– instantiate new Message– populate Body property with message payload– set Label: application-defined string to identify

message– set Extension: app-defined information (byte[])using (MessageQueue myQ = new MessageQueue(queueName)){ Message msg = new Message("Hello, MSMQ!"); // or use Body property to populate payload

msg.Label = "Greetings";}

Programming Model

• Sending the Message:– call MessageQueue.Send() passing Message– overload allows passing "label" to describe the

Messagecompletely app-defined, no meaning to MSMQoften used to define behavior on recipient end

using (MessageQueue myQ = new MessageQueue(queueName)){ Message msg = new Message("Hello, MSMQ!");

myQ.Send(msg); myQ.Send(msg, "greetingmsg");}

Programming Model

• Retrieving the Message:– establish the Formatter on the MessageQueue

instance– call either Receive(), Peek() or GetAllMessages()– examine the Body propertyusing (MessageQueue myQ = new MessageQueue(queueName)){ myQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });

Message msg = myQ.Peek(); // retrieves the message without removing it Message msg2 = myQ.Receive(); // removes the message from the queue Console.WriteLine((string)(msg.Body));}

Programming Model

• Filtered retrieval:– MessageReadPropertyFilter defines properties of

message that will be retrieved– does NOT do any filtering based on the value of

the propertyusing (MessageQueue myQ = new MessageQueue(queueName)){ myQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) }); myQ.MessageReadPropertyFilter.Label = true; myQ.MessageReadPropertyFilter.Extension = true; // Now those properties will be retrieved as well

Message m = myQ.Receive(); Console.WriteLine(m.Priority); // always 0}

Programming Model

• Request/Response messaging:– Message.ResponseQueue indicates response

queue– "client" sets this before Send()– "server" responds to this upon Receive() or Peek()– completely application-defined (default is null)using (MessageQueue responseQueue = new MessageQueue(...), senderQueue = new MessageQueue(...)) { responseQueue.Formatter = ...; // as before

Message msg = new Message("Hello, there!"); msg.ResponseQueue = responseQueue; senderQueue.Send(msg);

Message responseMsg = responseQueue.Receive(); Console.WriteLine(responseMsg.Body);}

Queues

• Application queues– queues established by admins or programmers– 4 roles: destination, administration, response,

report

• System queues– queues established by MSMQ itself– dead-letter, journal, connector

Application Queues

• Destination queues– stores messages for application use– public or private

• public: registered in directory services• private: minimal directory overhead; no lookup

• Administration queues– used to store system-generated ack messages

• Response queues– stores application responses to request messages

• Report queues– public queues storing "report" messages (route tracing)

System Queues

• Journal queues– stores copies of messages sent to/through/from this machine– allows for better quality-of-service guarantees for messages– read-only (can't be directly sent to); much like database logs

• Dead-letter queues– final resting place of undeliverable messages– one each for transactional and non-transactional Q’s– read-only (can only be read and deleted, not sent to)

• Connector queues– used for store-and-forward messaging in route

Queues

• Creating the Queue administratively:– ComputerManagement snap-in– Message Queuing, under Services and

Applications– right-click folder to create New queue

Queues

• Creating the Queue programmatically:– MessageQueue.Create() to create a queue– MessageQueue.Delete() to remove a queueusing System.Messaging;

string queueName = @".\private$\myqueue";if (!MessageQueue.Exists(queueName)){ MessageQueue.Create(queueName);

// or pass boolean true to create transactional queue

MessageQueue.Delete(queueName);}

Queue names

• Queue Path ("friendly") name:– SERVER\queuename or .\PRIVATE$\queuename– case-insensitive

Queue names• Format name:– public, private, direct, distribution list, multicast, machine– multi-format names are 1..* single-element names (send only)– PUBLIC=QueueGUID

public queues only– PRIVATE=ComputerGUID\QueueNumber

private queues only– DIRECT=address\QueueName

• public or private queues• avoids directory service lookup• supports TCP, OS, HTTP, HTTPS, SPX

– MACHINE=ComputerGUID;JOURNAL• or DEADLETTER or DEADXACT• used to access system queues (dead-letter, journal, etc)

Queue access

• Queues can establish access rights– send, peek, or receive access rights

• Queues can establish share mode– can open queue in shared mode (default) or in

"deny-receive"– "deny-receive" grants exclusive access to first

accessor

Programming Model

• Message payloads– messages can be any object, subject to Formatter

restrictions– three Formatter types: ActiveX, Binary, Xml (default)

• ActiveXMessageFormatter: works w/native MSMQ• BinaryMessageFormatter: uses .NET Serialization• XmlMessageFormatter: uses .NET XmlSerializers

– set Formatter property on Message instance to send– set Formatter property on MessageQueue instance to

read

Programming Model

• Message payloads:string queueName = @".\private$\myqueue";using (MessageQueue newQueue = new MessageQueue(queueName)){ CustomObject o2 = new CustomObject(); o2._unexposed = "Do you see this?"; o2.Name = "Fred"; Message m2 = new Message(o2); m2.Formatter = new BinaryMessageFormatter(); newQueue.Send(m2);

newQueue.Formatter = new BinaryMessageFormatter(); recvMsg = newQueue.Receive(); CustomObject otherRecvObj = (CustomObject)recvMsg.Body; Assert.IsTrue(otherRecvObj.Name == "Fred"); Assert.IsTrue(otherRecvObj._unexposed != null); // Binary formatter should use Serialization}

Programming Model

• Message priority– set Priority on Message instance– set MessageReadPropertyFilter on MessageQueue

using (MessageQueue newQueue = MessageQueue.Create(queueName)){ newQueue.MessageReadPropertyFilter.Priority = true;

Message msg = new Message("Normal"); msg.Priority = MessagePriority.Normal; newQueue.Send(msg); Message msg2 = new Message("Highest"); msg2.Priority = MessagePriority.Highest; newQueue.Send(msg2); newQueue.Formatter = new XmlMessageFormatter(...);

Message recvMsg1 = newQueue.Receive(); Message recvMsg2 = newQueue.Receive();}

Programming Model

• Asynchronous message retrieval– establish delegate callback

ReceiveCompleted or PeekCompleted

– call BeginReceive to set up receive thread and return

– delegate called (from thread pool thread) on message arrival• delegate must call EndReceive to obtain Message• delegate must call BeginReceive again

– BeginPeek./EndPeek work the same way

Programming Model

• Asynchronous message retrieval:

using (MessageQueue myQ = MessageQueue.Create(queueName)){ myQ.Formatter = ...; // as usual

myQ.ReceiveCompleted += new ReceiveCompletedEventHandler(RecvCB); myQ.BeginReceive();}

public static void RecvCB(object src, ReceiveCompletedEventArgs a){ MessageQueue q = (MessageQueue)src; Message msg = q.EndReceive(a.AsyncResult);

// Process msg

q.BeginReceive(); // set up async behavior again}

Transactional Programming Model

• Group messages into atomic units– delivery guaranteed under ACID conditions– transacted object (MessageQueueTransaction)

scopes msgs– on commit, all messages delivered– on abort, all messages discarded

using (MessageQueue mq = new MessageQueue(queueName)){ MessageQueueTransaction txn = new MessageQueueTransaction(); txn.Begin(); Message msg1 = new Message("First message"); Message msg2 = new Message("Second message"); mq.Send(msg1, txn); Assert.IsTrue(mq.GetAllMessages().Length == 0); mq.Send(msg2, txn); Assert.IsTrue(mq.GetAllMessages().Length == 0); txn.Commit(); // or txn.Abort() Assert.IsTrue(mq.GetAllMessages().Length == 2);}

Summary

• Messaging provides alternative communication– messaging is flexible– messaging is scalable– messaging can operate over many channels– messaging requires more work on the part of the

programmer– many different messaging exchange patterns exist

Summary: Simple Messaging

• Sometimes "old" is better than "new"– well-known security implications– well-understood solutions to known problems (FTP)– well-established architecture already in place– interoperability already in place– better support for independent deployment

• Sometimes "simple" is better than "complex"– easier diagnostics– easier support– better anarchic scalability

Summary: JMS

• JMS provides convenient Java bindings for messaging– provides both P2P and PubSub semantics– can mimic RPC-style communication using

Requestor– can provide more flexibility than vanilla RPC

Summary: MSMQ

• MSMQ provides messaging on Windows– provides both P2P and PubSub semantics– can mimic RPC-style communication using

request/response– can provide more flexibility than vanilla RPC

• System.Messaging provides convenient .NET bindings

Resources

• Web– [EAI] http://www.enterpriseintegrationpatterns.com– [HTTP] HTTP 1.1 Spec– [SOAP1.2] http://www.w3.org/TR/soap

• REST– Architectural Styles and the Design of Network-based

Software Architectures, by Roy Thomas Fielding (2000, UCIrvine)

– RESTWiki: http://internet.conveyor.org/RESTwiki/moin.cgi/ShortSummaryOfRest

• Books– Enterprise Integration Patterns (Addison-Wesley)

Questions

?

Credentials

• Who is this guy?– Independent consultant, architect, mentor– Founding Editor-in-Chief, TheServerSide.NET

(www.theserverside.net)– Author

• Server-Based Java Programming (Manning, 2000)• Effective Enterprise Java (Addison-Wesley, 2004)• C# in a Nutshell (OReilly, 2001)• SSCLI Essentials (w/Stutz, Shilling; OReilly, 2003)

– Papers at www.neward.net/ted/Papers– Weblog at www.neward.net/ted/weblog