当前位置: 首页 > 知识库问答 >
问题:

动态更改 JNDI 提供程序

卫深
2023-03-14

我在同一台机器上有两台HornetQ(2.2.14)独立服务器(实时备份服务器);考虑以下场景:

  1. Live服务器崩溃,备份服务器现在处于活动状态。
  2. 客户端A(不知道Live服务器崩溃)想要连接到Live服务器(它应该使用Live服务器JNDI提供程序查找其连接html" target="_blank">工厂)。
  3. 客户端A找不到Live服务器JNDI提供程序,因此它应该连接到备份服务器(它应该使用备份服务器JNDI提供程序查找其连接工厂)。

如何为客户端A动态更改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>

更新:我可以通过以下方式处理从应用程序中的当前实时 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.");
        }

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

共有1个答案

耿和韵
2023-03-14

我在这里发现了两件事

首先你设置一个全局标志,如果有条件

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块中的第二件事而不是异常声明它用于特定的异常。它也会影响性能

 类似资料:
  • 问题内容: 我在具有基本HTTP服务器(没有Express或Connect或类似的东西)的Node服务器上使用Socket.IO。默认情况下,Socket.IO将客户端文件提供给 /socket.io/socket.io.js 我希望能够将该基本路径更改为其他内容,例如 /foo/bar/socket.io/socket.io.js 是否有任何内置方法来执行此操作,或者是否有任何不更改Socket

  • 问题内容: 我正在从数据库中成功获取数据值。我也将它们存储到一个数组中。我需要将String数组作为项的加载,以响应执行的关键操作。每当获取按键值时,如何获取按键值,就如何重新加载项目。相反,我需要动态刷新项目。 问题答案:

  • 下面是我的app.js文件 下面是我的状态文件 我有一个模板,我想从那里导航到下一个状态 但是只要我点击这个锚标签,它就会把我导航回主页。(不去我打算去的州)。主要问题是URL(我猜)任何帮助都会很感激。

  • 问题内容: 我正在以编程方式/动态方式创建原型bean。我希望启动后的这些bean在jmx控制台中。我如何区分它们?我正在使用注释以便将我的bean添加到jmx中, 我需要动态注入objectName。知道我该怎么办吗? 这是我的jmx配置: 问题答案: 您可以使用JMX命名策略来执行此操作。在工作中,我们使用一个接口: 我已经发布了实现RuntimeMetadataNamingStrategy命

  • 我最近更改了DNS提供商,我正在尝试将DNS记录添加到我的新提供商。但是,我不确定应该添加多少记录。 我的旧名称服务器有一大堆自动创建的记录,如“ftp.example.com”、“cpanel.example.com”、“carddavs.\u tcp.example.com”、“webdisk.example.com”、“autodiscover.example.com”等。 所以我的问题是,

  • 我正在尝试使用pact来验证spring boot微服务。我已经从consumer生成了pact文件,并在provider端使用pact Broker验证了它。 我有另一个用例,在根据实际的服务响应验证pact文件之前,我需要执行一些代码。我读过关于状态改变URL和状态改变与闭包来实现它,但没有得到一个如何实现这一点的例子。有人能帮忙吗? 如果这个客户不存在,那么我将需要通过读取pact文件中的更