activemq-artemis/docs/user-manual/en/configuring-transports.xml

454 lines
31 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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 AttributionShare 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 "ActiveMQ_User_Manual.ent">
%BOOK_ENTITIES;
]>
<chapter id="configuring-transports">
<title>Configuring the Transport</title>
<para>ActiveMQ has a fully pluggable and highly flexible transport layer and defines its own
Service Provider Interface (SPI) to make plugging in a new transport provider relatively
straightforward.</para>
<para>In this chapter we'll describe the concepts required for understanding ActiveMQ transports
and where and how they're configured.</para>
<section id="configuring-transports.acceptors">
<title>Understanding Acceptors</title>
<para>One of the most important concepts in ActiveMQ transports is the
<emphasis>acceptor</emphasis>. Let's dive straight in and take a look at an acceptor
defined in xml in the configuration file <literal
>activemq-configuration.xml</literal>.</para>
<programlisting>
&lt;acceptors>
&lt;acceptor name="netty">
&lt;factory-class>
org.apache.activemq.core.remoting.impl.netty.NettyAcceptorFactory
&lt;/factory-class>
&lt;param key="port" value="5446"/>
&lt;/acceptor>
&lt;/acceptors></programlisting>
<para>Acceptors are always defined inside an <literal>acceptors</literal> element. There can
be one or more acceptors defined in the <literal>acceptors</literal> element. There's no
upper limit to the number of acceptors per server.</para>
<para>Each acceptor defines a way in which connections can be made to the ActiveMQ
server.</para>
<para>In the above example we're defining an acceptor that uses <ulink
url="http://jboss.org/netty">Netty</ulink> to listen for connections at port
<literal>5446</literal>. </para>
<para>The <literal>acceptor</literal> element contains a sub-element <literal
>factory-class</literal>, this element defines the factory used to create acceptor
instances. In this case we're using Netty to listen for connections so we use the Netty
implementation of an <literal>AcceptorFactory</literal> to do this. Basically, the
<literal>factory-class</literal> element determines which pluggable transport we're
going to use to do the actual listening.</para>
<para>The <literal>acceptor</literal> element can also be configured with zero or more
<literal>param</literal> sub-elements. Each <literal>param</literal> element defines
a key-value pair. These key-value pairs are used to configure the specific transport,
the set of valid key-value pairs depends on the specific transport be used and are
passed straight through to the underlying transport.</para>
<para>Examples of key-value pairs for a particular transport would be, say, to configure the
IP address to bind to, or the port to listen at.</para>
<para>Note that unlike versions before 2.4 an Acceptor can now support multiple protocols. By default this will
be all available protocols but can be limited by either the now deprecated <literal>protocol</literal> param or
by setting a comma seperated list to the newly added <literal>protocols</literal> parameter.</para>
</section>
<section id="configuring-transports.connectors">
<title>Understanding Connectors</title>
<para>Whereas acceptors are used on the server to define how we accept connections,
connectors are used by a client to define how it connects to a server.</para>
<para>Let's look at a connector defined in our <literal>activemq-configuration.xml</literal>
file:</para>
<programlisting>
&lt;connectors>
&lt;connector name="netty">
&lt;factory-class>
org.apache.activemq.core.remoting.impl.netty.NettyConnectorFactory
&lt;/factory-class>
&lt;param key="port" value="5446"/>
&lt;/connector>
&lt;/connectors></programlisting>
<para>Connectors can be defined inside a <literal>connectors</literal> element. There can be
one or more connectors defined in the <literal>connectors</literal> element. There's no
upper limit to the number of connectors per server.</para>
<para>You make ask yourself, if connectors are used by the <emphasis>client</emphasis> to
make connections then why are they defined on the <emphasis>server</emphasis>? There are
a couple of reasons for this:</para>
<itemizedlist>
<listitem>
<para>Sometimes the server acts as a client itself when it connects to another
server, for example when one server is bridged to another, or when a server
takes part in a cluster. In this cases the server needs to know how to connect
to other servers. That's defined by <emphasis>connectors</emphasis>.</para>
</listitem>
<listitem>
<para>If you're using JMS and the server side JMS service to instantiate JMS
ConnectionFactory instances and bind them in JNDI, then when creating the
<literal>ActiveMQConnectionFactory</literal> it needs to know what server
that connection factory will create connections to.</para>
<para>That's defined by the <literal>connector-ref</literal> element in the <literal
>activemq-jms.xml</literal> file on the server side. Let's take a look at a
snipped from a <literal>activemq-jms.xml</literal> file that shows a JMS
connection factory that references our netty connector defined in our <literal
>activemq-configuration.xml</literal> file:</para>
<programlisting>
&lt;connection-factory name="ConnectionFactory">
&lt;connectors>
&lt;connector-ref connector-name="netty"/>
&lt;/connectors>
&lt;entries>
&lt;entry name="ConnectionFactory"/>
&lt;entry name="XAConnectionFactory"/>
&lt;/entries>
&lt;/connection-factory></programlisting>
</listitem>
</itemizedlist>
</section>
<section id="configuring-transports.client.side">
<title>Configuring the transport directly from the client side.</title>
<para>How do we configure a core <literal>ClientSessionFactory</literal> with the
information that it needs to connect with a server?</para>
<para>Connectors are also used indirectly when directly configuring a core <literal
>ClientSessionFactory</literal> to directly talk to a server. Although in this case
there's no need to define such a connector in the server side configuration, instead we
just create the parameters and tell the <literal>ClientSessionFactory</literal> which
connector factory to use.</para>
<para>Here's an example of creating a <literal>ClientSessionFactory</literal> which will
connect directly to the acceptor we defined earlier in this chapter, it uses the
standard Netty TCP transport and will try and connect on port 5446 to localhost
(default):</para>
<programlisting>
Map&lt;String, Object> connectionParams = new HashMap&lt;String, Object>();
connectionParams.put(org.apache.activemq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME,
5446);
TransportConfiguration transportConfiguration =
new TransportConfiguration(
"org.apache.activemq.core.remoting.impl.netty.NettyConnectorFactory",
connectionParams);
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(transportConfiguration);
ClientSessionFactory sessionFactory = locator.createClientSessionFactory();
ClientSession session = sessionFactory.createSession(...);
etc</programlisting>
<para>Similarly, if you're using JMS, you can configure the JMS connection factory directly
on the client side without having to define a connector on the server side or define a
connection factory in <literal>activemq-jms.xml</literal>:</para>
<programlisting>
Map&lt;String, Object> connectionParams = new HashMap&lt;String, Object>();
connectionParams.put(org.apache.activemq.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 5446);
TransportConfiguration transportConfiguration =
new TransportConfiguration(
"org.apache.activemq.core.remoting.impl.netty.NettyConnectorFactory",
connectionParams);
ConnectionFactory connectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
Connection jmsConnection = connectionFactory.createConnection();
etc</programlisting>
</section>
<section>
<title>Configuring the Netty transport</title>
<para>Out of the box, ActiveMQ currently uses <ulink url="http://www.jboss.org/netty/"
>Netty</ulink>, a high performance low level network library.</para>
<para>Our Netty transport can be configured in several different ways; to use old (blocking)
Java IO, or NIO (non-blocking), also to use straightforward TCP sockets, SSL, or to
tunnel over HTTP or HTTPS..</para>
<para>We believe this caters for the vast majority of transport requirements.</para>
<section id="configuring-transports.single-port">
<title>Single Port Support</title>
<para>As of version 2.4 ActiveMQ now supports using a single port for all protocols, ActiveMQ will automatically
detect which protocol is being used CORE, AMQP, STOMP or OPENWIRE and use the appropriate ActiveMQ handler. It will also detect
whether protocols such as HTTP or Web Sockets are being used and also use the appropriate decoders</para>
<para>It is possible to limit which protocols are supported by using the <literal>protocols</literal> parameter
on the Acceptor like so:</para>
<programlisting>
&lt;param key="protocols" value="CORE,AMQP"/>
</programlisting>
<note><para>The <literal>protocol</literal> parameter is now deprecated</para></note>
</section>
<section>
<title>Configuring Netty TCP</title>
<para>Netty TCP is a simple unencrypted TCP sockets based transport. Netty TCP can be
configured to use old blocking Java IO or non blocking Java NIO. We recommend you
use the Java NIO on the server side for better scalability with many concurrent
connections. However using Java old IO can sometimes give you better latency than
NIO when you're not so worried about supporting many thousands of concurrent
connections. </para>
<para>If you're running connections across an untrusted network please bear in mind this
transport is unencrypted. You may want to look at the SSL or HTTPS
configurations.</para>
<para>With the Netty TCP transport all connections are initiated from the client side.
I.e. the server does not initiate any connections to the client. This works well
with firewall policies that typically only allow connections to be initiated in one
direction.</para>
<para>All the valid Netty transport keys are defined in the class <literal
>org.apache.activemq.core.remoting.impl.netty.TransportConstants</literal>. Most
parameters can be used either with acceptors or connectors, some only work with
acceptors. The following parameters can be used to configure Netty for simple
TCP:</para>
<itemizedlist>
<listitem>
<para><literal>use-nio</literal>. If this is <literal>true</literal> then Java
non blocking NIO will be used. If set to <literal>false</literal> then old
blocking Java IO will be used.</para>
<para>If you require the server to handle many concurrent connections, we highly
recommend that you use non blocking Java NIO. Java NIO does not maintain a
thread per connection so can scale to many more concurrent connections than
with old blocking IO. If you don't require the server to handle many
concurrent connections, you might get slightly better performance by using
old (blocking) IO. The default value for this property is <literal
>false</literal> on the server side and <literal>false</literal> on the
client side.</para>
</listitem>
<listitem>
<para><literal>host</literal>. This specifies the host name or IP address to
connect to (when configuring a connector) or to listen on (when configuring
an acceptor). The default value for this property is <literal
>localhost</literal>. When configuring acceptors, multiple hosts or IP
addresses can be specified by separating them with commas. It is also
possible to specify <code>0.0.0.0</code> to accept connection from all the
host's network interfaces. It's not valid to specify multiple addresses when
specifying the host for a connector; a connector makes a connection to one
specific address.</para>
<note>
<para>Don't forget to specify a host name or IP address! If you want your
server able to accept connections from other nodes you must specify a
hostname or IP address at which the acceptor will bind and listen for
incoming connections. The default is localhost which of course is not
accessible from remote nodes!</para>
</note>
</listitem>
<listitem>
<para><literal>port</literal>. This specified the port to connect to (when
configuring a connector) or to listen on (when configuring an acceptor). The
default value for this property is <literal>5445</literal>.</para>
</listitem>
<listitem>
<para><literal>tcp-no-delay</literal>. If this is <literal>true</literal> then
<ulink url="http://en.wikipedia.org/wiki/Nagle%27s_algorithm">Nagle's
algorithm</ulink> will be disabled. This is a
<ulink url="http://docs.oracle.com/javase/7/docs/technotes/guides/net/socketOpt.html">Java (client) socket option</ulink>. The default value for this property is <literal>true</literal>.</para>
</listitem>
<listitem>
<para><literal>tcp-send-buffer-size</literal>. This parameter determines the
size of the TCP send buffer in bytes. The default value for this property is
<literal>32768</literal> bytes (32KiB).</para>
<para>TCP buffer sizes should be tuned according to the bandwidth and latency of
your network. Here's a good link that explains the theory behind <ulink
url="http://www-didc.lbl.gov/TCP-tuning/">this</ulink>.</para>
<para>In summary TCP send/receive buffer sizes should be calculated as:</para>
<programlisting>
buffer_size = bandwidth * RTT.</programlisting>
<para>Where bandwidth is in <emphasis>bytes per second</emphasis> and network
round trip time (RTT) is in seconds. RTT can be easily measured using the
<literal>ping</literal> utility.</para>
<para>For fast networks you may want to increase the buffer sizes from the
defaults.</para>
</listitem>
<listitem>
<para><literal>tcp-receive-buffer-size</literal>. This parameter determines the
size of the TCP receive buffer in bytes. The default value for this property
is <literal>32768</literal> bytes (32KiB).</para>
</listitem>
<listitem>
<para><literal>batch-delay</literal>. Before writing packets to the transport,
ActiveMQ can be configured to batch up writes for a maximum of <literal
>batch-delay</literal> milliseconds. This can increase overall
throughput for very small messages. It does so at the expense of an increase
in average latency for message transfer. The default value for this property
is <literal>0</literal> ms.</para>
</listitem>
<listitem>
<para><literal>direct-deliver</literal>. When a message arrives on the server
and is delivered to waiting consumers, by default, the delivery is done on
the same thread as that on which the message arrived. This gives good latency
in environments with relatively small messages and a small number of consumers,
but at the cost of overall throughput and scalability - especially on multi-core
machines. If you want the lowest latency and a possible reduction in throughput
then you can use the default value for <literal>direct-deliver</literal> (i.e.
true). If you are willing to take some small extra hit on latency but want the
highest throughput set <literal>direct-deliver</literal> to <literal>false
</literal>.</para>
</listitem>
<listitem>
<para><literal>nio-remoting-threads</literal>. When configured to use NIO,
ActiveMQ will, by default, use a number of threads equal to three times the
number of cores (or hyper-threads) as reported by <literal
>Runtime.getRuntime().availableProcessors()</literal> for processing
incoming packets. If you want to override this value, you can set the number
of threads by specifying this parameter. The default value for this
parameter is <literal>-1</literal> which means use the value from <literal
>Runtime.getRuntime().availableProcessors()</literal> * 3.</para>
</listitem>
<listitem>
<para><literal>local-address</literal>. When configured a Netty Connector it is possible to specify
which local address the client will use when connecting to the remote address. This is typically used
in the Application Server or when running Embedded to control which address is used for outbound
connections. If the local-address is not set then the connector will use any local address available</para>
</listitem>
<listitem>
<para><literal>local-port</literal>. When configured a Netty Connector it is possible to specify
which local port the client will use when connecting to the remote address. This is typically used
in the Application Server or when running Embedded to control which port is used for outbound
connections. If the local-port default is used, which is 0, then the connector will let the
system pick up an ephemeral port. valid ports are 0 to 65535</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Configuring Netty SSL</title>
<para>Netty SSL is similar to the Netty TCP transport but it provides additional
security by encrypting TCP connections using the Secure Sockets Layer SSL</para>
<para>Please see the examples for a full working example of using Netty SSL.</para>
<para>Netty SSL uses all the same properties as Netty TCP but adds the following
additional properties:</para>
<itemizedlist>
<listitem>
<para><literal>ssl-enabled</literal></para>
<para>Must be <literal>true</literal> to enable SSL. Default is <literal>false</literal>.</para>
</listitem>
<listitem>
<para><literal>key-store-path</literal></para>
<para>When used on an <literal>acceptor</literal> this is the path to the SSL key
store on the server which holds the server's certificates (whether self-signed
or signed by an authority).</para>
<para>When used on a <literal>connector</literal> this is the path to the client-side
SSL key store which holds the client certificates. This is only relevant
for a <literal>connector</literal> if you are using 2-way SSL (i.e. mutual
authentication). Although this value is configured on the server, it is
downloaded and used by the client. If the client needs to use a different path
from that set on the server then it can override the server-side setting by either
using the customary "javax.net.ssl.keyStore" system property or the ActiveMQ-specific
"org.apache.activemq.ssl.keyStore" system property. The ActiveMQ-specific system property
is useful if another component on client is already making use of the standard, Java
system property.</para>
</listitem>
<listitem>
<para><literal>key-store-password</literal></para>
<para>When used on an <literal>acceptor</literal> this is the password for the
server-side keystore.</para>
<para>When used on a <literal>connector</literal> this is the password for the
client-side keystore. This is only relevant for a <literal>connector</literal>
if you are using 2-way SSL (i.e. mutual authentication). Although this value can
be configured on the server, it is downloaded and used by the client. If the client
needs to use a different password from that set on the server then it can override
the server-side setting by either using the customary "javax.net.ssl.keyStorePassword"
system property or the ActiveMQ-specific "org.apache.activemq.ssl.keyStorePassword" system
property. The ActiveMQ-specific system property is useful if another component on client
is already making use of the standard, Java system property.</para>
</listitem>
<listitem>
<para><literal>trust-store-path</literal></para>
<para>When used on an <literal>acceptor</literal> this is the path to the server-side
SSL key store that holds the keys of all the clients that the server trusts. This
is only relevant for an <literal>acceptor</literal> if you are using 2-way SSL
(i.e. mutual authentication).</para>
<para>When used on a <literal>connector</literal> this is the path to the client-side
SSL key store which holds the public keys of all the servers that the client
trusts. Although this value can be configured on the server, it is downloaded and
used by the client. If the client needs to use a different path
from that set on the server then it can override the server-side setting by either
using the customary "javax.net.ssl.trustStore" system property or the ActiveMQ-specific
"org.apache.activemq.ssl.trustStore" system property. The ActiveMQ-specific system property
is useful if another component on client is already making use of the standard, Java
system property.</para>
</listitem>
<listitem>
<para><literal>trust-store-password</literal></para>
<para>When used on an <literal>acceptor</literal> this is the password for the
server-side trust store. This is only relevant for an <literal>acceptor</literal>
if you are using 2-way SSL (i.e. mutual authentication).</para>
<para>When used on a <literal>connector</literal> this is the password for the
client-side truststore. Although this value can be configured on the server, it is
downloaded and used by the client. If the client
needs to use a different password from that set on the server then it can override
the server-side setting by either using the customary "javax.net.ssl.trustStorePassword"
system property or the ActiveMQ-specific "org.apache.activemq.ssl.trustStorePassword" system
property. The ActiveMQ-specific system property is useful if another component on client
is already making use of the standard, Java system property.</para>
</listitem>
<listitem>
<para><literal>enabled-cipher-suites</literal></para>
<para>Whether used on an <literal>acceptor</literal> or <literal>connector</literal> this is a
comma separated list of cipher suites used for SSL communication. The default value is
<literal>null</literal> which means the JVM's default will be used.</para>
</listitem>
<listitem>
<para><literal>enabled-protocols</literal></para>
<para>Whether used on an <literal>acceptor</literal> or <literal>connector</literal> this is a
comma separated list of protocols used for SSL communication. The default value is
<literal>null</literal> which means the JVM's default will be used.</para>
</listitem>
<listitem>
<para><literal>need-client-auth</literal></para>
<para>This property is only for an <literal>acceptor</literal>. It tells a client connecting to this
acceptor that 2-way SSL is required. Valid values are <literal>true</literal> or
<literal>false</literal>. Default is <literal>false</literal>.</para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Configuring Netty HTTP</title>
<para>Netty HTTP tunnels packets over the HTTP protocol. It can be useful in scenarios
where firewalls only allow HTTP traffic to pass.</para>
<para>Please see the examples for a full working example of using Netty HTTP.</para>
<para>Netty HTTP uses the same properties as Netty TCP but adds the following additional
properties:</para>
<itemizedlist>
<listitem>
<para><literal>http-enabled</literal>. This is now no longer needed as of version 2.4. With single
port support ActiveMQ will now automatically detect if http is being used and configure itself.</para>
</listitem>
<listitem>
<para><literal>http-client-idle-time</literal>. How long a client can be idle
before sending an empty http request to keep the connection alive</para>
</listitem>
<listitem>
<para><literal>http-client-idle-scan-period</literal>. How often, in
milliseconds, to scan for idle clients</para>
</listitem>
<listitem>
<para><literal>http-response-time</literal>. How long the server can wait before
sending an empty http response to keep the connection alive</para>
</listitem>
<listitem>
<para><literal>http-server-scan-period</literal>. How often, in milliseconds, to
scan for clients needing responses</para>
</listitem>
<listitem>
<para><literal>http-requires-session-id</literal>. If true the client will wait
after the first call to receive a session id. Used the http connector is
connecting to servlet acceptor (not recommended) </para>
</listitem>
</itemizedlist>
</section>
<section>
<title>Configuring Netty Servlet</title>
<para>As of 2.4 ActiveMQ Servlet support will be provided via Undertow in Wildfly</para>
</section>
</section>
</chapter>