224 lines
14 KiB
XML
224 lines
14 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!-- ============================================================================= -->
|
|
<!-- Licensed to the Apache Software Foundation (ASF) under one or more -->
|
|
<!-- contributor license agreements. See the NOTICE file distributed with -->
|
|
<!-- this work for additional information regarding copyright ownership. -->
|
|
<!-- The ASF licenses this file to You under the Apache License, Version 2.0 -->
|
|
<!-- (the "License"); you may not use this file except in compliance with -->
|
|
<!-- the License. You may obtain a copy of the License at -->
|
|
<!-- -->
|
|
<!-- http://www.apache.org/licenses/LICENSE-2.0 -->
|
|
<!-- -->
|
|
<!-- Unless required by applicable law or agreed to in writing, software -->
|
|
<!-- distributed under the License is distributed on an "AS IS" BASIS, -->
|
|
<!-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -->
|
|
<!-- See the License for the specific language governing permissions and -->
|
|
<!-- limitations under the License. -->
|
|
<!-- ============================================================================= -->
|
|
<chapter id="using-core">
|
|
<title>Using Core</title>
|
|
<para>ActiveMQ core is a completely JMS-agnostic messaging system with its own non-JMS API. We
|
|
call this the <emphasis>core API</emphasis>.</para>
|
|
<para>If you don't want to use JMS you can use the core API directly. The core API provides all
|
|
the functionality of JMS but without much of the complexity. It also provides features that
|
|
are not available using JMS.</para>
|
|
<section>
|
|
<title>Core Messaging Concepts</title>
|
|
<para>Some of the core messaging concepts are similar to JMS concepts, but core messaging
|
|
concepts differ in some ways. In general the core messaging API is simpler than the JMS
|
|
API, since we remove distinctions between queues, topics and subscriptions. We'll
|
|
discuss each of the major core messaging concepts in turn, but to see the API in detail,
|
|
please consult the Javadoc.</para>
|
|
<section>
|
|
<title>Message</title>
|
|
<itemizedlist>
|
|
<listitem>
|
|
<para>A message is the unit of data which is sent between clients and
|
|
servers.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>A message has a body which is a buffer containing convenient methods for
|
|
reading and writing data into it.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>A message has a set of properties which are key-value pairs. Each property
|
|
key is a string and property values can be of type integer, long, short,
|
|
byte, byte[], String, double, float or boolean.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>A message has an <emphasis>address</emphasis> it is being sent to. When
|
|
the message arrives on the server it is routed to any queues that are bound
|
|
to the address - if the queues are bound with any filter, the message will
|
|
only be routed to that queue if the filter matches. An address may have many
|
|
queues bound to it or even none. There may also be entities other than
|
|
queues, like <emphasis role="italic">diverts</emphasis> bound to
|
|
addresses.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Messages can be either durable or non durable. Durable messages in a
|
|
durable queue will survive a server crash or restart. Non durable messages
|
|
will never survive a server crash or restart.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Messages can be specified with a priority value between 0 and 9. 0
|
|
represents the lowest priority and 9 represents the highest. ActiveMQ will
|
|
attempt to deliver higher priority messages before lower priority
|
|
ones.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Messages can be specified with an optional expiry time. ActiveMQ will not
|
|
deliver messages after its expiry time has been exceeded.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>Messages also have an optional timestamp which represents the time the
|
|
message was sent.</para>
|
|
</listitem>
|
|
<listitem>
|
|
<para>ActiveMQ also supports the sending/consuming of very large messages - much
|
|
larger than can fit in available RAM at any one time.</para>
|
|
</listitem>
|
|
</itemizedlist>
|
|
</section>
|
|
<section>
|
|
<title>Address</title>
|
|
<para>A server maintains a mapping between an address and a set of queues. Zero or more
|
|
queues can be bound to a single address. Each queue can be bound with an optional
|
|
message filter. When a message is routed, it is routed to the set of queues bound to
|
|
the message's address. If any of the queues are bound with a filter expression, then
|
|
the message will only be routed to the subset of bound queues which match that
|
|
filter expression.</para>
|
|
<para>Other entities, such as <emphasis role="italic">diverts</emphasis> can also be
|
|
bound to an address and messages will also be routed there.</para>
|
|
<note>
|
|
<para>In core, there is no concept of a Topic, Topic is a JMS only term. Instead, in
|
|
core, we just deal with <emphasis>addresses</emphasis> and
|
|
<emphasis>queues</emphasis>.</para>
|
|
<para>For example, a JMS topic would be implemented by a single address to which
|
|
many queues are bound. Each queue represents a subscription of the topic. A JMS
|
|
Queue would be implemented as a single address to which one queue is bound -
|
|
that queue represents the JMS queue.</para>
|
|
</note>
|
|
</section>
|
|
<section>
|
|
<title>Queue</title>
|
|
<para>Queues can be durable, meaning the messages they contain survive a server crash or
|
|
restart, as long as the messages in them are durable. Non durable queues do not
|
|
survive a server restart or crash even if the messages they contain are
|
|
durable.</para>
|
|
<para>Queues can also be temporary, meaning they are automatically deleted when the
|
|
client connection is closed, if they are not explicitly deleted before that.</para>
|
|
<para>Queues can be bound with an optional filter expression. If a filter expression is
|
|
supplied then the server will only route messages that match that filter expression
|
|
to any queues bound to the address.</para>
|
|
<para>Many queues can be bound to a single address. A particular queue is only bound to
|
|
a maximum of one address.</para>
|
|
</section>
|
|
<section>
|
|
<title>ServerLocator</title>
|
|
<para>Clients use <literal>ServerLocator</literal> instances to create <literal
|
|
>ClientSessionFactory</literal> instances. <literal>ServerLocator</literal>
|
|
instances are used to locate servers and create connections to them. </para>
|
|
<para>In JMS terms think of a <literal>ServerLocator</literal> in the same way you would
|
|
a JMS Connection Factory.</para>
|
|
<para><literal>ServerLocator</literal> instances are created using the <literal
|
|
>ActiveMQClient</literal> factory class.</para>
|
|
</section>
|
|
<section>
|
|
<title>ClientSessionFactory</title>
|
|
<para>Clients use <literal>ClientSessionFactory</literal> instances to create <literal
|
|
>ClientSession</literal> instances. <literal>ClientSessionFactory</literal>
|
|
instances are basically the connection to a server</para>
|
|
<para> In JMS terms think of them as JMS Connections.</para>
|
|
<para><literal>ClientSessionFactory</literal> instances are created using the <literal
|
|
>ServerLocator</literal> class.</para>
|
|
</section>
|
|
<section>
|
|
<title>ClientSession</title>
|
|
<para>A client uses a ClientSession for consuming and producing messages and for
|
|
grouping them in transactions. ClientSession instances can support both
|
|
transactional and non transactional semantics and also provide an <literal
|
|
>XAResource</literal> interface so messaging operations can be performed as part
|
|
of a <ulink url="http://www.oracle.com/technetwork/java/javaee/tech/jta-138684.html">JTA</ulink>
|
|
transaction.</para>
|
|
<para>ClientSession instances group ClientConsumers and ClientProducers.</para>
|
|
<para>ClientSession instances can be registered with an optional <literal
|
|
>SendAcknowledgementHandler</literal>. This allows your client code to be
|
|
notified asynchronously when sent messages have successfully reached the server.
|
|
This unique ActiveMQ feature, allows you to have full guarantees that sent messages
|
|
have reached the server without having to block on each message sent until a
|
|
response is received. Blocking on each messages sent is costly since it requires a
|
|
network round trip for each message sent. By not blocking and receiving send
|
|
acknowledgements asynchronously you can create true end to end asynchronous systems
|
|
which is not possible using the standard JMS API. For more information on this
|
|
advanced feature please see the section <xref linkend="send-guarantees"/>.</para>
|
|
</section>
|
|
<section>
|
|
<title>ClientConsumer</title>
|
|
<para>Clients use <literal>ClientConsumer</literal> instances to consume messages from a
|
|
queue. Core Messaging supports both synchronous and asynchronous message consumption
|
|
semantics. <literal>ClientConsumer</literal> instances can be configured with an
|
|
optional filter expression and will only consume messages which match that
|
|
expression.</para>
|
|
</section>
|
|
<section>
|
|
<title>ClientProducer</title>
|
|
<para>Clients create <literal>ClientProducer</literal> instances on <literal
|
|
>ClientSession</literal> instances so they can send messages. ClientProducer
|
|
instances can specify an address to which all sent messages are routed, or they can
|
|
have no specified address, and the address is specified at send time for the
|
|
message.</para>
|
|
</section>
|
|
<warning>
|
|
<para>Please note that ClientSession, ClientProducer and ClientConsumer instances are
|
|
<emphasis>designed to be re-used</emphasis>.</para>
|
|
<para>It's an anti-pattern to create new ClientSession, ClientProducer and
|
|
ClientConsumer instances for each message you produce or consume. If you do this,
|
|
your application will perform very poorly. This is discussed further in the section
|
|
on performance tuning <xref linkend="perf-tuning"/>.</para>
|
|
</warning>
|
|
</section>
|
|
<section>
|
|
<title>A simple example of using Core</title>
|
|
<para>Here's a very simple program using the core messaging API to send and receive a
|
|
message. Logically it's comprised of two sections: firstly setting up the producer to
|
|
write a message to an <emphasis>addresss</emphasis>, and secondly, creating a
|
|
<emphasis>queue</emphasis> for the consumer, creating the consumer and
|
|
<emphasis>starting</emphasis> it.</para>
|
|
<programlisting>
|
|
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(
|
|
InVMConnectorFactory.class.getName()));
|
|
|
|
// In this simple example, we just use one session for both producing and receiving
|
|
|
|
ClientSessionFactory factory = locator.createClientSessionFactory();
|
|
ClientSession session = factory.createSession();
|
|
|
|
// A producer is associated with an address ...
|
|
|
|
ClientProducer producer = session.createProducer("example");
|
|
ClientMessage message = session.createMessage(true);
|
|
message.getBodyBuffer().writeString("Hello");
|
|
|
|
// We need a queue attached to the address ...
|
|
|
|
session.createQueue("example", "example", true);
|
|
|
|
// And a consumer attached to the queue ...
|
|
|
|
ClientConsumer consumer = session.createConsumer("example");
|
|
|
|
// Once we have a queue, we can send the message ...
|
|
|
|
producer.send(message);
|
|
|
|
// We need to start the session before we can -receive- messages ...
|
|
|
|
session.start();
|
|
ClientMessage msgReceived = consumer.receive();
|
|
|
|
System.out.println("message = " + msgReceived.getBodyBuffer().readString());
|
|
|
|
session.close();</programlisting>
|
|
</section>
|
|
</chapter>
|