Sunday, August 28, 2016

JBoss EAP 6.x with HornetQ Backup Cluster (Broadcast/Loopback) using JGroups

Hi everyone...
I am back!

Thanks a lot to stay here for reading my post. Sorry about my english, but i am studying hard to improve it :-)!

Today, i would like to present a configuration over HornetQ (jboss jms server), settting up a backup server into a HA Cluster.

HornetQ is a good choice to delivery messages using JBoss EAP 6.x, and you can define properties to work with a lot of nodes where the messages will be sent and received in miliseconds.

So, how can i create a HornetQ Live Server, Backup HornetQ Server and setting up a cluster configuration to provide performance for any tasks in Java EE Applications?

It is not a simple question, because a lot of issues and situations must be specified to ensure a good performance solution. But work with JMS as a important part of JEE that solves problems for working in asynchronous process.

So, let's see how we could create a good configuration for working in cluster with HornetQ Messages.

JGroups Properties

For a group server you have to define 3 essencials properties...

<property name="jboss.default.multicast.address"    value="231.0.0.3"/>
<property name="jboss.messaging.group.address"    value="231.3.3.3"/>
<property name="hornetq-discovery-group-name"     value="dg-hornetq-a"/>

These properties will be used for all servers inside the group, and messages will be received by the servers in a cluster environment.

For instance:

<server-group name="grp-b" profile="prf-b">
            <jvm name="default">
                <heap size="3096m" max-size="3096m"/>
                <jvm-options>
                    <option value="-XX:+CMSClassUnloadingEnabled"/>
                    <option value="-XX:+UseConcMarkSweepGC"/>
                    <option value="-XX:+UseCompressedOops"/>
                    <option value="-XX:+AggressiveOpts"/>
                    <option value="-XX:+ScavengeBeforeFullGC"/>
                    <option value="-XX:+HeapDumpOnOutOfMemoryError"/>
                    <option value="-noverify"/>
                    <option value="-Xss1024k"/>
                    <option value="-XX:StackShadowPages=10"/>
                    <option value="-XX:+UseFastAccessorMethods"/>
                </jvm-options>
            </jvm>
            <socket-binding-group ref="full-ha-sockets"/>
            <system-properties>
                <property name="jboss.default.multicast.address"   value="231.0.0.3"/>
                <property name="jboss.messaging.group.address"   value="231.3.3.3"/>
                <property name="hornetq-discovery-group-name"     value="dg-hornetq-a"/>
                <property name="jboss.tx.node.id"                             value="node-a"/>
            </system-properties>
        </server-group>



HornetQ Journal

We have to define the path where HornetQ will save informations for handling messages...

    <system-properties>
        <property name="java.net.preferIPv4Stack" value="true"/>
        <property name="org.apache.tomcat.util.http.Parameters.MAX_COUNT" value="5000"/>
        <property name="user.country" value="BR"/>
        <property name="user.language" value="pt"/>
    </system-properties>

    <paths>
        <path name="hornetq_storage_a" path="/opt/hornetq/a-queue"/>
        <path name="hornetq_storage_b" path="/opt/hornetq/b-queue"/>

        <!-- hornetq backups -->
        <path name="hornetq_storage_a_bkp"  path="/opt/hornetq_bkp/a-queue"/>
        <path name="hornetq_storage_b_bkp"  path="/opt/hornetq_bkp/b-queue"/>

    </paths>


These paths must be used by lived servers and HornetQ backup servers.
But if you prefer, according to your environment, a shared path must be defined for both into the same profile.

 <subsystem xmlns="urn:jboss:domain:messaging:1.4">
                <hornetq-server>
                    <persistence-enabled>true</persistence-enabled>
                    <security-enabled>false</security-enabled>
                    <!--transaction-timeout>180000</transaction-timeout-->
                <backup>false</backup>
 
                   <allow-failback>true</allow-failback>
                    <failover-on-shutdown>true</failover-on-shutdown>
                <shared-store>true</shared-store>
                    <journal-type>ASYNCIO</journal-type>
                    <!--journal-buffer-timeout>2000</journal-buffer-timeout-->
                    <journal-sync-transactional>true</journal-sync-transactional>
                    <journal-sync-non-transactional>true</journal-sync-non-transactional>
                    <log-journal-write-rate>false</log-journal-write-rate>
                    <journal-min-files>20</journal-min-files>
                    <!--journal-max-io>65000</journal-max-io-->
                    <run-sync-speed-test>false</run-sync-speed-test>
                <check-for-live-server>true</check-for-live-server>
                <backup-group-name>${live.group.a:a-live}</backup-group-name>


                <paging-directory     path="paging"     relative-to="hornetq_storage_a"/>
                <bindings-directory   path="bindings"  relative-to="hornetq_storage_a"/>
                <journal-directory path="journal"    relative-to="hornetq_storage_a"/>
                <large-messages-directory path="largemessages" relative-to="hornetq_storage_a"/>



Broadcast and Cluster Configuration

                    <broadcast-groups>
                        <broadcast-group name="bg-a">
                            <socket-binding>messaging-group</socket-binding>
                            <broadcast-period>2000</broadcast-period>
                            <connector-ref>
                                netty
                            </connector-ref>
                        </broadcast-group>
                    </broadcast-groups>

                    <discovery-groups>
                        <discovery-group name="dg-hornetq-a">
                            <socket-binding>messaging-group</socket-binding>
                            <refresh-timeout>2000</refresh-timeout>
                        </discovery-group>
                    </discovery-groups>

                    <cluster-connections>
                        <cluster-connection name="a-cluster">
                            <address>jms</address>
                            <connector-ref>netty</connector-ref>
                      <discovery-group-ref discovery-group-name="dg-hornetq-a"/>                        </cluster-connection>
                    </cluster-connections>

                    <security-settings>
                        <security-setting match="#">
                            <permission type="send" roles="guest"/>
                            <permission type="consume" roles="guest"/>
                            <permission type="createNonDurableQueue" roles="guest"/>
                            <permission type="deleteNonDurableQueue" roles="guest"/>
                        </security-setting>
                    </security-settings>

                    <address-settings>
                        <address-setting match="#">
                            <dead-letter-address>jms.queue.DLQ</dead-letter-address>
                            <expiry-address>jms.queue.ExpiryQueue</expiry-address>
                            <redelivery-delay>0</redelivery-delay>
                            <max-size-bytes>10485760</max-size-bytes>
                            <page-size-bytes>2097152</page-size-bytes>
                      <address-full-policy>BLOCK</address-full-policy>                            <message-counter-history-day-limit>10</message-counter-history-day-limit>
                        </address-setting>
                    </address-settings>

                    <jms-connection-factories>
                        <connection-factory name="InVmConnectionFactory">
                              <connectors>
                                    <connector-ref connector-name="in-vm"/>
                              </connectors>
                              <entries>
                                    <entry name="java:/ConnectionFactory"/>
                              </entries>
   
                              <producer-window-size>-1</producer-window-size>
                              <consumer-window-size>0</consumer-window-size>
                              <consumer-max-rate>-1</consumer-max-rate>
                              <producer-max-rate>-1</producer-max-rate>
                        </connection-factory>
       
                        <connection-factory name="RemoteConnectionFactory">
                            <discovery-group-ref discovery-group-name="dg-hornetq-a"/>                                 
                                  <entries>
                                        <entry name="java:/RemoteJmsXA"/>
                                        <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                                  </entries>
                                  <ha>true</ha>
                           <block-on-acknowledge>true</block-on-acknowledge>                                  <retry-interval>1000</retry-interval>
                                  <retry-interval-multiplier>1.0</retry-interval-multiplier>
                                  <reconnect-attempts>-1</reconnect-attempts>
                                  <producer-window-size>-1</producer-window-size>
                           <consumer-window-size>0</consumer-window-size>                                  <consumer-max-rate>-1</consumer-max-rate>
                                  <producer-max-rate>-1</producer-max-rate>
                        </connection-factory>
       
                        <pooled-connection-factory name="hornetq-ra">
                                  <transaction mode="xa"/>
                                  <connectors>
                                        <connector-ref connector-name="in-vm"/>
                                  </connectors>
                                  <entries>
                                        <entry name="java:/JmsXA"/>
                                  </entries>
                                  <ha>true</ha>
                           <block-on-acknowledge>true</block-on-acknowledge>                                  <retry-interval>1000</retry-interval>
                                  <retry-interval-multiplier>1.0</retry-interval-multiplier>
                                  <reconnect-attempts>-1</reconnect-attempts>
                                 
                                  <producer-window-size>-1</producer-window-size>
                           <consumer-window-size>0</consumer-window-size>                                  <consumer-max-rate>-1</consumer-max-rate>
                                  <producer-max-rate>-1</producer-max-rate>
                        </pooled-connection-factory>
                    </jms-connection-factories>


HornetQ Backup Server

                <hornetq-server name="a-bkp">
                    <persistence-enabled>true</persistence-enabled>
                    <security-enabled>false</security-enabled>
                    <!--transaction-timeout>180000</transaction-timeout-->
                <backup>true</backup>
                    <allow-failback>true</allow-failback>
                    <failover-on-shutdown>true</failover-on-shutdown>
                    <shared-store>true</shared-store>
                    <journal-type>ASYNCIO</journal-type>
                    <!--journal-buffer-timeout>2000</journal-buffer-timeout-->
                    <journal-sync-transactional>true</journal-sync-transactional>
                    <journal-sync-non-transactional>true</journal-sync-non-transactional>
                    <log-journal-write-rate>false</log-journal-write-rate>
                    <journal-min-files>20</journal-min-files>
                    <!--journal-max-io>65000</journal-max-io-->
                    <run-sync-speed-test>false</run-sync-speed-test>
                    <check-for-live-server>true</check-for-live-server>
                    <backup-group-name>${backup.group.a:a-bkp}</backup-group-name>

               <paging-directory    path="paging"   relative-to="hornetq_storage_a_bkp"/>
               <bindings-directory path="bindings" relative-to="hornetq_storage_a_bkp"/>
               <journal-directory   path="journal"   relative-to="hornetq_storage_a_bkp"/>
               <large-messages-directory path="largemessages" relative-to="hornetq_storage_a_bkp"/>


               ... (the same lines as you put on lived server)


That's it!
Your HornetQ Cluster was created...So, you can have 2 or more hosts using <server-group name="grp-b" profile="prf-b">.

The complete file was saved into my github profile. Please, see it at:

 https://github.com/alvesfred/samples-jboss/blob/master/deploy/domain-block-hornetq-backup.xml

In this file, i created 3 profiles and 3 groups.

If you would like to know if the packages over the network have been sending, just execute the linux command below for each server/host:

 # tcpdump -vv | grep 231.3.3.3
(all udp packages will be showed for each host servers)


If you have any doubt, please let me know.

Thanks a lot and regards



No comments:

Post a Comment