INT-3325 Add Redis Channel Message Group Store

JIRA: https://jira.spring.io/browse/INT-3325
JIRA: https://jira.spring.io/browse/INT-1870

Optimized MGS for QueueChannel - uses a LIST for
each channel and LPUSH, RPOP.

* Also fix MutableMessage to be Serializable

INT-1870 Priority Redis Channel Message Store

Supports priorities 0-9 (+ no priority).

Priorities out of that range are treated as no priority.

Polishing - Add Marker Interfaces

* Emit a `WARN` log if a channel is used with a regular MessageGroupStore
* Allow message-store on namespace when defining a priority channel

INT-3325 Polishing; PR Comments

Fix some typos in JavaDocs and Docs
This commit is contained in:
Gary Russell
2014-03-18 12:33:41 +02:00
committed by Artem Bilan
parent a9faa5836f
commit a8c8a4fed5
20 changed files with 846 additions and 70 deletions

View File

@@ -577,7 +577,7 @@ payload to an Integer.
the <emphasis>org.springframework.integration.jdbc</emphasis> package of that module (spring-integration-jdbc).
<important>
One important feature is that with any transactional persistent store (e.g., JdbcMessageStore), as long as the poller has a transaction configured,
One important feature is that with any transactional persistent store (e.g., JdbcChannelMessageStore), as long as the poller has a transaction configured,
a Message removed from the store will only be permanently removed if the transaction completes
successfully, otherwise the transaction will roll back and the Message will not be lost.
</important>
@@ -585,6 +585,13 @@ payload to an Integer.
related to "NoSQL" data stores provide the underlying support. Of course, you can always provide your own implementation
of the MessageGroupStore interface if you cannot find one that meets your particular needs.
</para>
<para>
Since <emphasis>version 4.0</emphasis>, it is recommended that <classname>QueueChannel</classname>s are
configured to use a <interfacename>ChannelMessageStore</interfacename> if possible. These are generally optimized
for this use, when compared with a general message store. If the <interfacename>ChannelMessageStore</interfacename>
is a <interfacename>ChannelPriorityMessageStore</interfacename> the messages will be received in
FIFO within priority order. The notion of priority is determined by the message store implementation.
</para>
</section>
<section id="channel-configuration-pubsubchannel">
@@ -652,6 +659,13 @@ payload to an Integer.
</int:channel>
]]></programlisting>
</para>
<para>
Since <emphasis>version 4.0</emphasis>, the <code>priority-channel</code> child element supports
the <code>message-store</code> option (<code>comparator</code> is not allowed in that case).
The message store must be a <interfacename>ChannelPriorityMessageStore</interfacename> and, in this
case, the namespace parser will declare a <classname>QueueChannel</classname> instead of
a <classname>PriorityChannel</classname>. See <xref linkend="channel-configuration-queuechannel"/>.
</para>
</section>
<section id="channel-configuration-rendezvouschannel">
<title>RendezvousChannel Configuration</title>

View File

@@ -384,16 +384,13 @@ rt.setConnectionFactory(redisConnectionFactory);]]></programlisting>
<para>
As described in EIP, a <ulink url="http://www.eaipatterns.com/MessageStore.html">Message Store</ulink> allows you to persist Messages.
This can be very useful when dealing with components that have a capability to buffer messages
(<emphasis>QueueChannel, Aggregator, Resequencer</emphasis>, etc.) if reliability is a concern.
(<emphasis>Aggregator, Resequencer</emphasis>, etc.) if reliability is a concern.
In Spring Integration, the MessageStore strategy also provides the foundation for the
<ulink url="http://www.eaipatterns.com/StoreInLibrary.html">ClaimCheck</ulink> pattern, which is described in EIP as well.
</para>
<para>
Spring Integration's Redis module provides the <classname>RedisMessageStore</classname> which is an implementation of both the
the <classname>MessageStore</classname> strategy (mainly used by the <emphasis>QueueChannel</emphasis> and <emphasis>ClaimCheck</emphasis>
patterns) and the <classname>MessageGroupStore</classname> strategy (mainly used by the <emphasis>Aggregator</emphasis> and
<emphasis>Resequencer</emphasis> patterns).
Spring Integration's Redis module provides the <classname>RedisMessageStore</classname>.
</para>
<para>
@@ -401,17 +398,13 @@ rt.setConnectionFactory(redisConnectionFactory);]]></programlisting>
<constructor-arg ref="redisConnectionFactory"/>
</bean>
<int:channel id="somePersistentQueueChannel">
<int:queue message-store="redisMessageStore"/>
<int:channel>
<int:aggregator input-channel="inputChannel" output-channel="outputChannel"
message-store="redisMessageStore"/>]]></programlisting>
</para>
<para>
Above is a sample <classname>RedisMessageStore</classname> configuration that shows its usage by a <emphasis>QueueChannel</emphasis>
and an <emphasis>Aggregator</emphasis>. As you can see it is a simple bean configuration, and it expects a
Above is a sample <classname>RedisMessageStore</classname> configuration that shows its usage by
an <emphasis>Aggregator</emphasis>. As you can see it is a simple bean configuration, and it expects a
<classname>RedisConnectionFactory</classname> as a constructor argument.
</para>
@@ -419,6 +412,45 @@ rt.setConnectionFactory(redisConnectionFactory);]]></programlisting>
However if you want to use a different serialization technique (e.g., JSON), you can provide your own serializer via
the <code>valueSerializer</code> property of the <classname>RedisMessageStore</classname>.
</para>
<section id="redis-cms">
<title>Redis Channel Message Stores</title>
<para>
The <classname>RedisMessageStore</classname> above maintains each group as a value under a single key
(the group id). While this can be used to back a <classname>QueueChannel</classname> for persistence,
a specialized <classname>RedisChannelMessageStore</classname> is provided for that purpose (since
<emphasis>version 4.0</emphasis>). This store uses a <code>LIST</code> for each channel and
<code>LPUSH</code> when sending and <code>RPOP</code> when receiving messages. This store also
uses JDK serialization by default, but the value serializer can be modified as described above.
</para>
<para>
It is recommended that this store is used for backing channels, instead of the general
<classname>RedisMessageStore</classname>.
</para>
<programlisting language="xml"><![CDATA[<bean id="redisMessageStore" class="o.s.i.redis.store.RedisChannelMessageStore">
<constructor-arg ref="redisConnectionFactory"/>
</bean>
<int:channel id="somePersistentQueueChannel">
<int:queue message-store="redisMessageStore"/>
<int:channel>]]></programlisting>
<para>
The keys are used to store the data have the form <code>&lt;storeBeanName&gt;:&lt;channelId&gt;</code>
(in the above example, <code>redisMessageStore:somePersistentQueueChannel</code>).
</para>
<para>
In addition, a subclass <classname>RedisChannelPriorityMessageStore</classname> is also provided.
When this is used with a <classname>QueueChannel</classname>, the messages are received in
(FIFO within) priority order. It uses the standard <classname
>IntegrationMessageHeaderAccessor.PRIORITY</classname> header and supports priority values
<code>0 - 9</code>; messages with other priorities (and messages with no priority) are retrieved
in FIFO order after any messages with priority.
</para>
<important>
These stores implement only <interfacename>BasicMessageGroupStore</interfacename> and
do not implement <interfacename>MessageGroupStore</interfacename>; they
can only be used for situations such as backing a <classname>QueueChannel</classname>.
</important>
</section>
</section>
<section id="redis-metadata-store">
<title>Redis Metadata Store</title>

View File

@@ -65,6 +65,20 @@
>Spring Boot - AutoConfigure</ulink>.
</para>
</section>
<section id="4.0-redis-cms">
<title>Redis Channel Message Stores</title>
<para>
A new Redis <interfacename>MessageGroupStore</interfacename>, that is optimized for
use when backing a <classname>QueueChannel</classname> for persistence, is now
provided.
For more information, see <xref linkend="redis-cms"/>.
</para>
<para>
A new Redis <interfacename>ChannelPriorityMessageStore</interfacename> is now
provided. This can be used to retrieve messages by priority.
For more information, see <xref linkend="redis-cms"/>.
</para>
</section>
</section>
<section id="4.0-general">