7 Replies Latest reply on Jul 9, 2013 4:55 AM by erasmo2 marciano2

    fail-over using HornetQJMSClient

    Jeff Bride Novice

      Hi.

         I"m making use of the HornetQJMSClient in a standalone JVM similar to how it's being used in SymmetricClusterExample.java .

          My HA configured brokers are configured in domain mode in EAP6.0.1  (all clients and brokers used hornetq libraries from EAP6.0.1 --> hornetq--2.2.23.Final-redhat-1 )

       

        When using the HornetQJMSClient, fail-over of the client connection bombs when the primary broker is shutdown and its backup comes on line:

       

      javax.jms.IllegalStateException: Consumer is closed
           [java]           at org.hornetq.core.client.impl.ClientConsumerImpl.checkClosed(ClientConsumerImpl.java:961)
           [java]           at org.hornetq.core.client.impl.ClientConsumerImpl.receive(ClientConsumerImpl.java:186)
           [java]           at org.hornetq.core.client.impl.ClientConsumerImpl.receive(ClientConsumerImpl.java:391)
           [java]           at org.hornetq.jms.client.HornetQMessageConsumer.getMessage(HornetQMessageConsumer.java:225)
           [java]           at org.hornetq.jms.client.HornetQMessageConsumer.receive(HornetQMessageConsumer.java:134)
      
      

       

       

         As a comparison, with the exact same broker environment, when switching to a client that uses jndi to lookup the ConnectionFactory ..... fail-over behavior of the client occurs flawlessly as per Hornetq documentation.

       

        Any hints as to where i may have misconfigured something ???

       

        I've bumped up client-side logging and conducted tests for both a UDP discovery based client and a JNDI based client.

         The results are attached.

       

        What seems interesting is the following message on line 304 of hornetq.udp log :

       

      calling cleanup on ClientSessionImpl [name=b3134f40-a3c8-11e2-83ba-3183c7406c01, username=null, closed=false, factory = ClientSessionFactoryImpl 
      [serverLocator=ServerLocatorImpl [initialConnectors=[org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5645&host=192-168-122-1], 
      discoveryGroupConfiguration=DiscoveryGroupConfiguration [discoveryInitialWaitTimeout=10000, groupAddress=231.7.7.7, groupPort=9876, localBindAddress=null, name=b0e6842d-a3c8-11e2-83ba-3183c7406c01, 
      refreshTimeout=10000]], connectorConfig=org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5645&host=192-168-122-1, backupConfig=org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5545&host=192-168-122-1], 
      metaData=(jms-session=,)]@98dbc96
      

       

      ...and then the previous exception is thrown.  In comparison,  on line 304 of hornetq.jndi, the following message is logged :

       

      Trying reconnection attempt 0/-1
      

       

      ..... and then the connection created from JNDI fails-over to the backup broker just fine.

       

       

      thanks!  jeff

        • 1. Re: fail-over using HornetQJMSClient
          Justin Bertram Master

          Can you copy/paste or attach the code where your using HornetQJMSClient to instantiate the connection factory?  Also, can you copy/paste or attach your hornetq-jms.xml?

          • 2. Re: fail-over using HornetQJMSClient
            Jeff Bride Novice

            Hi Justin.

             

            thanks for taking a look at this.

             

            code snippet as follows :

             

                       ConnectionFactory cFactory = null;
                        if(useDiscover) {
                            DiscoveryGroupConfiguration groupConfiguration = new DiscoveryGroupConfiguration(discoverHost, discoverPort);
                            cFactory = (ConnectionFactory)HornetQJMSClient.createConnectionFactoryWithHA(groupConfiguration, JMSFactoryType.QUEUE_CF);
                            gwDObj = HornetQJMSClient.createQueue(gwDObjName);
                        }else {
                            Properties env = new Properties();
                            env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
                            env.put(Context.PROVIDER_URL, "remote://"+labHost+":"+labPort);
                            Context jndiContext = new InitialContext(env);
                            cFactory = (ConnectionFactory)jndiContext.lookup(cFactoryName);
                            gwDObj = (Destination)jndiContext.lookup(gwDObjPath);
                            jndiContext.close();
                        }
            
                        //session objects have all of the load-balancing and fail-over magic .... only need one Connection object for entire JVM
                        connectionObj = cFactory.createConnection();
            
            

             

             

            in regards to my configs, our EAP6.0.1 domain mode environments are provisioned via CLI.   So i've attached the domain.xml .  relevant profiles as follows :

             

            full         :   messaging subsystem starts on line 725.   used as profile for an  MDB  application

            full-ha    :    messaging subsystem starts on line 903.   used as profile for primary hornetq broker

            full-ha-1 :    messaging subsystem starts on line 1135.  used as profile for backup hornetq broker

            • 3. Re: fail-over using HornetQJMSClient
              Justin Bertram Master

              I'm a little confused.  You talked about using HA and fail-over, but none of the profiles in the domain.xml you attached are configured for HA functionality.  Can you clarify this?

              • 4. Re: fail-over using HornetQJMSClient
                Jeff Bride Novice

                F#*$K ....    really sorry about that.  I previously posted the domain.xml used in my project prior to the CLI commands being executed.  no idea what i was thinking.

                 

                anyway, i've updated the previous post with the actual domain.xml used in the runtime along with the line #s where the messaging subsystems begin.

                 

                thanks Justin. 

                • 5. Re: fail-over using HornetQJMSClient
                  Justin Bertram Master

                  So the connection factory you are presumably using from JNDI is this:

                   

                                          <connection-factory name="RemoteConnectionFactory">

                                              <connectors>

                                                  <connector-ref connector-name="netty"/>

                                              </connectors>

                                              <entries>

                                                  <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>

                                              </entries>

                                              <ha>true</ha>

                                              <reconnect-attempts>-1</reconnect-attempts>

                                          </connection-factory>

                   

                  Notice that is has <reconnect-attempts>-1</reconnect-attempts>.  However, the code you are using with HornetQJMSClient is not setting this property, and I believe that is why it is not attempting to reconnect.  You should call org.hornetq.jms.client.HornetQConnectionFactory.setReconnectAttempts(int) passing -1.

                  • 6. Re: fail-over using HornetQJMSClient
                    Jeff Bride Novice

                    excellent.   that was exactly the problem.  Thanks again for your help Justin.

                     

                    jeff

                    • 7. Re: fail-over using HornetQJMSClient
                      erasmo2 marciano2 Master

                      Hi

                       

                      I should do a similar code

                       

                         Hi

                       

                          this is my code

                       

                         

                                      // Set up the context for the JNDI lookup

                                    final Properties env = new Properties();

                                    env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);

                                   env.put(Context.PROVIDER_URL, System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));

                                   env.put(Context.SECURITY_PRINCIPAL, System.getProperty("username", DEFAULT_USERNAME));

                                   env.put(Context.SECURITY_CREDENTIALS, System.getProperty("password", DEFAULT_PASSWORD));

                                   context = new InitialContext(env);

                                  //SessionFactory factory = HornetQClient.createClientSessionFactory(new DiscoveryGroupConfiguration(groupAddress, groupPort));

                       

                                  // Perform the JNDI lookups

                                  String connectionFactoryString = System.getProperty("connection.factory", DEFAULT_CONNECTION_FACTORY);

                                  log.info("Attempting to acquire connection factory \"" + connectionFactoryString + "\"");

                                  connectionFactory = (ConnectionFactory) context.lookup(connectionFactoryString);

                                  log.info("Found connection factory \"" + connectionFactoryString + "\" in JNDI");

                       

                                  String destinationString = System.getProperty("destination", DEFAULT_DESTINATION);

                                  log.info("Attempting to acquire destination \"" + destinationString + "\"");

                                  destination = (Destination) context.lookup(destinationString);

                                  log.info("Found destination \"" + destinationString + "\" in JNDI");

                       

                                  // Create the JMS connection, session, producer, and consumer

                                  connection = connectionFactory.createConnection(System.getProperty("username", DEFAULT_USERNAME), System.getProperty("password", DEFAULT_PASSWORD));

                       

                                  session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

                                  producer = session.createProducer(destination);

                                  consumer = session.createConsumer(destination);

                                  connection.start();

                       

                                  int count = Integer.parseInt(System.getProperty("message.count", DEFAULT_MESSAGE_COUNT));

                                  String content = System.getProperty("message.content", DEFAULT_MESSAGE);

                       

                                  log.info("Sending " + count + " messages with content: " + content);

                       

                       

                       

                             

                                 How I can add this code in my code

                       

                       

                                  DiscoveryGroupConfiguration groupConfiguration = new DiscoveryGroupConfiguration(groupAddress, groupPort);

                                  connectionFactory = (ConnectionFactory)HornetQJMSClient.createConnectionFactoryWithHA(groupConfiguration, JMSFactoryType.QUEUE_CF);

                       

                             

                              I have to make a ClientJms that is connect at the DiscoveryGroup

                       

                      Thanks