This commit is contained in:
Clebert Suconic 2017-08-31 12:04:08 -04:00
commit 184a52eb24
11 changed files with 145 additions and 545 deletions

View File

@ -29,21 +29,11 @@ If the client has sent more commands than were received before failover
it can replay any sent commands from its buffer so that the client and
server can reconcile their states.Ac
The size of this buffer is configured by the `ConfirmationWindowSize`
parameter, when the server has received `ConfirmationWindowSize` bytes
of commands and processed them it will send back a command confirmation
to the client, and the client can then free up space in the buffer.
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 this parameter
can be configured in the jms configuration using the element
`confirmationWindowSize` a. If you're using JMS but not using JNDI
then you can set these values directly on the
`ActiveMQConnectionFactory` instance using the appropriate setter
method.
If you're using the core API you can set these values directly on the
`ServerLocator` instance using the appropriate setter method.
The size of this buffer is configured with the `confirmationWindowSize`
parameter on the connection URL. When the server has received
`confirmationWindowSize` bytes of commands and processed them it will
send back a command confirmation to the client, and the client can then
free up space in the buffer.
The window is specified in bytes.
@ -110,22 +100,7 @@ Client reconnection is configured using the following parameters:
down. A value of `-1` signifies an unlimited number of attempts. The
default value is `0`.
If you're using JMS and you're using JNDI on the client to look up your
JMS connection factory instances then you can specify these parameters
in the JNDI context environment in, e.g. `jndi.properties`:
java.naming.factory.initial = ActiveMQInitialContextFactory
connection.ConnectionFactory=tcp://localhost:61616?retryInterval=1000&retryIntervalMultiplier=1.5&maxRetryInterval=60000&reconnectAttempts=1000
If you're using JMS, but instantiating your JMS connection factory
directly, you can specify the parameters using the appropriate setter
methods on the `ActiveMQConnectionFactory` immediately after creating
it.
If you're using the core API and instantiating the `ServerLocator`
instance directly you can also specify the parameters using the
appropriate setter methods on the `ServerLocator` immediately after
creating it.
All of these parameters are set on the URL used to connect to the broker.
If your client does manage to reconnect but the session is no longer
available on the server, for instance if the server has been restarted

View File

@ -348,88 +348,28 @@ Let's discuss how to configure an Apache ActiveMQ Artemis client to use discover
discover a list of servers to which it can connect. The way to do this
differs depending on whether you're using JMS or the core API.
##### Configuring client discovery using JMS
##### Configuring client discovery
If you're using JMS and you're using JNDI on the client to look up your
JMS connection factory instances then you can specify these parameters
in the JNDI context environment. e.g. in `jndi.properties`. Simply
ensure the host:port combination matches the group-address and
group-port from the corresponding `broadcast-group` on the server. Let's
take a look at an example:
Use the `udp` URL scheme and a host:port combination matches the group-address and
group-port from the corresponding `broadcast-group` on the server:
java.naming.factory.initial = ActiveMQInitialContextFactory
connectionFactory.myConnectionFactory=udp://231.7.7.7:9876
udp://231.7.7.7:9876
The element `discovery-group-ref` specifies the name of a discovery
group defined in `broker.xml`.
When this connection factory is downloaded from JNDI by a client
application and JMS connections are created from it, those connections
will be load-balanced across the list of servers that the discovery
group maintains by listening on the multicast address specified in the
discovery group configuration.
Connections created using this URI will be load-balanced across the
list of servers that the discovery group maintains by listening on
the multicast address specified in the discovery group configuration.
If you're using JMS, but you're not using JNDI to lookup a connection
factory - you're instantiating the JMS connection factory directly then
you can specify the discovery group parameters directly when creating
the JMS connection factory. Here's an example:
The aforementioned `refreshTimeout` parameter can be set directly in the URI.
``` java
final String groupAddress = "231.7.7.7";
final int groupPort = 9876;
ConnectionFactory jmsConnectionFactory =
ActiveMQJMSClient.createConnectionFactory(new DiscoveryGroupConfiguration(groupAddress, groupPort,
new UDPBroadcastGroupConfiguration(groupAddress, groupPort, null, -1)), JMSFactoryType.CF);
Connection jmsConnection1 = jmsConnectionFactory.createConnection();
Connection jmsConnection2 = jmsConnectionFactory.createConnection();
```
The `refresh-timeout` can be set directly on the
DiscoveryGroupConfiguration by using the setter method
`setDiscoveryRefreshTimeout()` if you want to change the default value.
There is also a further parameter settable on the
DiscoveryGroupConfiguration using the setter method
`setDiscoveryInitialWaitTimeout()`. If the connection factory is used
immediately after creation then it may not have had enough time to
received broadcasts from all the nodes in the cluster. On first usage,
the connection factory will make sure it waits this long since creation
before creating the first connection. The default value for this
parameter is `10000` milliseconds.
##### Configuring client discovery using Core
If you're using the core API to directly instantiate
`ClientSessionFactory` instances, then you can specify the discovery
group parameters directly when creating the session factory. Here's an
example:
``` java
final String groupAddress = "231.7.7.7";
final int groupPort = 9876;
ServerLocator factory = ActiveMQClient.createServerLocatorWithHA(new DiscoveryGroupConfiguration(groupAddress, groupPort,
new UDPBroadcastGroupConfiguration(groupAddress, groupPort, null, -1))));
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session1 = factory.createSession();
ClientSession session2 = factory.createSession();
```
The `refresh-timeout` can be set directly on the
DiscoveryGroupConfiguration by using the setter method
`setDiscoveryRefreshTimeout()` if you want to change the default value.
There is also a further parameter settable on the
DiscoveryGroupConfiguration using the setter method
`setDiscoveryInitialWaitTimeout()`. If the session factory is used
immediately after creation then it may not have had enough time to
received broadcasts from all the nodes in the cluster. On first usage,
the session factory will make sure it waits this long since creation
before creating the first session. The default value for this parameter
is `10000` milliseconds.
There is also a URL parameter named `initialWaitTimeout`. If the corresponding
JMS connection factory or core session factory is used immediately after
creation then it may not have had enough time to received broadcasts from
all the nodes in the cluster. On first usage, the connection factory will
make sure it waits this long since creation before creating the first
connection. The default value for this parameter is `10000` milliseconds.
### Discovery using static Connectors
@ -455,57 +395,15 @@ the cluster connection configuration.
A static list of possible servers can also be used by a normal client.
##### Configuring client discovery using JMS
##### Configuring client discovery
If you're using JMS and you're using JNDI on the client to look up your
JMS connection factory instances then you can specify these parameters
in the JNDI context environment in, e.g. `jndi.properties`:
A list of servers to be used for the initial connection attempt can be
specified in the connection URI using a syntax with `()`, e.g.:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.myConnectionFactory=(tcp://myhost:61616,tcp://myhost2:61616)
(tcp://myhost:61616,tcp://myhost2:61616)?reconnectAttempts=5
The `connectionFactory.myConnectionFactory` contains a list of servers to use for the
connection factory. When this connection factory used client application
and JMS connections are created from it, those connections will be
load-balanced across the list of servers defined within the brackets `()`.
The brackets are expanded so the same query cab be appended after the last bracket for ease.
If you're using JMS, but you're not using JNDI to lookup a connection
factory - you're instantiating the JMS connection factory directly then
you can specify the connector list directly when creating the JMS
connection factory. Here's an example:
``` java
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("host", "myhost");
map.put("port", "61616");
TransportConfiguration server1 = new TransportConfiguration(NettyConnectorFactory.class.getName(), map);
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("host", "myhost2");
map2.put("port", "61617");
TransportConfiguration server2 = new TransportConfiguration(NettyConnectorFactory.class.getName(), map2);
ActiveMQConnectionFactory cf = ActiveMQJMSClient.createConnectionFactoryWithHA(JMSFactoryType.CF, server1, server2);
```
##### Configuring client discovery using Core
If you are using the core API then the same can be done as follows:
``` java
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("host", "myhost");
map.put("port", "61616");
TransportConfiguration server1 = new TransportConfiguration(NettyConnectorFactory.class.getName(), map);
HashMap<String, Object> map2 = new HashMap<String, Object>();
map2.put("host", "myhost2");
map2.put("port", "61617");
TransportConfiguration server2 = new TransportConfiguration(NettyConnectorFactory.class.getName(), map2);
ServerLocator locator = ActiveMQClient.createServerLocatorWithHA(server1, server2);
ClientSessionFactory factory = locator.createSessionFactory();
ClientSession session = factory.createSession();
```
The brackets are expanded so the same query can be appended after the last
bracket for ease.
## Server-Side Message Load Balancing
@ -841,40 +739,18 @@ using JMS or the core API. If you don't specify a policy then the
default will be used which is
`org.apache.activemq.artemis.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy`.
If you're using JMS and you're using JNDI on the client to look up your
JMS connection factory instances then you can specify these parameters
in the JNDI context environment in, e.g. `jndi.properties`, to specify
the load balancing policy directly:
The parameter `loadBalancingPolicyClassName` can be set on the URI to
configure what load balancing policy to use:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connection.myConnectionFactory=tcp://localhost:61616?loadBalancingPolicyClassName=org.apache.activemq.artemis.api.core.client.loadbalance.RandomConnectionLoadBalancingPolicy
The above example would instantiate a JMS connection factory that uses
the random connection load balancing policy.
If you're using JMS but you're instantiating your connection factory
directly on the client side then you can set the load balancing policy
using the setter on the `ActiveMQConnectionFactory` before using it:
``` java
ConnectionFactory jmsConnectionFactory = ActiveMQJMSClient.createConnectionFactory(...);
jmsConnectionFactory.setLoadBalancingPolicyClassName("com.acme.MyLoadBalancingPolicy");
```
If you're using the core API, you can set the load balancing policy
directly on the `ServerLocator` instance you are using:
``` java
ServerLocator locator = ActiveMQClient.createServerLocatorWithHA(server1, server2);
locator.setLoadBalancingPolicyClassName("com.acme.MyLoadBalancingPolicy");
```
tcp://localhost:61616?loadBalancingPolicyClassName=org.apache.activemq.artemis.api.core.client.loadbalance.RandomConnectionLoadBalancingPolicy
The set of servers over which the factory load balances can be
determined in one of two ways:
- Specifying servers explicitly
- Specifying servers explicitly in the URL. This also requires setting
the `useTopologyForLoadBalancing` parameter to `false` on the URL.
- Using discovery.
- Using discovery. This is the default behavior.
## Specifying Members of a Cluster Explicitly

View File

@ -24,29 +24,27 @@ In the above example we're defining an acceptor that uses
[Netty](http://netty.io/) to listen for connections at port
`61617`.
The `acceptor` element contains a `URI` that defines the kind of Acceptor
to create along with its configuration. The `schema` part of the `URI`
The `acceptor` element contains a `URL` that defines the kind of Acceptor
to create along with its configuration. The `schema` part of the `URL`
defines the Acceptor type which can either be `tcp` or `vm` which is
`Netty` or an In VM Acceptor respectively. For `Netty` the host and the
port of the `URI` define what host and port the Acceptor will bind to. For
In VM the `Authority` part of the `URI` defines a unique server id.
port of the `URL` define what host and port the `acceptor` will bind to. For
In VM the `Authority` part of the `URL` defines a unique server id.
The `acceptor` can also be configured with a set of key, value pairs
The `acceptor` can also be configured with a set of key=value pairs
used to configure the specific transport, the set of
valid key-value pairs depends on the specific transport be used and are
valid key=value pairs depends on the specific transport be used and are
passed straight through to the underlying transport. These are set on the
`URI` as part of the query, like so:
`URL` as part of the query, like so:
<acceptor name="netty">tcp://localhost:61617?sslEnabled=true&keyStorePath=/path</acceptor>
## Understanding Connectors
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.
connections, connectors are used to define how to connect to a server.
Let's look at a connector defined in our `broker.xml`
file:
Let's look at a connector defined in our `broker.xml` file:
<connectors>
<connector name="netty">tcp://localhost:61617</connector>
@ -56,40 +54,23 @@ Connectors can be defined inside a `connectors` element. There can be
one or more connectors defined in the `connectors` element. There's no
upper limit to the number of connectors per server.
You make ask yourself, if connectors are used by the *client* to make
connections then why are they defined on the *server*? There are a
couple of reasons for this:
A `connector` is used when the server acts as a client itself, e.g.:
- 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
*connectors*.
- When one server is bridged to another
- When a server takes part in a cluster
- If you're using JMS and you're using JNDI on the client to look up
your JMS connection factory instances then when creating the
`ActiveMQConnectionFactory` it needs to know what server that
connection factory will create connections to.
That's defined by the `java.naming.provider.url` element in the JNDI
context environment, e.g. `jndi.properties`. Behind the scenes, the
`ActiveMQInitialContextFactory` uses the
`java.naming.provider.url` to construct the transport. Here's a
simple example:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.MyConnectionFactory=tcp://myhost:61616
In these cases the server needs to know how to connect to other servers.
That's defined by `connectors`.
## Configuring the transport directly from the client side.
How do we configure a core `ClientSessionFactory` with the information
that it needs to connect with a server?
Connectors are also used indirectly when directly configuring a core
Connectors are also used indirectly when configuring a core
`ClientSessionFactory` 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
`ClientSessionFactory` which connector factory to use.
configuration, instead we just specify the appropriate URI.
Here's an example of creating a `ClientSessionFactory` which will
connect directly to the acceptor we defined earlier in this chapter, it
@ -97,43 +78,20 @@ uses the standard Netty TCP transport and will try and connect on port
61617 to localhost (default):
``` java
Map<String, Object> connectionParams = new HashMap<String, Object>();
connectionParams.put(org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME,
61617);
TransportConfiguration transportConfiguration =
new TransportConfiguration(
"org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory",
connectionParams);
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(transportConfiguration);
ServerLocator locator = ActiveMQClient.createServerLocator("tcp://localhost:61617");
ClientSessionFactory sessionFactory = locator.createClientSessionFactory();
ClientSession session = sessionFactory.createSession(...);
etc
```
Similarly, if you're using JMS, you can configure the JMS connection
factory directly on the client side:
``` java
Map<String, Object> connectionParams = new HashMap<String, Object>();
connectionParams.put(org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants.PORT_PROP_NAME, 61617);
TransportConfiguration transportConfiguration =
new TransportConfiguration(
"org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory",
connectionParams);
ConnectionFactory connectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(JMSFactoryType.CF, transportConfiguration);
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61617");
Connection jmsConnection = connectionFactory.createConnection();
etc
```
## Configuring the Netty transport
@ -162,25 +120,19 @@ It is possible to limit which protocols are supported by using the
## Configuring Netty TCP
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.
If you're running connections across an untrusted network please bear in
Netty TCP is a simple unencrypted TCP sockets based transport. 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.
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
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.
All the valid Netty transport keys are defined in the class
`org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants`. Most
parameters can be used either with acceptors or connectors, some only
All the valid keys for the `tcp` URL scheme used for Netty are defined in the
class `org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants`.
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:
@ -474,9 +426,9 @@ Please see the examples for a full working example of using Netty HTTP.
Netty HTTP uses the same properties as Netty TCP but adds the following
additional properties:
- `httpEnabled`. This is now no longer needed as of version 2.4. With
single port support Apache ActiveMQ Artemis will now automatically detect if http
is being used and configure itself.
- `httpEnabled`. This is now no longer needed. With single port support
Apache ActiveMQ Artemis will now automatically detect if http is being
used and configure itself.
- `httpClientIdleTime`. How long a client can be idle before
sending an empty http request to keep the connection alive

View File

@ -54,7 +54,7 @@ Connection jmsConnection = null;
try
{
ConnectionFactory jmsConnectionFactory = ActiveMQJMSClient.createConnectionFactoryWithoutHA(...);
ConnectionFactory jmsConnectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
jmsConnection = jmsConnectionFactory.createConnection();
@ -76,7 +76,7 @@ Or with using auto-closeable feature from Java, which can save a few lines of co
try (
ActiveMQConnectionFactory jmsConnectionFactory = new ActiveMQConnectionFactory();
ActiveMQConnectionFactory jmsConnectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection jmsConnection = jmsConnectionFactory.createConnection())
{
... do some stuff with the connection...
@ -101,26 +101,23 @@ Apache ActiveMQ Artemis supports client reconnection, so we don't want to clean
from reconnecting, as it won't be able to find its old sessions on the
server.
Apache ActiveMQ Artemis makes all of this configurable. For each `ClientSessionFactory`
we define a *connection TTL*. Basically, the TTL determines how long the
server will keep a connection alive in the absence of any data arriving
from the client. The client will automatically send "ping" packets
periodically to prevent the server from closing it down. If the server
doesn't receive any packets on a connection for the connection TTL time,
then it will automatically close all the sessions on the server that
relate to that connection.
Apache ActiveMQ Artemis makes all of this configurable via a *connection TTL*.
Basically, the TTL determines how long the server will keep a connection
alive in the absence of any data arriving from the client. The client will
automatically send "ping" packets periodically to prevent the server from
closing it down. If the server doesn't receive any packets on a connection
for the connection TTL time, then it will automatically close all the
sessions on the server that relate to that connection.
If you're using JMS, the connection TTL is defined by the
`ConnectionTTL` attribute on a `ActiveMQConnectionFactory` instance, or
if you're deploying JMS connection factory instances direct into JNDI on
the server side, you can specify it in the xml config, using the
parameter `connectionTtl`.
The connection TTL is configured on the URI using the `connectionTtl`
parameter.
The default value for connection ttl on an "unreliable" connection (e.g.
a Netty connection) is `60000`ms, i.e. 1 minute. The default value for
connection ttl on a "reliable" connection (e.g. an in-vm connection) is
`-1`. A value of `-1` for `ConnectionTTL` means the server will never
time out the connection on the server side.
a Netty connection using the `tcp` URL scheme) is `60000`ms, i.e. 1 minute.
The default value for connection ttl on a "reliable" connection (e.g. an
in-vm connection using the `vm` URL scheme) is `-1`. A value of `-1` for
`connectionTTL` means the server will never time out the connection on
the server side.
If you do not wish clients to be able to specify their own connection
TTL, you can override all values used by a global value set on the
@ -141,16 +138,7 @@ and JMS connections are always closed explicitly in a `finally` block
when you are finished using them.
If you fail to do so, Apache ActiveMQ Artemis will detect this at garbage collection
time, and log a warning similar to the following in the logs (If you are
using JMS the warning will involve a JMS connection not a client
session):
[Finalizer] 20:14:43,244 WARNING [org.apache.activemq.artemis.core.client.impl.DelegatingSession] I'm closing a ClientSession you left open. Please make sure you close all ClientSessions explicitly before let
ting them go out of scope!
[Finalizer] 20:14:43,244 WARNING [org.apache.activemq.artemis.core.client.impl.DelegatingSession] The session you didn't close was created here:
java.lang.Exception
at org.apache.activemq.artemis.core.client.impl.DelegatingSession.<init>(DelegatingSession.java:83)
at org.acme.yourproject.YourClass (YourClass.java:666)
time, and log a warning (If you are using JMS the warning will involve a JMS connection).
Apache ActiveMQ Artemis will then close the connection / client session for you.
@ -175,16 +163,8 @@ either initiate failover, or call any `FailureListener` instances (or
`ExceptionListener` instances if you are using JMS) depending on how
it has been configured.
This is controlled by the `clientFailureCheckPeriod` attribute which can
be set a number of ways:
- If you're using the core API then you can invoke `org.apache.activemq.artemis.api.core.client.ServerLocator.setClientFailureCheckPeriod(long)`
- If you're using JMS then you can invoke `org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory.setClientFailureCheckPeriod(long)`
on your `javax.jms.ConnectionFactory`.
- However, the simplest way is to just set the `clientFailureCheckPeriod`
on the URL your client is using to connect, e.g.
This is controlled by setting the `clientFailureCheckPeriod` parameter
on the URI your client is using to connect, e.g.
`tcp://localhost:61616?clientFailureCheckPeriod=30000`.
The default value for client failure check period on an "unreliable"

View File

@ -72,10 +72,10 @@ thus preventing them being processed by the fast consumer. The fast
consumer is therefore sitting idle when it could be processing the
other messages.
To allow slow consumers, set the `consumerWindowSize` to 0 (for no
buffer at all). This will prevent the slow consumer from buffering
any messages on the client side. Messages will remain on the server
side ready to be consumed by other consumers.
To allow slow consumers, set `consumerWindowSize` on the URI to 0
(for no buffer at all). This will prevent the slow consumer from
buffering any messages on the client side. Messages will remain on
the server side ready to be consumed by other consumers.
Setting this to 0 can give deterministic distribution between
multiple consumers on a queue.
@ -86,63 +86,25 @@ consumers but are in-between. In that case, setting the value of
use case and requires benchmarks to find the optimal value, but a value
of 1MiB is fine in most cases.
### Using Core API
If Apache ActiveMQ Artemis Core API is used, the consumer window size is specified by
`ServerLocator.setConsumerWindowSize()` method and some of the
`ClientSession.createConsumer()` methods.
### Using JMS
If JNDI is used on the client to instantiate and look up the connection
factory the consumer window size is configured in the JNDI context
environment, e.g. `jndi.properties`. Here's a simple example using the
"ConnectionFactory" connection factory which is available in the context
by default:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.myConnectionFactory=tcp://localhost:61616?consumerWindowSize=0
If the connection factory is directly instantiated, the consumer window
size is specified by `ActiveMQConnectionFactory.setConsumerWindowSize()`
method.
Please see the examples for an example which shows how to configure Apache ActiveMQ Artemis to
prevent consumer buffering when dealing with slow consumers.
Please see [the examples chapter](examples.md) for an example which shows
how to configure ActiveMQ Artemis to prevent consumer buffering when dealing
with slow consumers.
## Rate limited flow control
It is also possible to control the *rate* at which a consumer can
consume messages. This is a form of throttling and can be used to make
sure that a consumer never consumes messages at a rate faster than the
rate specified.
rate specified. This is configured using the `consumerMaxRate` URI
parameter.
The rate must be a positive integer to enable this functionality and is
the maximum desired message consumption rate specified in units of
messages per second. Setting this to `-1` disables rate limited flow
control. The default value is `-1`.
Please see [the examples chapter](examples.md) for a working example of limiting consumer rate.
### Using Core API
If the Apache ActiveMQ Artemis core API is being used the rate can be set via the
`ServerLocator.setConsumerMaxRate(int consumerMaxRate)` method or
alternatively via some of the `ClientSession.createConsumer()` methods.
### Using JMS
If JNDI is used to instantiate and look up the connection factory, the
max rate can be configured in the JNDI context environment, e.g.
`jndi.properties`. Here's a simple example using the "ConnectionFactory"
connection factory which is available in the context by default:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:61616?consumerMaxRate=10
If the connection factory is directly instantiated, the max rate size
can be set via the `ActiveMQConnectionFactory.setConsumerMaxRate(int
consumerMaxRate)` method.
Please see [the examples chapter](examples.md) for a working example of
limiting consumer rate.
> **Note**
>
@ -152,9 +114,6 @@ can be set via the `ActiveMQConnectionFactory.setConsumerMaxRate(int
> buffer. So if you had a slow rate limit and a high window based limit
> the clients internal buffer would soon fill up with messages.
Please see [the examples chapter](examples.md) for an example which shows how to configure ActiveMQ Artemis to
prevent consumer buffering when dealing with slow consumers.
## Producer flow control
Apache ActiveMQ Artemis also can limit the amount of data sent from a client to a
@ -171,33 +130,13 @@ As producers run low on credits they request more from the server, when
the server sends them more credits they can send more messages.
The amount of credits a producer requests in one go is known as the
*window size*.
*window size* and it is controlled by the `producerWindowSize` URI
parameter.
The window size therefore determines the amount of bytes that can be
in-flight at any one time before more need to be requested - this
prevents the remoting connection from getting overloaded.
#### Using Core API
If the Apache ActiveMQ Artemis core API is being used, window size can be set via the
`ServerLocator.setProducerWindowSize(int producerWindowSize)` method.
#### Using JMS
If JNDI is used to instantiate and look up the connection factory, the
producer window size can be configured in the JNDI context environment,
e.g. `jndi.properties`. Here's a simple example using the
"ConnectionFactory" connection factory which is available in the context
by default:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.myConnectionFactory=tcp://localhost:61616?producerWindowSize=10
If the connection factory is directly instantiated, the producer window
size can be set via the
`ActiveMQConnectionFactory.setProducerWindowSize(int
producerWindowSize)` method.
#### Blocking producer window based flow control using CORE protocol
When using the CORE protocol (used by both the Artemis Core Client and Artemis JMS Client)
@ -300,31 +239,12 @@ rejecting messages once the address size is reached.
Apache ActiveMQ Artemis also allows the rate a producer can emit message to be limited,
in units of messages per second. By specifying such a rate, Apache ActiveMQ Artemis
will ensure that producer never produces messages at a rate higher than
that specified.
that specified. This is controlled by the `producerMaxRate` URL parameter.
The rate must be a positive integer to enable this functionality and is
the maximum desired message consumption rate specified in units of
The `producerMaxRate` must be a positive integer to enable this functionality and is
the maximum desired message production rate specified in units of
messages per second. Setting this to `-1` disables rate limited flow
control. The default value is `-1`.
Please see [the examples chapter](examples.md) for a working example of limiting producer rate.
#### Using Core API
If the Apache ActiveMQ Artemis core API is being used the rate can be set via the
`ServerLocator.setProducerMaxRate(int producerMaxRate)` method or
alternatively via some of the `ClientSession.createProducer()` methods.
#### Using JMS
If JNDI is used to instantiate and look up the connection factory, the
max rate size can be configured in the JNDI context environment, e.g.
`jndi.properties`. Here's a simple example using the "ConnectionFactory"
connection factory which is available in the context by default:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.myConnectionFactory=tcp://localhost:61616?producerMaxRate=10
If the connection factory is directly instantiated, the max rate size
can be set via the `ActiveMQConnectionFactory.setProducerMaxRate(int
producerMaxRate)` method.
Please see [the examples chapter](examples.md) for a working example of limiting
producer rate.

View File

@ -840,11 +840,9 @@ Since the client does not learn about the full topology until after the
first connection is made there is a window where it does not know about
the backup. If a failure happens at this point the client can only try
reconnecting to the original live server. To configure how many attempts
the client will make you can set the property `initialConnectAttempts`
on the `ClientSessionFactoryImpl` or `ActiveMQConnectionFactory` or
`initial-connect-attempts` in xml. The default for this is `0`, that is
try only once. Once the number of attempts has been made an exception
will be thrown.
the client will make you can set the URL parameter `initialConnectAttempts`.
The default for this is `0`, that is try only once. Once the number of
attempts has been made an exception will be thrown.
For examples of automatic failover with transacted and non-transacted
JMS sessions, please see [the examples](examples.md) chapter.

View File

@ -49,7 +49,7 @@ on a different physical volume to the message journal or paging directory.
Any message larger than a certain size is considered a large message.
Large messages will be split up and sent in fragments. This is
determined by the parameter `minLargeMessageSize`
determined by the URL parameter `minLargeMessageSize`
> **Note**
>
@ -62,67 +62,27 @@ determined by the parameter `minLargeMessageSize`
The default value is 100KiB.
### Using Core API
If the Apache ActiveMQ Artemis Core API is used, the minimal large message size is
specified by `ServerLocator.setMinLargeMessageSize`.
``` java
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(new TransportConfiguration(NettyConnectorFactory.class.getName()))
locator.setMinLargeMessageSize(25 * 1024);
ClientSessionFactory factory = ActiveMQClient.createClientSessionFactory();
```
[Configuring the transport directly from the client side](configuring-transports.md) will provide more information on how to instantiate the session
factory.
### Using JMS
If JNDI is used to instantiate and look up the connection factory, the
minimum large message size is configured in the JNDI context
environment, e.g. `jndi.properties`. Here's a simple example using the
"ConnectionFactory" connection factory which is available in the context
by default:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.myConnectionFactory=tcp://localhost:61616?minLargeMessageSize=250000
If the connection factory is being instantiated directly, the minimum
large message size is specified by
`ActiveMQConnectionFactory.setMinLargeMessageSize`.
[Configuring the transport directly from the client side](configuring-transports.md)
will provide more information on how to instantiate the core session factory
or JMS connection factory.
### Compressed Large Messages
You can choose to send large messages in compressed form using `
compress-large-messages` attributes.
You can choose to send large messages in compressed form using
`compressLargeMessages` URL parameter.
#### `compressLargeMessages`
If you specify the boolean property `compressLargeMessages` on the
`server locator` or `ConnectionFactory` as true, The system will use the
ZIP algorithm to compress the message body as the message is transferred
to the server's side. Notice that there's no special treatment at the
server's side, all the compressing and uncompressing is done at the
client.
If you specify the boolean URL parameter `compressLargeMessages` as true,
The system will use the ZIP algorithm to compress the message body as
the message is transferred to the server's side. Notice that there's no
special treatment at the server's side, all the compressing and uncompressing
is done at the client.
If the compressed size of a large message is below `
minLargeMessageSize`, it is sent to server as regular
messages. This means that the message won't be written into the server's
large-message data directory, thus reducing the disk I/O.
###
If JNDI is used to instantiate and look up the connection factory, large
message compression can be configured in the JNDI context environment,
e.g. `jndi.properties`. Here's a simple example using the
"ConnectionFactory" connection factory which is available in the context
by default:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connectionFactory.myConnectionFactory=tcp://localhost:61616?compressLargeMessages=true
If the compressed size of a large message is below `minLargeMessageSize`,
it is sent to server as regular messages. This means that the message won't
be written into the server's large-message data directory, thus reducing the
disk I/O.
## Streaming large messages
@ -150,7 +110,7 @@ messages or `java.io.OutputStream` for receiving them.
The following table shows a list of methods available at `ClientMessage`
which are also available through JMS by the use of object properties.
<table summary="Server Configuration" border="1">
<table summary="org.hornetq.api.core.client.ClientMessage API" border="1">
<colgroup>
<col/>
<col/>
@ -183,8 +143,6 @@ which are also available through JMS by the use of object properties.
</tbody>
</table>
: org.apache.activemq.artemis.api.core.client.ClientMessage API
To set the output stream when receiving a core message:
``` java
@ -297,5 +255,5 @@ for (int i = 0; i < rm.getBodyLength(); i += 1024)
## Large message example
Please see the [examples](examples.md) chapter for an example which shows how large message is configured
and used with JMS.
Please see the [examples](examples.md) chapter for an example which shows
how large message is configured and used with JMS.

View File

@ -42,24 +42,15 @@ arrive soon, overriding the previous price.
## Using PRE_ACKNOWLEDGE
This can be configured in a client's JNDI context environment, e.g.
`jndi.properties`, like this:
This can be configured by setting the boolean URL parameter `preAcknowledge`
to `true`.
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
connection.ConnectionFactory=tcp://localhost:61616?preAcknowledge=true
Alternatively, to use pre-acknowledgement mode using the JMS API, create
a JMS Session with the `ActiveMQSession.PRE_ACKNOWLEDGE` constant.
Alternatively, when using the JMS API, create a JMS Session with the
`ActiveMQSession.PRE_ACKNOWLEDGE` constant.
// messages will be acknowledge on the server *before* being delivered to the client
Session session = connection.createSession(false, ActiveMQJMSConstants.PRE_ACKNOWLEDGE);
Or you can set pre-acknowledge directly on the
`ActiveMQConnectionFactory` instance using the setter method.
To use pre-acknowledgement mode using the core API you can set it
directly on the `ClientSessionFactory` instance using the setter method.
## Individual Acknowledge
A valid use-case for individual acknowledgement would be when you need
@ -67,7 +58,7 @@ to have your own scheduling and you don't know when your message
processing will be finished. You should prefer having one consumer per
thread worker but this is not possible in some circumstances depending
on how complex is your processing. For that you can use the individual
Acknowledgement.
acknowledgement.
You basically setup Individual ACK by creating a session with the
acknowledge mode with `ActiveMQJMSConstants.INDIVIDUAL_ACKNOWLEDGE`.
@ -83,4 +74,5 @@ the exception the message is individually acked.
## Example
See the [examples](examples.md) chapter for an example which shows how to use pre-acknowledgement mode with JMS.
See the [examples](examples.md) chapter for an example which shows how to
use pre-acknowledgement mode with JMS.

View File

@ -770,20 +770,15 @@ A `*` means 'match-all' in a black or white list.
### Specifying black list and white list via Connection Factories
To specify the white and black lists one can append properties `deserializationBlackList` and `deserializationWhiteList` respectively
to a Connection Factory's url string. For example:
To specify the white and black lists one can use the URL parameters
`deserializationBlackList` and `deserializationWhiteList`. For example,
using JMS:
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("vm://0?deserializationBlackList=org.apache.pkg1,org.some.pkg2");
The above statement creates a factory that has a black list contains two forbidden packages, "org.apache.pkg1" and "org.some.pkg2",
separated by a comma.
You can also set the values via ActiveMQConnectionFactory's API:
public void setDeserializationBlackList(String blackList);
public void setDeserializationWhiteList(String whiteList);
Again the parameters are comma separated list of package/class names.
The above statement creates a factory that has a black list contains two
forbidden packages, "org.apache.pkg1" and "org.some.pkg2", separated by a
comma.
### Specifying black list and white list via system properties

View File

@ -30,14 +30,14 @@ If you are sending messages to a server using a non transacted session,
Apache ActiveMQ Artemis 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:
non-durable messages, and is determined by the following two URL parameters:
- `BlockOnDurableSend`. If this is set to `true` then all calls to
- `blockOnDurableSend`. If this is set to `true` 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 `true`.
- `BlockOnNonDurableSend`. If this is set to `true` then all calls to
- `blockOnNonDurableSend`. If this is set to `true` 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 `false`.
@ -52,15 +52,6 @@ session, only the commit / rollback blocks not every send, or, using
Apache ActiveMQ Artemis's advanced *asynchronous send acknowledgements feature*
described in Asynchronous Send Acknowledgements.
If you are using JMS and JNDI then using the elements
`blockOnDurableSend` and `blockOnNonDurableSend`. If you're using
JMS but not using JNDI then you can set these values directly on the
`ActiveMQConnectionFactory` instance using the appropriate setter
methods.
If you're using core you can set these values directly on the
`ClientSessionFactory` instance using the appropriate setter methods.
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

View File

@ -86,56 +86,19 @@ ActiveMQ-AIO-writer-pool.
## Client-Side Thread Management
On the client side, Apache ActiveMQ Artemis 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.
On the client side, Apache ActiveMQ Artemis maintains a single, "global"
static scheduled thread pool and a single, "global" static general thread
pool for use by all clients using the same classloader in that JVM instance.
The static scheduled thread pool has a maximum size of `5` threads, and
the general purpose thread pool has an unbounded maximum size.
The static scheduled thread pool has a maximum size of `5` threads by
default. This can be changed using the `scheduledThreadPoolMaxSize` URI
parameter.
The general purpose thread pool has an unbounded maximum size. This is
changed using the `threadPoolMaxSize` URL parameter.
If required Apache ActiveMQ Artemis can also be configured so that each
`ClientSessionFactory` instance does not use these static pools but
`ClientSessionFactory` instance does not use these "global" static pools but
instead maintains its own scheduled and general purpose pool. Any
sessions created from that `ClientSessionFactory` will use those pools
instead.
To configure a `ClientSessionFactory` instance to use its own pools,
simply use the appropriate setter methods immediately after creation,
for example:
``` java
ServerLocator locator = ActiveMQClient.createServerLocatorWithoutHA(...)
ClientSessionFactory myFactory = locator.createClientSessionFactory();
myFactory.setUseGlobalPools(false);
myFactory.setScheduledThreadPoolMaxSize(10);
myFactory.setThreadPoolMaxSize(-1);
```
If you're using the JMS API, you can set the same parameters on the
ClientSessionFactory and use it to create the `ConnectionFactory`
instance, for example:
``` java
ConnectionFactory myConnectionFactory = ActiveMQJMSClient.createConnectionFactory(myFactory);
```
If you're using JNDI to instantiate `ActiveMQConnectionFactory`
instances, you can also set these parameters in the JNDI context
environment, e.g. `jndi.properties`. Here's a simple example using the
"ConnectionFactory" connection factory which is available in the context
by default:
java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
java.naming.provider.url=tcp://localhost:61616
connection.ConnectionFactory.useGlobalPools=false
connection.ConnectionFactory.scheduledThreadPoolMaxSize=10
connection.ConnectionFactory.threadPoolMaxSize=-1
instead. This is configured using the `useGlobalPools` boolean URL parameter.