Corda RPC客户端无法在节点重新启动后与Corda节点重新连接

Corda RPC客户端无法在节点重新启动后与Corda节点重新连接,corda,Corda,我正在尝试使用RPC连接管理来启用节点故障切换时的自动重试。但我注意到,在重新启动节点后,客户端无法与corda节点重新连接。下面是我的代码: class ConnectToCordaRPC(val nodeHostAndPort: NetworkHostAndPort, val username: String, val password: String) { lateinit var rpcConnection: CordaRPCConnection priv

我正在尝试使用RPC连接管理来启用节点故障切换时的自动重试。但我注意到,在重新启动节点后,客户端无法与corda节点重新连接。下面是我的代码:

class ConnectToCordaRPC(val nodeHostAndPort: NetworkHostAndPort, val 
   username: String, val password: String) {
    lateinit var rpcConnection: CordaRPCConnection
        private set
    lateinit var proxy: CordaRPCOps
        private set
    val logger = loggerFor<ConnectToCordaRPC>()

private fun establishConnectionWithRetry(): CordaRPCConnection? {
    val retryInterval = 5.seconds

    do {
        val connection = try {
            logger.info("Connecting to: $nodeHostAndPort")
            val cordaRPCClientConfiguration = CordaRPCClientConfiguration(retryInterval)
            val client = CordaRPCClient(
                    nodeHostAndPort,
                    cordaRPCClientConfiguration
            )
            val _connection = client.start(username, password)
            // Check connection is truly operational before returning it.
            val nodeInfo = _connection.proxy.nodeInfo()
            require(nodeInfo.legalIdentitiesAndCerts.isNotEmpty())
            _connection
        } catch(secEx: ActiveMQSecurityException) {
            // Happens when incorrect credentials provided - no point to retry connecting.
            throw secEx
        }
        catch(ex: RPCException) {
            // Deliberately not logging full stack trace as it will be full of internal stacktraces.
            logger.info("Exception upon establishing connection: " + ex.message)
            null
        }

        if(connection != null) {
            logger.info("Connection successfully established with: $nodeHostAndPort")
            return connection
        }
        // Could not connect this time round - pause before giving another try.
        Thread.sleep(retryInterval.toMillis())
    } while (connection == null)

    return null
}

fun performRpcReconnect() {
    rpcConnection = establishConnectionWithRetry()!!
    proxy = rpcConnection.proxy

    val (snapshot, updates) = proxy.vaultTrack(IOUState::class.java)

    //snapshot.states.forEach {}
    updates.toBlocking().subscribe { update ->
        update.produced.forEach { processState(it.state.data) }
    }

    val (stateMachineInfos, stateMachineUpdatesRaw) = proxy.stateMachinesFeed()

    val retryableStateMachineUpdatesSubscription: AtomicReference<Subscription?> = AtomicReference(null)
    val subscription: Subscription = stateMachineUpdatesRaw
            .startWith(stateMachineInfos.map { StateMachineUpdate.Added(it) })
            .subscribe({logger.info(it.id.toString())

                /* Client code here */ }, {
                logger.info("*********closing the connection*********")
                // Terminate subscription such that nothing gets past this point to downstream Observables.
                retryableStateMachineUpdatesSubscription.get()?.unsubscribe()
                // It is good idea to close connection to properly mark the end of it. During re-connect we will create a new
                // client and a new connection, so no going back to this one. Also the server might be down, so we are
                // force closing the connection to avoid propagation of notification to the server side.
                rpcConnection.forceClose()
                // Perform re-connect.
                performRpcReconnect()
            })

    retryableStateMachineUpdatesSubscription.set(subscription)
}
private fun processState(state: ContractState) {
    logger.info("state is "+ state.toString())

        }
    }
}

class EventListenerRPC {

    fun main(args: Array<String>) {

        require(System.getenv("CONFIG_RPC_HOST") != null) { "CONFIG_RPC_HOST env var was not set." }
        require(System.getenv("CONFIG_RPC_PORT") != null) { "CONFIG_RPC_PORT env var was not set." }
        require(System.getenv("CONFIG_RPC_USERNAME") != null) { "CONFIG_RPC_USERNAME env var was not set." }
        require(System.getenv("CONFIG_RPC_PASSWORD") != null) { "CONFIG_RPC_PASSWORD env var was not set." }


        val nodeIpAndPort = "${System.getenv(CORDA_VARS.CORDA_NODE_HOST)}:${System.getenv(CORDA_VARS.CORDA_NODE_RPC_PORT)}"
        val nodeAddress = NetworkHostAndPort.parse(nodeIpAndPort)

        val nodeUsername = System.getenv(CORDA_VARS.CORDA_USER_NAME)
        val nodePassword = System.getenv(CORDA_VARS.CORDA_USER_PASSWORD)
        val connectToCordaRPC = ConnectToCordaRPC(nodeAddress, nodeUsername, nodePassword)
        connectToCordaRPC.performRpcReconnect()
    }
}

这里可能有什么问题?是因为订阅新状态更新的阻止代码吗?

这是企业RPC客户端和节点的原因吗?如果是这样的话,你能申请一张支持票吗?我不确定开源RPC客户端是否具有HA/故障转移支持。

我使用的是Corda OS v3.2,但我假设Artemis隐式支持故障转移。那么,是否从操作系统版本中删除了artemis故障切换?它没有被删除否。artemis客户端库支持artemis群集成员之间的故障切换。但是当代理嵌入到节点中时,从Artemis的观点来看,两个节点=两个不同的不相关集群。在企业中,我们通过一些应用程序级故障切换解决了这一问题。从长远来看,正确的方法是建立一个HA Artemis集群,然后是一个使用它的HA Corda集群,然后“正常”的Artemis故障切换应该可以工作。Ent4中提供了对分离Artemis的支持。同意Artemis支持成员之间的故障切换。但我还认为artemis客户端库将尝试自动重新连接到同一个代理(不在集群模式下运行),并且应用程序不需要编写任何额外的代码来尝试重新连接。同样,在阅读此评论之后,故障转移似乎是在artemis级别处理的?让我描述一下我面临的问题:我尝试运行示例spring boot应用程序(来自corda samples),并注意到spring boot应用程序可以自动处理与corda节点的重新连接。因此,不需要上面的代码就可以做到这一点,而且我也不必显式地重新启动我的应用程序。但是,如果我只运行连接到corda节点的基本RPCClient代码并使用Vault Track RPC,则必须显式重新启动应用程序,因为
artemis断开连接
异常不会传播回Vault Rack,因此无法再次开始跟踪。
    16:19:21.455 [Thread-4 (ActiveMQ-client-global-threads)] WARN org.apache.activemq.artemis.core.client - AMQ212037: Connection failure has been detected: AMQ119015: The connection was disconnected because of server shutdown [code=DISCONNECTED]
16:19:21.486 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying reconnection attempt 0/-1
16:19:21.486 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying to connect with connectorFactory = org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory@f09733f, connectorConfig=TransportConfiguration(name=913dad64-f4bb-11e8-844e-5cea1d41295b, factory=org-apache-activemq-artemis-core-remoting-impl-netty-NettyConnectorFactory) ?host=192-168-249-61&port=10003&protocols=CORE,AMQP&useGlobalWorkerPool=true&RemotingThreads=-1
16:19:21.488 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Connector + NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] using nio
16:19:21.488 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Started Netty Connector version 4.1.27.Final
16:19:21.488 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Remote destination: /192.168.249.61:10003
16:19:22.729 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Connector towards NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] failed
16:19:27.732 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying reconnection attempt 1/-1
16:19:27.733 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying to connect with connectorFactory = org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory@f09733f, connectorConfig=TransportConfiguration(name=913dad64-f4bb-11e8-844e-5cea1d41295b, factory=org-apache-activemq-artemis-core-remoting-impl-netty-NettyConnectorFactory) ?host=192-168-249-61&port=10003&protocols=CORE,AMQP&useGlobalWorkerPool=true&RemotingThreads=-1
16:19:27.736 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Connector + NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] using nio
16:19:27.736 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Started Netty Connector version 4.1.27.Final
16:19:27.736 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Remote destination: /192.168.249.61:10003
16:19:28.927 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Connector towards NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] failed
16:19:33.932 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying reconnection attempt 2/-1
16:19:33.932 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying to connect with connectorFactory = org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory@f09733f, connectorConfig=TransportConfiguration(name=913dad64-f4bb-11e8-844e-5cea1d41295b, factory=org-apache-activemq-artemis-core-remoting-impl-netty-NettyConnectorFactory) ?host=192-168-249-61&port=10003&protocols=CORE,AMQP&useGlobalWorkerPool=true&RemotingThreads=-1
16:19:33.933 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Connector + NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] using nio
16:19:33.933 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Started Netty Connector version 4.1.27.Final
16:19:33.933 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Remote destination: /192.168.249.61:10003
16:19:35.128 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Connector towards NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] failed
16:19:40.132 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying reconnection attempt 3/-1
16:19:40.133 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying to connect with connectorFactory = org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory@f09733f, connectorConfig=TransportConfiguration(name=913dad64-f4bb-11e8-844e-5cea1d41295b, factory=org-apache-activemq-artemis-core-remoting-impl-netty-NettyConnectorFactory) ?host=192-168-249-61&port=10003&protocols=CORE,AMQP&useGlobalWorkerPool=true&RemotingThreads=-1
16:19:40.136 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Connector + NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] using nio
16:19:40.136 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Started Netty Connector version 4.1.27.Final
16:19:40.136 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Remote destination: /192.168.249.61:10003
16:19:41.428 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Connector towards NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] failed
16:19:46.450 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying reconnection attempt 4/-1
16:19:46.456 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Trying to connect with connectorFactory = org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnectorFactory@f09733f, connectorConfig=TransportConfiguration(name=913dad64-f4bb-11e8-844e-5cea1d41295b, factory=org-apache-activemq-artemis-core-remoting-impl-netty-NettyConnectorFactory) ?host=192-168-249-61&port=10003&protocols=CORE,AMQP&useGlobalWorkerPool=true&RemotingThreads=-1
16:19:46.458 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Connector + NettyConnector [host=192.168.249.61, port=10003, httpEnabled=false, httpUpgradeEnabled=false, useServlet=false, servletPath=/messaging/ActiveMQServlet, sslEnabled=false, useNio=true] using nio
16:19:46.458 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Started Netty Connector version 4.1.27.Final
16:19:46.458 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.remoting.impl.netty.NettyConnector - Remote destination: /192.168.249.61:10003
16:19:46.620 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client.impl.ClientSessionFactoryImpl - Reconnection successful
16:19:46.673 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client - AMQ214028: Couldnt reattach session {0}, performing as a failover operation now and recreating objects
16:19:46.791 [Thread-4 (ActiveMQ-client-global-threads)] DEBUG org.apache.activemq.artemis.core.client - AMQ214028: Couldnt reattach session {0}, performing as a failover operation now and recreating objects