Installing and using an external RabbitMQ as a full-featured message broker enables new technological opportunities and the design of a production-like infrastructure.
In this recipe, we will install RabbitMQ as a standalone server and configure it so it supports STOMP messages.
We will also update our WebSocket Spring configuration to rely on this full-featured message broker, instead of the internal simple message broker.
v8.2.x
branch this time.<home-directory>/workspace
).cloudstreetmarket-shared
and cloudstreetmarket-websocket
must show up in the project hierarchy./app
directory, the cloudstreetmarket.properties
file has been updated. Reflect the changes in your file located in <home-directory>/app/cloudstreetmarket.properties
.Maven clean
and Maven install
commands on zipcloud-parent
and then on cloudstreetmarket-parent
, followed by a Maven | Update Project on all the modules.If you are using Windows OS, please note that it is a prerequisite to download and install Erlang (http://www.erlang.org/download.html).
http://localhost:15672
(like in the following screenshot).rabbitmq_server-x.x.xsbin
directory, by executing the command line:rabbitmq-plugins enable rabbitmq_stomp
<dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> <version>1.4.0.RELEASE</version> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> <version>2.0.5.RELEASE</version> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-net</artifactId> <version>2.0.5.RELEASE</version> </dependency> <dependency> <groupId>io.projectreactor.spring</groupId> <artifactId>reactor-spring-context</artifactId> <version>2.0.5.RELEASE</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.0.31.Final</version> </dependency>
dispatcher-servlet.xml
of the cloudstreetmarket-api
module, the following beans have been added making use of the rabbit
namespace:<beans xmlns="http://www.sfw.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ... xmlns:rabbit="http://www.sfw.org/schema/rabbit" xsi:schemaLocation="http://www.sfw.org/schema/beans ... http://www.sfw.org/schema/rabbit http://www.sfw.org/schema/rabbit/spring-rabbit-1.5.xsd"> ... <rabbit:connection-factory id="connectionFactory" host="localhost" username="guest" password="guest" /> <rabbit:admin connection-factory="connectionFactory" /> <rabbit:template id="messagingTemplate" connection-factory="connectionFactory"/> </beans>
csmcore-config.xml
file (in cloudstreetmarket-core
), the following beans have been added with the task
namespace:<beans xmlns="http://www.sfw.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ... xmlns:task=http://www.sfw.org/schema/task http://www.sfw.org/schema/task/spring-task-4.0.xsd"> ... <task:annotation-driven scheduler="wsScheduler"/> <task:scheduler id="wsScheduler" pool-size="1000"/> <task:executor id="taskExecutor"/> </beans>
AnnotationConfig
bean (the main configuration bean for cloudstreetmarket-api
) has been added the two annotations:@EnableRabbit @EnableAsync public class AnnotationConfig { ... }
WebSocketConfig
bean has been updated as well; especially the broker registration. We now make use of a StompBrokerRelay
instead of a simples broker:@Configuration @ComponentScan("edu.zipcloud.cloudstreetmarket.api") @EnableWebSocketMessageBroker @EnableScheduling @EnableAsync public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { ... @Override public void configureMessageBroker(final MessageBrokerRegistry registry) { registry.setApplicationDestinationPrefixes( WEBAPP_PREFIX_PATH); registry.enableStompBrokerRelay(TOPIC_ROOT_PATH); } }
That's it! Everything is set to use RabbitMQ as external broker for our system. However, please note that if you try to start the server right now, the code will be expecting MySQL to be installed as well as the Redis Server. These two third-party systems are going to be detailed over the two next recipes.
In comparison to a simple message broker, using a full-featured message broker such as RabbitMQ provides interesting benefits, which we will discuss now.
A RabbitMQ broker is made of one or more Erlang nodes. Each of these nodes represent an instance of RabbitMQ in itself and can be started independently. Nodes can be linked with each other using the command line tool rabbitmqctl
. For example, rabbitmqctl join_cluster [email protected]
would actually connect one node to an existing cluster network. RabbitMQ nodes use cookies to communicate with one another. To be connected on the same cluster, two nodes must have the same cookie.
In the previous recipe, we talked about the flow that a message passes through in the Spring WebSocket engine. As shown with the following image, this flow is not affected at all when switching to an external message broker relay.
Only the RabbitMQ external message broker shows up as an extra piece.BrokerMessageHandler
(StompBrokerRelayMessageHandler
) acts only as a proxy targeting a RabbitMQ node behind the scenes. Only one TCP connection is maintained between the StompBrokerRelay
and its message broker. The StompBrokerRelay
maintains the connection by sending heartbeat messages.