2012-11-20 84 views
4

我在同一臺計算機上有兩個HornetQ(2.2.14)獨立服務器(實時備份服務器)考慮這種情況:動態更改JNDI提供程序

  1. Live服務器崩潰,備份服務器現在住。
  2. 客戶端A(不知道Live服務器崩潰)想要連接到Live服務器(它應該查找其連接工廠Live服務器JNDI提供)。
  3. 客戶端A無法找到活動服務器JNDI提供程序,因此它應該連接到備份服務器(它應該查找其連接工廠備份服務器JNDI提供程序)。

我如何更改客戶端A JNDI提供商(改變URL)動態? JNDI故障轉移有任何方法嗎?

我有一個春天的綜合應用,這是我的applicationContext.xml:

<!-- Default JndiTemplate --> 
     <bean id="defaultJndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
      <property name="environment"> 
       <props> 
        <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop> 
        <prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop> 
        <prop key="java.naming.provider.url">jnp://localhost:1099</prop> 
       </props> 
      </property> 
     </bean> 

<!-- Backup JndiTemplate --> 
     <bean id="backupJndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
      <property name="environment"> 
       <props> 
        <prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop> 
        <prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop> 
        <prop key="java.naming.provider.url">jnp://localhost:2099</prop> 
       </props> 
      </property> 
     </bean> 

    <!-- Destinations --> 
    <bean id="defaultDestination" class="org.springframework.jndi.JndiObjectFactoryBean"> 
     <property name="jndiTemplate" ref="defaultJndiTemplate" /> 
     <property name="jndiName" value="/queue/exampleQueue" /> 
    </bean> 

    <!-- ConnectionFactories --> 
    <bean id="defaultConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> 
     <property name="jndiTemplate" ref="defaultJndiTemplate" /> 
     <property name="jndiName" value="/ConnectionFactory" /> 
    </bean> 

    <!-- JMS Template --> 
    <bean name="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> 
     <property name="connectionFactory" ref="defaultConnectionFactory" /> 
     <property name="sessionTransacted" value="true" /> 
    </bean> 

    <!-- Message Producer --> 
    <bean name="messageSender" class="messaging.producer.MessageSender"> 
     <property name="jmsTemplate" ref="jmsTemplate" /> 
     <property name="destination" ref="defaultDestination" /> 
    </bean> 

更新: 我能處理這樣查找從當前實際serrver連接工廠在我的應用程序: 對於每封郵件,

  1. 檢查可用的JNDI提供商(從目前的現場服務器)
  2. 查找連接工廠
  3. 發送消息

像這樣的東西(它從我的messageSender,和類的):

//init initialContexts for live and backup servers 
    public init() throws NamingException, CommunicationException 
     { 
      Hashtable<String, String> environment = new Hashtable<String, String>(); 
      environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); 
      environment.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); 
      environment.put(Context.PROVIDER_URL, "jnp://localhost:1099"); 
      initialContext_live = new InitialContext(environment); 

      environment = new Hashtable<String, String>(); 
      environment.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory"); 
      environment.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces"); 
      environment.put(Context.PROVIDER_URL, "jnp://localhost:2099"); 
      initialContext_backup = new InitialContext(environment); 

      jmsTemplate = new JmsTemplate(); 

     } 
     //Sending message to toQueue 
     public void send(final AbstractMessage message, String toQueue) throws NamingException 
     { 
      Destination destination; 
      try 
      { 
       connectionFactory = (ConnectionFactory)initialContext_live.lookup("/ConnectionFactory"); 
       jmsTemplate.setConnectionFactory(connectionFactory); 
       destination = (Destination) initialContext_live.lookup(toQueue); 
       System.out.print("[to-live]-"); 
      } 
      catch(Exception e) //live server is down 
      { 
       connectionFactory = (ConnectionFactory)initialContext_backup.lookup("/ConnectionFactory"); 
       jmsTemplate.setConnectionFactory(connectionFactory); 
       destination = (Destination) initialContext_backup.lookup(toQueue); 
       System.out.print("[to-backup]-"); 
      } 
      jmsTemplate.send(destination, new MessageCreator() 
      { 
       @Override 
       public Message createMessage(Session session) throws JMSException 
       { 
        ObjectMessage objMessage = session.createObjectMessage(message); 
        return objMessage; 
       } 
      }); 
      System.out.println("[MessageSender] Message sent."); 
     } 

但它耗時(約二分之一的消息秒)!

回答

0

我發現這裏有兩件事情

首先您設置一個全局標誌並提出,如果其他條件

flag=true; 
if(flag){ 
try 
     { 
      connectionFactory =  (ConnectionFactory)initialContext_live.lookup("/ConnectionFactory"); 
      jmsTemplate.setConnectionFactory(connectionFactory); 
      destination = (Destination) initialContext_live.lookup(toQueue); 
      System.out.print("[to-live]-"); 
     } 
}else{ 
connectionFactory = (ConnectionFactory)initialContext_backup.lookup("/ConnectionFactory"); 
      jmsTemplate.setConnectionFactory(connectionFactory); 
      destination = (Destination) initialContext_backup.lookup(toQueue); 
      System.out.print("[to-backup]-"); 
} 
     catch(Exception e) //live server is down 
     { 
flag=false; 
      connectionFactory = (ConnectionFactory)initialContext_backup.lookup("/ConnectionFactory"); 
      jmsTemplate.setConnectionFactory(connectionFactory); 
      destination = (Destination) initialContext_backup.lookup(toQueue); 
      System.out.print("[to-backup]-"); 
     } 

所以在這裏也不會,如果莫名其妙地檢查活動服務器的代碼連接丟失之間它將直接連接到備份服務器

如果您的服務器已啓動,您可以將標誌設置爲true。

第二件事情在catch塊而不是異常聲明它爲特定的異常。它也影響性能。

+0

謝謝,它更好!但我想知道是否有一種方法可以用於JNDI故障轉移! – united

+0

而且我認爲它在Live服務器重新啓動時不起作用! – united

+0

不,它會工作,我們需要做的事情,一旦我們知道活服務器了,我們需要設置標誌爲真。 – Pri