Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 动态更改JNDI提供程序_Java_Spring_Jms_Jndi_Hornetq - Fatal编程技术网

Java 动态更改JNDI提供程序

Java 动态更改JNDI提供程序,java,spring,jms,jndi,hornetq,Java,Spring,Jms,Jndi,Hornetq,我在同一台机器上有两台HornetQ(2.2.14)独立服务器(实时备份服务器);考虑这种情况: 实时服务器崩溃,备份服务器现在处于实时状态 客户端A(不知道Live server崩溃)希望连接到Live server(它应该使用Live server JNDI提供程序查找其连接工厂) 客户端A找不到实时服务器JNDI提供程序,因此它应该连接到备份服务器(它应该使用备份服务器JNDI提供程序查找其连接工厂)。 如何为客户端动态更改JNDI提供程序(更改URL)?有没有JNDI故障切换的方法? 我

我在同一台机器上有两台HornetQ(2.2.14)独立服务器(实时备份服务器);考虑这种情况:

  • 实时服务器崩溃,备份服务器现在处于实时状态
  • 客户端A(不知道Live server崩溃)希望连接到Live server(它应该使用Live server JNDI提供程序查找其连接工厂)
  • 客户端A找不到实时服务器JNDI提供程序,因此它应该连接到备份服务器(它应该使用备份服务器JNDI提供程序查找其连接工厂)。
  • 如何为客户端动态更改JNDI提供程序(更改URL)?有没有JNDI故障切换的方法?

    我有一个spring集成应用程序,它是我的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>
    
    
    org.jnp.interfaces.NamingContextFactory
    org.jboss.naming:org.jnp.interfaces
    jnp://localhost:1099
    org.jnp.interfaces.NamingContextFactory
    org.jboss.naming:org.jnp.interfaces
    jnp://localhost:2099
    
    更新: 我可以通过以下方式从我的应用程序中的当前live Server查找连接工厂: 对于每条消息

  • 检查可用的JNDI提供程序(从当前实时服务器)
  • 查找连接工厂
  • 发送消息
  • 类似这样的内容(来自我的MessageSender类):

    //实时服务器和备份服务器的初始化上下文
    public init()引发NamingException、CommunicationException
    {
    Hashtable环境=新的Hashtable();
    put(Context.INITIAL_Context_FACTORY,“org.jnp.interfaces.NamingContextFactory”);
    put(Context.URL_PKG_前缀,“org.jboss.naming:org.jnp.interfaces”);
    environment.put(Context.PROVIDER\u URL,“jnp://localhost:1099");
    initialContext_live=新的initialContext(环境);
    环境=新哈希表();
    put(Context.INITIAL_Context_FACTORY,“org.jnp.interfaces.NamingContextFactory”);
    put(Context.URL_PKG_前缀,“org.jboss.naming:org.jnp.interfaces”);
    environment.put(Context.PROVIDER\u URL,“jnp://localhost:2099");
    initialContext\u backup=新的initialContext(环境);
    jmsTemplate=新jmsTemplate();
    }
    //向toQueue发送消息
    public void send(最终的AbstractMessage消息,字符串toQueue)引发NamingException
    {
    目的地;
    尝试
    {
    connectionFactory=(connectionFactory)initialContext_live.lookup(“/connectionFactory”);
    jmsTemplate.setConnectionFactory(connectionFactory);
    destination=(destination)initialContext\u live.lookup(toQueue);
    系统输出打印(“[to live]”);
    }
    catch(异常e)//实时服务器已关闭
    {
    connectionFactory=(connectionFactory)initialContext_backup.lookup(“/connectionFactory”);
    jmsTemplate.setConnectionFactory(connectionFactory);
    destination=(destination)initialContext\u backup.lookup(toQueue);
    系统输出打印(“[备份]”);
    }
    发送(目的地,newmessagecreator()
    {
    @凌驾
    公共消息createMessage(会话)引发JMSExException
    {
    ObjectMessage objMessage=session.createObjectMessage(消息);
    返回objMessage;
    }
    });
    System.out.println(“[MessageSender]messagesent.”);
    }
    

    但是它非常耗时(大约两秒钟一条消息)

    我在这里发现了两件事

    首先设置一个全局标志,并设置if-else条件

    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]-");
            } 
    
    所以,在这里,它不会检查live server的代码,如果其间的连接丢失,它将直接连接到备份服务器

    如果您的实时服务器已启动,则可以将flag设置为true


    在catch块中的第二件事是为特定的异常声明它,而不是异常。这也会影响性能。

    谢谢,这样更好!但是我想知道是否有JNDI故障切换的方法!不,这将是我们需要做的工作,一旦我们知道实时服务器已经启动,我们需要将标志设置为true。
    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]-");
            }