Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

拉出再拉入,在连接中断之后不会重新建连 #6583

Closed
2 tasks
haiyang1985 opened this issue Aug 12, 2020 · 5 comments
Closed
2 tasks

拉出再拉入,在连接中断之后不会重新建连 #6583

haiyang1985 opened this issue Aug 12, 2020 · 5 comments

Comments

@haiyang1985
Copy link
Member

  • I have searched the issues of this repository and believe that this is not a duplicate.
  • I have checked the FAQ of this repository and believe that this is not a duplicate.

Environment

  • Dubbo version: 2.7.3
  • Operating System version: macOs
  • Java version: 1.8

Steps to reproduce this issue

  1. 启动服务端,再启动客户端
  2. 服务端拉出,再拉入集群
  3. 在服务端主动关闭连接,或者通过网络设备导致客户端与服务端的连接中断
  4. 客户端发送请求,会报message channel is closed的错误,只有重启才能恢复。

Pls. provide [GitHub address] to reproduce this issue.

Expected Result

因为dubbo客户端有主动重新建连的功能,如果服务端主动关闭,应该只有少量请求报错,之后会重新建连恢复。如果网络设备出现问题,也应该在网络设备恢复后报错停止。

Actual Result

在部分情况下会一直报错,直到重启恢复。

服务端在拉出之后,客户端会替换成lazyUrl,这里设置的RECONNECT_KEY为false

org.apache.dubbo.rpc.protocol.dubbo.ReferenceCountExchangeClient

private void replaceWithLazyClient() {
    URL lazyUrl = URLBuilder.from(url)
            .addParameter(LAZY_CONNECT_INITIAL_STATE_KEY, Boolean.TRUE)
            .addParameter(RECONNECT_KEY, Boolean.FALSE)
            .addParameter(SEND_RECONNECT_KEY, Boolean.FALSE.toString())
            .addParameter("warning", Boolean.TRUE.toString())
            .addParameter(LazyConnectExchangeClient.REQUEST_WITH_WARNING_KEY, false)
            .addParameter("_client_memo", "referencecounthandler.replacewithlazyclient")
            .build();
    if (!(client instanceof LazyConnectExchangeClient) || client.isClosed()) {
        client = new LazyConnectExchangeClient(lazyUrl, client.getExchangeHandler());
    }
}

因为是lazy连接,在下一个请求发起之前会尝试重新建连,在启动ReconnectTimerTask的时候会看下shouldReconnect(url)的状态是否要重新建连。
org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeClient

private void startReconnectTask(URL url) {
    if (shouldReconnect(url)) {
        AbstractTimerTask.ChannelProvider cp = () -> Collections.singletonList(HeaderExchangeClient.this);
        int idleTimeout = getIdleTimeout(url);
        long heartbeatTimeoutTick = calculateLeastDuration(idleTimeout);
        this.reconnectTimerTask = new ReconnectTimerTask(cp, heartbeatTimeoutTick, idleTimeout);
        IDLE_CHECK_TIMER.newTimeout(reconnectTimerTask, heartbeatTimeoutTick, TimeUnit.MILLISECONDS);
    }
}

如果被拉出之后再拉入,这里的url就是默认的false,不会启动ReconnectTimerTask

private boolean shouldReconnect(URL url) {
    return url.getParameter(Constants.RECONNECT_KEY, true);
}
@AlbumenJ
Copy link
Member

replaceWithLazyClient will be called when invoker close. This means invoker should not being invoked in the future, which cannot be reconected. Reconnect happends when the situation like network temporarily failure. If you use a registry to discover provider, when provider restart, a new invoker will be created.

@tianshuang
Copy link
Contributor

tianshuang commented Sep 9, 2020

Same problem.

@owen200008
Copy link
Contributor

owen200008 commented Sep 18, 2020

@AlbumenJ
Same problem. V2.7.8
when provider restart, a new invoker will be created. and use the same client(lazy).
getSharedClient reuse the client!

@chickenlj
Copy link
Contributor

please check this patch #7322

@CrazyHZM
Copy link
Member

CrazyHZM commented Nov 6, 2021

Try it with the latest version, if you still have problems, you can reopen the issue

@CrazyHZM CrazyHZM closed this as completed Nov 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants