http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/scheduled-messages.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/scheduled-messages.xml b/docs/user-manual/en/scheduled-messages.xml new file mode 100644 index 0000000..509904e --- /dev/null +++ b/docs/user-manual/en/scheduled-messages.xml @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="scheduled-messages"> + <title>Scheduled Messages</title> + <para>Scheduled messages differ from normal messages in that they won't be delivered until a + specified time in the future, at the earliest.</para> + <para>To do this, a special property is set on the message before sending it.</para> + <section> + <title>Scheduled Delivery Property</title> + <para>The property name used to identify a scheduled message is <literal + >"_HQ_SCHED_DELIVERY"</literal> (or the constant <literal + >Message.HDR_SCHEDULED_DELIVERY_TIME</literal>).</para> + <para>The specified value must be a positive <literal>long</literal> corresponding to the time the + message must be delivered (in milliseconds). An example of sending a scheduled message + using the JMS API is as follows.</para> + <programlisting> +TextMessage message = session.createTextMessage("This is a scheduled message message which will be delivered in 5 sec."); +message.setLongProperty("_HQ_SCHED_DELIVERY", System.currentTimeMillis() + 5000); +producer.send(message); + +... + +// message will not be received immediately but 5 seconds later +TextMessage messageReceived = (TextMessage) consumer.receive();</programlisting> + <para>Scheduled messages can also be sent using the core API, by setting the same property on + the core message before sending.</para> + </section> + <section> + <title>Example</title> + <para>See <xref linkend="examples.scheduled-message"/> for an example which shows how + scheduled messages can be used with JMS.</para> + </section> +</chapter>
http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/security.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/security.xml b/docs/user-manual/en/security.xml new file mode 100644 index 0000000..91a832e --- /dev/null +++ b/docs/user-manual/en/security.xml @@ -0,0 +1,288 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="security"> + <title>Security</title> + <para>This chapter describes how security works with HornetQ and how you can configure it. To + disable security completely simply set the <literal>security-enabled</literal> property to + false in the <literal>hornetq-configuration.xml</literal> file.</para> + <para>For performance reasons security is cached and invalidated every so long. To change this + period set the property <literal>security-invalidation-interval</literal>, which is in + milliseconds. The default is <literal>10000</literal> ms.</para> + <section id="security.settings.roles"> + <title>Role based security for addresses</title> + <para>HornetQ contains a flexible role-based security model for applying security to queues, + based on their addresses.</para> + <para>As explained in <xref linkend="using-core"/>, HornetQ core consists mainly of sets of + queues bound to addresses. A message is sent to an address and the server looks up the + set of queues that are bound to that address, the server then routes the message to + those set of queues.</para> + <para>HornetQ allows sets of permissions to be defined against the queues based on their + address. An exact match on the address can be used or a wildcard match can be used using + the wildcard characters '<literal>#</literal>' and '<literal>*</literal>'.</para> + <para>Seven different permissions can be given to the set of queues which match the address. + Those permissions are:</para> + <itemizedlist> + <listitem> + <para><literal>createDurableQueue</literal>. This permission allows the user to + create a durable queue under matching addresses.</para> + </listitem> + <listitem> + <para><literal>deleteDurableQueue</literal>. This permission allows the user to + delete a durable queue under matching addresses.</para> + </listitem> + <listitem> + <para><literal>createNonDurableQueue</literal>. This permission allows the user to create + a non-durable queue under matching addresses.</para> + </listitem> + <listitem> + <para><literal>deleteNonDurableQueue</literal>. This permission allows the user to delete + a non-durable queue under matching addresses.</para> + </listitem> + <listitem> + <para><literal>send</literal>. This permission allows the user to send a message to + matching addresses.</para> + </listitem> + <listitem> + <para><literal>consume</literal>. This permission allows the user to consume a + message from a queue bound to matching addresses.</para> + </listitem> + <listitem> + <para><literal>manage</literal>. This permission allows the user to invoke + management operations by sending management messages to the management + address.</para> + </listitem> + </itemizedlist> + <para>For each permission, a list of roles who are granted that permission is specified. If + the user has any of those roles, he/she will be granted that permission for that set of + addresses.</para> + <para>Let's take a simple example, here's a security block from <literal + >hornetq-configuration.xml</literal> or <literal>hornetq-queues.xml</literal> + file:</para> + <programlisting> +<security-setting match="globalqueues.europe.#"> + <permission type="createDurableQueue" roles="admin"/> + <permission type="deleteDurableQueue" roles="admin"/> + <permission type="createNonDurableQueue" roles="admin, guest, europe-users"/> + <permission type="deleteNonDurableQueue" roles="admin, guest, europe-users"/> + <permission type="send" roles="admin, europe-users"/> + <permission type="consume" roles="admin, europe-users"/> +</security-setting></programlisting> + <para>The '<literal>#</literal>' character signifies "any sequence of words". Words are + delimited by the '<literal>.</literal>' character. For a full description of the + wildcard syntax please see <xref linkend="wildcard-syntax"/>. The above security block + applies to any address that starts with the string "globalqueues.europe.":</para> + <para>Only users who have the <literal>admin</literal> role can create or delete durable + queues bound to an address that starts with the string "globalqueues.europe."</para> + <para>Any users with the roles <literal>admin</literal>, <literal>guest</literal>, or + <literal>europe-users</literal> can create or delete temporary queues bound to an + address that starts with the string "globalqueues.europe."</para> + <para>Any users with the roles <literal>admin</literal> or <literal>europe-users</literal> + can send messages to these addresses or consume messages from queues bound to an address + that starts with the string "globalqueues.europe."</para> + <para>The mapping between a user and what roles they have is handled by the security + manager. HornetQ ships with a user manager that reads user credentials from a file on + disk, and can also plug into JAAS or JBoss Application Server security.</para> + <para>For more information on configuring the security manager, please see <xref + linkend="change-security-manager"/>.</para> + <para>There can be zero or more <literal>security-setting</literal> elements in each xml + file. Where more than one match applies to a set of addresses the <emphasis>more + specific</emphasis> match takes precedence.</para> + <para>Let's look at an example of that, here's another <literal>security-setting</literal> + block:</para> + <programlisting> +<security-setting match="globalqueues.europe.orders.#"> + <permission type="send" roles="europe-users"/> + <permission type="consume" roles="europe-users"/> +</security-setting></programlisting> + <para>In this <literal>security-setting</literal> block the match + 'globalqueues.europe.orders.#' is more specific than the previous match + 'globalqueues.europe.#'. So any addresses which match 'globalqueues.europe.orders.#' + will take their security settings <emphasis>only</emphasis> from the latter + security-setting block.</para> + <para>Note that settings are not inherited from the former block. All the settings will be + taken from the more specific matching block, so for the address + 'globalqueues.europe.orders.plastics' the only permissions that exist are <literal + >send</literal> and <literal>consume</literal> for the role europe-users. The + permissions <literal>createDurableQueue</literal>, <literal + >deleteDurableQueue</literal>, <literal>createNonDurableQueue</literal>, <literal + >deleteNonDurableQueue</literal> are not inherited from the other security-setting + block.</para> + <para>By not inheriting permissions, it allows you to effectively deny permissions in more + specific security-setting blocks by simply not specifying them. Otherwise it would not + be possible to deny permissions in sub-groups of addresses.</para> + </section> + <section> + <title>Secure Sockets Layer (SSL) Transport</title> + <para>When messaging clients are connected to servers, or servers are connected to other + servers (e.g. via bridges) over an untrusted network then HornetQ allows that traffic to + be encrypted using the Secure Sockets Layer (SSL) transport.</para> + <para>For more information on configuring the SSL transport, please see <xref + linkend="configuring-transports"/>.</para> + </section> + <section> + <title>Basic user credentials</title> + <para>HornetQ ships with a security manager implementation that reads user credentials, i.e. + user names, passwords and role information from an xml file on the classpath called + <literal>hornetq-users.xml</literal>. This is the default security manager.</para> + <para>If you wish to use this security manager, then users, passwords and roles can easily + be added into this file.</para> + <para>Let's take a look at an example file:</para> + <programlisting> +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq ../schemas/hornetq-users.xsd "> + + <defaultuser name="guest" password="guest"> + <role name="guest"/> + </defaultuser> + + <user name="tim" password="marmite"> + <role name="admin"/> + </user> + + <user name="andy" password="doner_kebab"> + <role name="admin"/> + <role name="guest"/> + </user> + + <user name="jeff" password="camembert"> + <role name="europe-users"/> + <role name="guest"/> + </user> + +</configuration></programlisting> + <para>The first thing to note is the element <literal>defaultuser</literal>. This defines + what user will be assumed when the client does not specify a username/password when + creating a session. In this case they will be the user <literal>guest</literal> and have + the role also called <literal>guest</literal>. Multiple roles can be specified for a + default user.</para> + <para>We then have three more users, the user <literal>tim</literal> has the role <literal + >admin</literal>. The user <literal>andy</literal> has the roles <literal + >admin</literal> and <literal>guest</literal>, and the user <literal>jeff</literal> + has the roles <literal>europe-users</literal> and <literal>guest</literal>.</para> + </section> + <section id="change-security-manager"> + <title>Changing the security manager</title> + <para>If you do not want to use the default security manager then you can specify a + different one by editing the file <literal>hornetq-beans.xml</literal> (or <literal + >hornetq-jboss-beans.xml</literal> if you're running JBoss Application Server) and + changing the class for the <literal>HornetQSecurityManager</literal> bean.</para> + <para>Let's take a look at a snippet from the default beans file:</para> + <programlisting> +<bean name="HornetQSecurityManager" class="org.hornetq.spi.core.security.HornetQSecurityManagerImpl"> + <start ignored="true"/> + <stop ignored="true"/> +</bean></programlisting> + <para>The class <literal>org.hornetq.spi.core.security.HornetQSecurityManagerImpl</literal> + is the default security manager that is used by the standalone server.</para> + <para>HornetQ ships with two other security manager implementations you can use + off-the-shelf; one a JAAS security manager and another for integrating with JBoss + Application Sever security, alternatively you could write your own implementation by + implementing the <literal>org.hornetq.spi.core.security.HornetQSecurityManager</literal> + interface, and specifying the classname of your implementation in the file <literal + >hornetq-beans.xml</literal> (or <literal>hornetq-jboss-beans.xml</literal> if + you're running JBoss Application Server).</para> + <para>These two implementations are discussed in the next two sections.</para> + </section> + <section> + <title>JAAS Security Manager</title> + <para>JAAS stands for 'Java Authentication and Authorization Service' and is a standard part + of the Java platform. It provides a common API for security authentication and + authorization, allowing you to plugin your pre-built implementations.</para> + <para>To configure the JAAS security manager to work with your pre-built JAAS infrastructure + you need to specify the security manager as a <literal>JAASSecurityManager</literal> in + the beans file. Here's an example:</para> + <programlisting> +<bean name="HornetQSecurityManager" class="org.hornetq.integration.jboss.security.JAASSecurityManager"> + <start ignored="true"/> + <stop ignored="true"/> + + <property name="ConfigurationName">org.hornetq.jms.example.ExampleLoginModule</property> + <property name="Configuration"> + <inject bean="ExampleConfiguration"/> + </property> + <property name="CallbackHandler"> + <inject bean="ExampleCallbackHandler"/> + </property> +</bean></programlisting> + <para>Note that you need to feed the JAAS security manager with three properties:</para> + <itemizedlist> + <listitem> + <para>ConfigurationName: the name of the <literal>LoginModule</literal> + implementation that JAAS must use</para> + </listitem> + <listitem> + <para>Configuration: the <literal>Configuration</literal> implementation used by + JAAS</para> + </listitem> + <listitem> + <para>CallbackHandler: the <literal>CallbackHandler</literal> implementation to use + if user interaction are required</para> + </listitem> + </itemizedlist> + <section> + <title>Example</title> + <para>See <xref linkend="examples.jaas"/> for an example which shows how HornetQ can be + configured to use JAAS.</para> + </section> + </section> + <section> + <title>JBoss AS Security Manager</title> + <para>The JBoss AS security manager is used when running HornetQ inside the JBoss + Application server. This allows tight integration with the JBoss Application Server's + security model.</para> + <para>The class name of this security manager is <literal + >org.hornetq.integration.jboss.security.JBossASSecurityManager</literal></para> + <para>Take a look at one of the default <literal>hornetq-jboss-beans.xml</literal> files for + JBoss Application Server that are bundled in the distribution for an example of how this + is configured.</para> + <section> + <title>Configuring Client Login</title> + <para>JBoss can be configured to allow client login, basically this is when a JEE component such as a Servlet + or EJB sets security credentials on the current security context and these are used throughout the call. + If you would like these credentials to be used by HornetQ when sending or consuming messages then + set <literal>allowClientLogin</literal> to true. This will bypass HornetQ authentication and propagate the + provided Security Context. If you would like HornetQ to authenticate using the propagated security then set the + <literal>authoriseOnClientLogin</literal> to true also.</para> + <para>There is more info on using the JBoss client login module <ulink + url="http://community.jboss.org/wiki/ClientLoginModule">here</ulink> </para> + <note><para>If messages are sent non blocking then there is a chance that these could arrive on the server after + the calling thread has completed meaning that the security context has been cleared. If this is the case then messages + will need to be sent blocking</para></note> + </section> + <section> + <title>Changing the Security Domain</title> + <para>The name of the security domain used by the JBoss AS security manager defaults to <literal>java:/jaas/hornetq + </literal>. This can be changed by specifying <literal>securityDomainName</literal> (e.g. java:/jaas/myDomain). + </para> + </section> + </section> + <section> + <title>Changing the username/password for clustering</title> + <para>In order for cluster connections to work correctly, each node in the cluster must make + connections to the other nodes. The username/password they use for this should always be + changed from the installation default to prevent a security risk.</para> + <para>Please see <xref linkend="management"/> for instructions on how to do this.</para> + </section> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/send-guarantees.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/send-guarantees.xml b/docs/user-manual/en/send-guarantees.xml new file mode 100644 index 0000000..40a0bc5 --- /dev/null +++ b/docs/user-manual/en/send-guarantees.xml @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="send-guarantees"> + <title>Guarantees of sends and commits</title> + <section> + <title>Guarantees of Transaction Completion</title> + <para>When committing or rolling back a transaction with HornetQ, the request to commit or + rollback is sent to the server, and the call will block on the client side until a + response has been received from the server that the commit or rollback was + executed.</para> + <para>When the commit or rollback is received on the server, it will be committed to the + journal, and depending on the value of the parameter <literal + >journal-sync-transactional</literal> the server will ensure that the commit or + rollback is durably persisted to storage before sending the response back to the client. + If this parameter has the value <literal>false</literal> then commit or rollback may not + actually get persisted to storage until some time after the response has been sent to + the client. In event of server failure this may mean the commit or rollback never gets + persisted to storage. The default value of this parameter is <literal>true</literal> so + the client can be sure all transaction commits or rollbacks have been persisted to + storage by the time the call to commit or rollback returns.</para> + <para>Setting this parameter to <literal>false</literal> can improve performance at the + expense of some loss of transaction durability.</para> + <para>This parameter is set in <literal>hornetq-configuration.xml</literal></para> + </section> + <section id="non-transactional-sends"> + <title>Guarantees of Non Transactional Message Sends</title> + <para>If you are sending messages to a server using a non transacted session, HornetQ can be + configured to block the call to send until the message has definitely reached the + server, and a response has been sent back to the client. This can be configured + individually for durable and non-durable messages, and is determined by the + following two parameters:</para> + <itemizedlist> + <listitem> + <para><literal>BlockOnDurableSend</literal>. If this is set to <literal + >true</literal> then all calls to send for durable messages on non + transacted sessions will block until the message has reached the server, and a + response has been sent back. The default value is <literal>true</literal>. + </para> + </listitem> + <listitem> + <para><literal>BlockOnNonDurableSend</literal>. If this is set to <literal + >true</literal> then all calls to send for non-durable messages on non + transacted sessions will block until the message has reached the server, and a + response has been sent back. The default value is <literal + >false</literal>.</para> + </listitem> + </itemizedlist> + <para>Setting block on sends to <literal>true</literal> can reduce performance since each + send requires a network round trip before the next send can be performed. This means the + performance of sending messages will be limited by the network round trip time (RTT) of + your network, rather than the bandwidth of your network. For better performance we + recommend either batching many messages sends together in a transaction since with a + transactional session, only the commit / rollback blocks not every send, or, using + HornetQ's advanced <emphasis>asynchronous send acknowledgements feature</emphasis> + described in <xref linkend="asynchronous-send-acknowledgements"/>.</para> + <para>If you are using JMS and you're using the JMS service on the server to load your JMS + connection factory instances into JNDI then these parameters can be configured in + <literal>hornetq-jms.xml</literal> using the elements <literal + >block-on-durable-send</literal> and <literal + >block-on-non-durable-send</literal>. If you're using JMS but not using JNDI then + you can set these values directly on the <literal>HornetQConnectionFactory</literal> + instance using the appropriate setter methods.</para> + <para>If you're using core you can set these values directly on the <literal + >ClientSessionFactory</literal> instance using the appropriate setter + methods.</para> + <para>When the server receives a message sent from a non transactional session, and that + message is durable and the message is routed to at least one durable queue, then the + server will persist the message in permanent storage. If the journal parameter <literal + >journal-sync-non-transactional</literal> is set to <literal>true</literal> the + server will not send a response back to the client until the message has been persisted + and the server has a guarantee that the data has been persisted to disk. The default + value for this parameter is <literal>true</literal>.</para> + </section> + <section id="send-guarantees.nontrans.acks"> + <title>Guarantees of Non Transactional Acknowledgements</title> + <para>If you are acknowledging the delivery of a message at the client side using a non + transacted session, HornetQ can be configured to block the call to acknowledge until the + acknowledge has definitely reached the server, and a response has been sent back to the + client. This is configured with the parameter <literal>BlockOnAcknowledge</literal>. If + this is set to <literal>true</literal> then all calls to acknowledge on non transacted + sessions will block until the acknowledge has reached the server, and a response has + been sent back. You might want to set this to <literal>true</literal> if you want to + implement a strict <emphasis>at most once</emphasis> delivery policy. The default value + is <literal>false</literal></para> + </section> + <section id="asynchronous-send-acknowledgements"> + <title>Asynchronous Send Acknowledgements</title> + <para>If you are using a non transacted session but want a guarantee that every message sent + to the server has reached it, then, as discussed in <xref + linkend="non-transactional-sends"/>, you can configure HornetQ to block the call to + send until the server has received the message, persisted it and sent back a response. + This works well but has a severe performance penalty - each call to send needs to block + for at least the time of a network round trip (RTT) - the performance of sending is thus + limited by the latency of the network, <emphasis>not</emphasis> limited by the network + bandwidth.</para> + <para>Let's do a little bit of maths to see how severe that is. We'll consider a standard + 1Gib ethernet network with a network round trip between the server and the client of + 0.25 ms.</para> + <para>With a RTT of 0.25 ms, the client can send <emphasis>at most</emphasis> 1000/ 0.25 = + 4000 messages per second if it blocks on each message send.</para> + <para>If each message is < 1500 bytes and a standard 1500 bytes MTU size is used on the + network, then a 1GiB network has a <emphasis>theoretical</emphasis> upper limit of (1024 + * 1024 * 1024 / 8) / 1500 = 89478 messages per second if messages are sent without + blocking! These figures aren't an exact science but you can clearly see that being + limited by network RTT can have serious effect on performance.</para> + <para>To remedy this, HornetQ provides an advanced new feature called <emphasis>asynchronous + send acknowledgements</emphasis>. With this feature, HornetQ can be configured to + send messages without blocking in one direction and asynchronously getting + acknowledgement from the server that the messages were received in a separate stream. By + de-coupling the send from the acknowledgement of the send, the system is not limited by + the network RTT, but is limited by the network bandwidth. Consequently better throughput + can be achieved than is possible using a blocking approach, while at the same time + having absolute guarantees that messages have successfully reached the server.</para> + <para>The window size for send acknowledgements is determined by the confirmation-window-size parameter on + the connection factory or client session factory. Please see <xref linkend="client-reconnection"/> for more info on this.</para> + <section> + <title>Asynchronous Send Acknowledgements</title> + <para>To use the feature using the core API, you implement the interface <literal + >org.hornetq.api.core.client.SendAcknowledgementHandler</literal> and set a handler + instance on your <literal>ClientSession</literal>.</para> + <para>Then, you just send messages as normal using your <literal + >ClientSession</literal>, and as messages reach the server, the server will send + back an acknowledgement of the send asynchronously, and some time later you are + informed at the client side by HornetQ calling your handler's <literal + >sendAcknowledged(ClientMessage message)</literal> method, passing in a + reference to the message that was sent.</para> + <para>To enable asynchronous send acknowledgements you must make sure <literal>confirmation-window-size</literal> is set to a positive integer value, e.g. 10MiB</para> + <para>Please see <xref linkend="asynchronous-send-acknowledgements-example"/> for a full + working example.</para> + </section> + </section> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/spring-integration.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/spring-integration.xml b/docs/user-manual/en/spring-integration.xml new file mode 100644 index 0000000..730fa02 --- /dev/null +++ b/docs/user-manual/en/spring-integration.xml @@ -0,0 +1,93 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3CR3//EN" +"../../../lib/docbook-support/support/docbook-dtd/docbookx.dtd"> --> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="spring.integration"> + <title>Spring Integration</title> + + <para>HornetQ provides a simple bootstrap class, + <literal>org.hornetq.integration.spring.SpringJmsBootstrap</literal>, for + integration with Spring. To use it, you configure HornetQ as you always + would, through its various configuration files like + <literal>hornetq-configuration.xml</literal>, + <literal>hornetq-jms.xml</literal>, and + <literal>hornetq-users.xml</literal>. The Spring helper class starts the + HornetQ server and adds any factories or destinations configured within + <literal>hornetq-jms.xml</literal> directly into the namespace of the Spring + context. Let's take this <literal>hornetq-jms.xml</literal> file for + instance: </para> + <programlisting> +<configuration xmlns="urn:hornetq" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd"> + <!--the connection factory used by the example--> + <connection-factory name="ConnectionFactory"> + <connectors> + <connector-ref connector-name="in-vm"/> + </connectors> + <entries> + <entry name="ConnectionFactory"/> + </entries> + </connection-factory> + + <!--the queue used by the example--> + <queue name="exampleQueue"> + <entry name="/queue/exampleQueue"/> + </queue> +</configuration></programlisting> + <para>Here we've specified a + <literal>javax.jms.ConnectionFactory</literal> we want bound to a + <literal>ConnectionFactory</literal> entry as well as a queue destination + bound to a <literal>/queue/exampleQueue</literal> entry. Using the + <literal>SpringJmsBootStrap</literal> bean will automatically populate the + Spring context with references to those beans so that you can use them. + Below is an example Spring JMS bean file taking advantage of this + feature:</para> + <programlisting> +<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-3.0.xsd"> + + <bean id="EmbeddedJms" class="org.hornetq.integration.spring.SpringJmsBootstrap" init-method="start"/> + + <bean id="listener" class="org.hornetq.tests.integration.spring.ExampleListener"/> + + <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> + <property name="connectionFactory" ref="ConnectionFactory"/> + <property name="destination" ref="/queue/exampleQueue"/> + <property name="messageListener" ref="listener"/> + </bean> +</beans></programlisting> + <para>As you can see, the + <literal>listenerContainer</literal> bean references the components defined + in the <literal>hornetq-jms.xml</literal> file. The + <literal>SpringJmsBootstrap</literal> class extends the EmbeddedJMS class + talked about in <xref + linkend="simple.embedded.jms" /> and the same defaults and + configuration options apply. Also notice that an + <literal>init-method</literal> must be declared with a start value so that + the bean's lifecycle is executed. See the javadocs for more details on other + properties of the bean class.</para> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/thread-pooling.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/thread-pooling.xml b/docs/user-manual/en/thread-pooling.xml new file mode 100644 index 0000000..e78b1b0 --- /dev/null +++ b/docs/user-manual/en/thread-pooling.xml @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="thread-pooling"> + <title>Thread management</title> + <para>This chapter describes how HornetQ uses and pools threads and how you can manage + them.</para> + <para>First we'll discuss how threads are managed and used on the server side, then we'll look + at the client side.</para> + <section> + <title>Server-Side Thread Management</title> + <para>Each HornetQ Server maintains a single thread pool for general use, and a scheduled + thread pool for scheduled use. A Java scheduled thread pool cannot be configured to use + a standard thread pool, otherwise we could use a single thread pool for both scheduled + and non scheduled activity.</para> + <para>A separate thread pool is also used to service connections. HornetQ can use "old" + (blocking) IO or "new" (non-blocking) IO also called NIO. Both of these options use + a separate thread pool, but each of them behaves uniquely.</para> + <para>Since old IO requires a thread per connection its thread pool is unbounded. The thread + pool is created via <literal> + java.util.concurrent.Executors.newCachedThreadPool(ThreadFactory)</literal>. As the + JavaDoc for this method states: + <quote>Creates a thread pool that creates new threads as needed, but will reuse previously + constructed threads when they are available, and uses the provided ThreadFactory to create + new threads when needed.</quote> + Threads from this pool which are idle for more than 60 seconds will time out and be + removed. If old IO connections were serviced from the standard pool the pool would + easily get exhausted if too many connections were made, resulting in the server "hanging" + since it has no remaining threads to do anything else. However, even an unbounded thread + pool can run into trouble if it becomes too large. If you require the server to handle + many concurrent connections you should use NIO, not old IO.</para> + <para>When using new IO (NIO), HornetQ will, by default, cap its thread pool at three times + the number of cores (or hyper-threads) as reported by <literal> + Runtime.getRuntime().availableProcessors()</literal> for processing incoming packets. + To override this value, you can set the number of threads by specifying the parameter + <literal>nio-remoting-threads</literal> in the transport configuration. See the + <xref linkend="configuring-transports"/> for more information on this.</para> + <para>There are also a small number of other places where threads are used directly, we'll + discuss each in turn.</para> + <section id="server.scheduled.thread.pool"> + <title>Server Scheduled Thread Pool</title> + <para>The server scheduled thread pool is used for most activities on the server side + that require running periodically or with delays. It maps internally to a <literal + >java.util.concurrent.ScheduledThreadPoolExecutor</literal> instance.</para> + <para>The maximum number of thread used by this pool is configure in <literal + >hornetq-configuration.xml</literal> with the <literal + >scheduled-thread-pool-max-size</literal> parameter. The default value is + <literal>5</literal> threads. A small number of threads is usually sufficient + for this pool.</para> + </section> + <section> + <title>General Purpose Server Thread Pool</title> + <para>This general purpose thread pool is used for most asynchronous actions on the + server side. It maps internally to a <literal + >java.util.concurrent.ThreadPoolExecutor</literal> instance.</para> + <para>The maximum number of thread used by this pool is configure in <literal + >hornetq-configuration.xml</literal> with the <literal + >thread-pool-max-size</literal> parameter.</para> + <para>If a value of <literal>-1</literal> is used this signifies that the thread pool + has no upper bound and new threads will be created on demand if there are not enough + threads available to satisfy a request. If activity later subsides then threads are + timed-out and closed.</para> + <para>If a value of <literal>n</literal> where <literal>n</literal>is a positive integer + greater than zero is used this signifies that the thread pool is bounded. If more + requests come in and there are no free threads in the pool and the pool is full then + requests will block until a thread becomes available. It is recommended that a + bounded thread pool is used with caution since it can lead to dead-lock situations + if the upper bound is chosen to be too low.</para> + <para>The default value for <literal>thread-pool-max-size</literal> is <literal + >30</literal>.</para> + <para>See the <ulink + url="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ThreadPoolExecutor.htm" + >J2SE javadoc</ulink> for more information on unbounded (cached), and bounded + (fixed) thread pools.</para> + </section> + <section> + <title>Expiry Reaper Thread</title> + <para>A single thread is also used on the server side to scan for expired messages in + queues. We cannot use either of the thread pools for this since this thread needs to + run at its own configurable priority.</para> + <para>For more information on configuring the reaper, please see <xref + linkend="message-expiry"/>.</para> + </section> + <section> + <title>Asynchronous IO</title> + <para>Asynchronous IO has a thread pool for receiving and dispatching events out of the + native layer. You will find it on a thread dump with the prefix + HornetQ-AIO-poller-pool. HornetQ uses one thread per opened file on the journal + (there is usually one).</para> + <para>There is also a single thread used to invoke writes on libaio. We do that to avoid + context switching on libaio that would cause performance issues. You will find this + thread on a thread dump with the prefix HornetQ-AIO-writer-pool.</para> + </section> + </section> + <section id="thread-pooling.client.side"> + <title>Client-Side Thread Management</title> + <para>On the client side, HornetQ maintains a single static scheduled thread pool and a + single static general thread pool for use by all clients using the same classloader in + that JVM instance.</para> + <para>The static scheduled thread pool has a maximum size of <literal>5</literal> threads, + and the general purpose thread pool has an unbounded maximum size.</para> + <para>If required HornetQ can also be configured so that each <literal + >ClientSessionFactory</literal> instance does not use these static pools but instead + maintains its own scheduled and general purpose pool. Any sessions created from that + <literal>ClientSessionFactory</literal> will use those pools instead.</para> + <para>To configure a <literal>ClientSessionFactory</literal> instance to use its own pools, + simply use the appropriate setter methods immediately after creation, for + example:</para> + <programlisting> +ServerLocator locator = HornetQClient.createServerLocatorWithoutHA(...) +ClientSessionFactory myFactory = locator.createClientSessionFactory(); +myFactory.setUseGlobalPools(false); +myFactory.setScheduledThreadPoolMaxSize(10); +myFactory.setThreadPoolMaxSize(-1); </programlisting> + <para>If you're using the JMS API, you can set the same parameters on the + ClientSessionFactory and use it to create the <literal>ConnectionFactory</literal> + instance, for example:</para> + <programlisting> +ConnectionFactory myConnectionFactory = HornetQJMSClient.createConnectionFactory(myFactory);</programlisting> + <para>If you're using JNDI to instantiate <literal>HornetQConnectionFactory</literal> + instances, you can also set these parameters in the <literal>hornetq-jms.xml</literal> + file where you describe your connection factory, for example:</para> + <programlisting> +<connection-factory name="ConnectionFactory"> + <connectors> + <connector-ref connector-name="netty"/> + </connectors> + <entries> + <entry name="ConnectionFactory"/> + <entry name="XAConnectionFactory"/> + </entries> + <use-global-pools>false</use-global-pools> + <scheduled-thread-pool-max-size>10</scheduled-thread-pool-max-size> + <thread-pool-max-size>-1</thread-pool-max-size> +</connection-factory></programlisting> + </section> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/tools.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/tools.xml b/docs/user-manual/en/tools.xml new file mode 100644 index 0000000..12bf70e --- /dev/null +++ b/docs/user-manual/en/tools.xml @@ -0,0 +1,117 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ + <!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> + %BOOK_ENTITIES; + ]> +<chapter id="tools"> + <title>Tools</title> + + <para>HornetQ ships with several helpful command line tools. All tools are available from the hornetq-tools-<version>-jar-with-dependencies.jar. + As the name suggests, this Java archive contains HornetQ along with all of its dependencies. This is done to + simplify the execution of the tools by eliminating the need so specify a classpath. These tools are:</para> + <itemizedlist> + <listitem> + <para><emphasis role="bold"><literal>print-data</literal></emphasis>. Used for low-level inspection of the bindings and message journals. It + takes two parameters - <literal>bindings-directory</literal> and <literal>journal-directory</literal>. These + are the paths to the directories where the bindings and message journals are stored, respectively. For + example: + </para> + <programlisting>java -jar hornetq-tools-<version>-jar-with-dependencies.jar print-data /home/user/hornetq/data/bindings /home/user/hornetq/data/journal</programlisting> + </listitem> + <listitem> + <para><emphasis role="bold"><literal>print-pages</literal></emphasis>. Used for low-level inspection of paged message data. It takes two + parameters - <literal>paging-directory</literal> and <literal>journal-directory</literal>. These are the + paths to the directories where paged messages and the message journals are stored, respectively. For + example: + </para> + <programlisting>java -jar hornetq-tools-<version>-jar-with-dependencies.jar print-pages /home/user/hornetq/data/paging-directory /home/user/hornetq/data/journal</programlisting> + </listitem> + <listitem> + <para><emphasis role="bold"><literal>export</literal></emphasis>. Used for exporting all binding and message data (including paged and large + messages) as well as JMS destinations and connection factories (including JNDI bindings). The export is + structured as XML. This data can then be imported to another server even if the server is a different + version than the original. It takes 4 parameters: + </para> + <itemizedlist> + <listitem> + <para><literal>bindings-directory</literal> - the path to the bindings directory.</para> + </listitem> + <listitem> + <para><literal>journal-directory</literal> - the path to the journal directory.</para> + </listitem> + <listitem> + <para><literal>paging-directory</literal> - the path to the paging directory.</para> + </listitem> + <listitem> + <para><literal>large-messages-directory</literal> - the path to the large-messages directory.</para> + </listitem> + </itemizedlist> + <para>Here's an example:</para> + <programlisting>java -jar hornetq-tools-<version>-jar-with-dependencies.jar export /home/user/hornetq/data/bindings-directory /home/user/hornetq/data/journal-directory /home/user/hornetq/data/paging-directory /home/user/hornetq/data/large-messages</programlisting> + <para>This tool will export directly to standard out so if the data needs to be stored in a file please + redirect as appropriate for the operation system in use. Also, please note that the <literal>export</literal> + tool is single threaded so depending on the size of the journal it could take awhile to complete. + </para> + </listitem> + <listitem> + <para><emphasis role="bold"><literal>import</literal></emphasis>. Used for importing data from an XML document generated by the + <literal>export</literal> tool. The <literal>import</literal> tool reads the XML document and connects + to a HornetQ server via Netty to import all the data. It takes 5 parameters: + </para> + <itemizedlist> + <listitem> + <para><literal>input-file</literal> - the path to the XML file generated by the <literal>export</literal> + tool. + </para> + </listitem> + <listitem> + <para><literal>host</literal> - the IP address or hostname of the server where the data should be + imported. + </para> + </listitem> + <listitem> + <para><literal>port</literal> - the port where HornetQ is listening.</para> + </listitem> + <listitem> + <para><literal>transactional</literal> - a <literal>boolean</literal> flag to indicate whether or not to + send all the <emphasis>message</emphasis> data in a single transaction. Valid values are <literal>true</literal> + or <literal>false</literal>. + </para> + </listitem> + <listitem> + <para><literal>application-server-compatibility</literal> - a <literal>boolean</literal> flag to indicate + whether or not JNDI bindings need special treatment to account for the way JBoss AS7, Wildfly, and + JBoss EAP 6 handle JNDI for remote clients. Each of these application servers require a special JNDI + binding to allow access from remote clients. If this is <literal>true</literal> then every JNDI + binding in the XML will be duplicated in the "java:jboss/exported/" namespace thus allowing both local + and remote clients to use the same name when accessing resources via JNDI. Valid values are + <literal>true</literal> or <literal>false</literal>. + </para> + </listitem> + </itemizedlist> + <para>Here's an example:</para> + <programlisting>java -jar hornetq-tools-<version>-jar-with-dependencies.jar import /home/user/exportData.xml 127.0.0.1 5445 false false</programlisting> + <para>Like the <literal>export</literal> tool the <literal>import</literal> tool is single threaded so + depending on the size of the XML file it may take awhile for the process to complete. + </para> + </listitem> + </itemizedlist> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/transaction-config.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/transaction-config.xml b/docs/user-manual/en/transaction-config.xml new file mode 100644 index 0000000..4f0905e --- /dev/null +++ b/docs/user-manual/en/transaction-config.xml @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="transaction-config"> + <title>Resource Manager Configuration</title> + <para>HornetQ has its own Resource Manager for handling the lifespan of JTA transactions. When a + transaction is started the resource manager is notified and keeps a record of the + transaction and its current state. It is possible in some cases for a transaction to be + started but then forgotten about. Maybe the client died and never came back. If this happens + then the transaction will just sit there indefinitely.</para> + <para>To cope with this HornetQ can, if configured, scan for old transactions and rollback any + it finds. The default for this is 3000000 milliseconds (5 minutes), i.e. any transactions older + than 5 minutes are removed. This timeout can be changed by editing the <literal + >transaction-timeout</literal> property in <literal>hornetq-configuration.xml</literal> (value must be in milliseconds). + The property <literal>transaction-timeout-scan-period</literal> configures how often, in + milliseconds, to scan for old transactions.</para> + <para>Please note that HornetQ will not unilaterally rollback any XA transactions in a prepared state - this must be heuristically rolled + back via the management API if you are sure they will never be resolved by the transaction manager.</para> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/undelivered-messages.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/undelivered-messages.xml b/docs/user-manual/en/undelivered-messages.xml new file mode 100644 index 0000000..ec76c5d --- /dev/null +++ b/docs/user-manual/en/undelivered-messages.xml @@ -0,0 +1,160 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> + +<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ +<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent"> +%BOOK_ENTITIES; +]> +<chapter id="undelivered-messages"> + <title>Message Redelivery and Undelivered Messages</title> + <para>Messages can be delivered unsuccessfully (e.g. if the transacted session used to consume + them is rolled back). Such a message goes back to its queue ready to be redelivered. However, + this means it is possible for a message to be delivered again and again without any success + and remain in the queue, clogging the system.</para> + <para>There are 2 ways to deal with these undelivered messages:</para> + <itemizedlist> + <listitem> + <para>Delayed redelivery.</para> + <para>It is possible to delay messages redelivery to let the client some time to recover + from transient failures and not overload its network or CPU resources</para> + </listitem> + <listitem> + <para>Dead Letter Address.</para> + <para>It is also possible to configure a dead letter address so that after a specified + number of unsuccessful deliveries, messages are removed from the queue and will not be + delivered again</para> + </listitem> + </itemizedlist> + <para>Both options can be combined for maximum flexibility.</para> + <section> + <title>Delayed Redelivery</title> + <para>Delaying redelivery can often be useful in the case that clients regularly fail or + rollback. Without a delayed redelivery, the system can get into a "thrashing" state, with + delivery being attempted, the client rolling back, and delivery being re-attempted ad + infinitum in quick succession, consuming valuable CPU and network resources.</para> + <section id="undelivered-messages.delay"> + <title>Configuring Delayed Redelivery</title> + <para>Delayed redelivery is defined in the address-setting configuration:</para> + <programlisting> +<!-- delay redelivery of messages for 5s --> +<address-setting match="jms.queue.exampleQueue"> + <!-- default is 1.0 --> + <redelivery-delay-multiplier>1.5</redelivery-delay-multiplier> + <!-- default is 0 (no delay) --> + <redelivery-delay>5000</redelivery-delay> + <!-- default is redelivery-delay * 10 --> + <max-redelivery-delay>50000</max-redelivery-delay> + +</address-setting></programlisting> + <para>If a <literal>redelivery-delay</literal> is specified, HornetQ will wait this delay + before redelivering the messages.</para> + <para>By default, there is no redelivery delay (<literal>redelivery-delay</literal>is set + to 0).</para> + <para>Other subsequent messages will be delivery regularly, only the cancelled message + will be sent asynchronously back to the queue after the delay.</para> + <para>You can specify a multiplier that will take effect on top of the redelivery-delay + with a max-redelivery-delay to be taken into account.</para> + <para>The max-redelivery-delay is defaulted to redelivery-delay * 10</para> + <para>Address wildcards can be used to configure redelivery delay for a set of addresses + (see <xref linkend="wildcard-syntax"/>), so you don't have to specify redelivery delay + individually for each address.</para> + </section> + <section> + <title>Example</title> + <para>See <xref linkend="examples.delayed-redelivery"/> for an example which shows how + delayed redelivery is configured and used with JMS.</para> + </section> + </section> + <section> + <title>Dead Letter Addresses</title> + <para>To prevent a client infinitely receiving the same undelivered message (regardless of + what is causing the unsuccessful deliveries), messaging systems define <emphasis + role="italic">dead letter addresses</emphasis>: after a specified unsuccessful delivery + attempts, the message is removed from the queue and send instead to a dead letter address. </para> + <para>Any such messages can then be diverted to queue(s) where they can later be perused by + the system administrator for action to be taken.</para> + <para>HornetQ's addresses can be assigned a dead letter address. Once the messages have been + unsuccessfully delivered for a given number of attempts, they are removed from the queue + and sent to the dead letter address. These <emphasis>dead letter</emphasis> messages can + later be consumed for further inspection.</para> + <section id="undelivered-messages.configuring"> + <title>Configuring Dead Letter Addresses</title> + <para>Dead letter address is defined in the address-setting configuration:</para> + <programlisting> +<!-- undelivered messages in exampleQueue will be sent to the dead letter address + deadLetterQueue after 3 unsuccessful delivery attempts --> +<address-setting match="jms.queue.exampleQueue"> + <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address> + <max-delivery-attempts>3</max-delivery-attempts> +</address-setting></programlisting> + <para>If a <literal>dead-letter-address</literal> is not specified, messages will removed + after <literal>max-delivery-attempts</literal> unsuccessful attempts.</para> + <para>By default, messages are redelivered 10 times at the maximum. Set <literal + >max-delivery-attempts</literal> to -1 for infinite redeliveries.</para> + <para>For example, a dead letter can be set globally for a set of matching addresses and + you can set <literal>max-delivery-attempts</literal> to -1 for a specific address + setting to allow infinite redeliveries only for this address.</para> + <para>Address wildcards can be used to configure dead letter settings for a set of + addresses (see <xref linkend="wildcard-syntax"/>).</para> + </section> + <section> + <title>Dead Letter Properties</title> + <para>Dead letter messages which are consumed from a dead letter address have the following + properties:</para> + <itemizedlist> + <listitem> + <para><literal>_HQ_ORIG_ADDRESS</literal></para> + <para>a String property containing the <emphasis>original address</emphasis> of + the dead letter message</para> + </listitem> + <listitem> + <para><literal>_HQ_ORIG_QUEUE</literal></para> + <para>a String property containing the <emphasis>original queue</emphasis> of + the dead letter message</para> + </listitem> + </itemizedlist> + </section> + <section> + <title>Example</title> + <para>See <xref linkend="examples.dead-letter"/> for an example which shows how dead letter + is configured and used with JMS.</para> + </section> + </section> + <section id="configuring.delivery.count.persistence"> + <title>Delivery Count Persistence</title> + <para>In normal use, HornetQ does not update delivery count <emphasis>persistently</emphasis> + until a message is rolled back (i.e. the delivery count is not updated + <emphasis>before</emphasis> the message is delivered to the consumer). In most messaging + use cases, the messages are consumed, acknowledged and forgotten as soon as they are + consumed. In these cases, updating the delivery count persistently before delivering the + message would add an extra persistent step <emphasis>for each message delivered</emphasis>, + implying a significant performance penalty.</para> + <para>However, if the delivery count is not updated persistently before the message delivery + happens, in the event of a server crash, messages might have been delivered but that will + not have been reflected in the delivery count. During the recovery phase, the server will + not have knowledge of that and will deliver the message with <literal>redelivered</literal> + set to <literal>false</literal> while it should be <literal>true</literal>. </para> + <para>As this behavior breaks strict JMS semantics, HornetQ allows to persist delivery count + before message delivery but disabled it by default for performance implications.</para> + <para>To enable it, set <literal>persist-delivery-count-before-delivery</literal> to <literal + >true</literal> in <literal>hornetq-configuration.xml</literal>:</para> + <programlisting> +<persist-delivery-count-before-delivery>true</persist-delivery-count-before-delivery></programlisting> + </section> +</chapter> http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/using-core.xml ---------------------------------------------------------------------- diff --git a/docs/user-manual/en/using-core.xml b/docs/user-manual/en/using-core.xml new file mode 100644 index 0000000..eb72c79 --- /dev/null +++ b/docs/user-manual/en/using-core.xml @@ -0,0 +1,213 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- ============================================================================= --> +<!-- Copyright © 2009 Red Hat, Inc. and others. --> +<!-- --> +<!-- The text of and illustrations in this document are licensed by Red Hat under --> +<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license ("CC-BY-SA"). --> +<!-- --> +<!-- An explanation of CC-BY-SA is available at --> +<!-- --> +<!-- http://creativecommons.org/licenses/by-sa/3.0/. --> +<!-- --> +<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation --> +<!-- of it, you must provide the URL for the original version. --> +<!-- --> +<!-- Red Hat, as the licensor of this document, waives the right to enforce, --> +<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent --> +<!-- permitted by applicable law. --> +<!-- ============================================================================= --> +<chapter id="using-core"> + <title>Using Core</title> + <para>HornetQ 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. HornetQ will + attempt to deliver higher priority messages before lower priority + ones.</para> + </listitem> + <listitem> + <para>Messages can be specified with an optional expiry time. HornetQ 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>HornetQ 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 + >HornetQClient</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 HornetQ 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:</para> + <programlisting> +ServerLocator locator = HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration( + InVMConnectorFactory.class.getName())); + +ClientSessionFactory factory = locator.createClientSessionFactory(); + +ClientSession session = factory.createSession(); + +session.createQueue("example", "example", true); + +ClientProducer producer = session.createProducer("example"); + +ClientMessage message = session.createMessage(true); + +message.getBodyBuffer().writeString("Hello"); + +producer.send(message); + +session.start(); + +ClientConsumer consumer = session.createConsumer("example"); + +ClientMessage msgReceived = consumer.receive(); + +System.out.println("message = " + msgReceived.getBodyBuffer().readString()); + +session.close();</programlisting> + </section> +</chapter>