-
Notifications
You must be signed in to change notification settings - Fork 26.6k
[3.3] Retry connect to provider server by catching ClosedChannelException #15209
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
Merged
AlbumenJ
merged 1 commit into
apache:3.3
from
zrlw:3.3-Optimized-catchClosedChannelException4NettyClient
Mar 12, 2025
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,8 @@ | |
| import org.apache.dubbo.remoting.RemotingException; | ||
| import org.apache.dubbo.remoting.transport.AbstractClient; | ||
|
|
||
| import java.net.InetSocketAddress; | ||
| import java.nio.channels.ClosedChannelException; | ||
| import java.util.concurrent.Executors; | ||
| import java.util.concurrent.TimeUnit; | ||
|
|
||
|
|
@@ -86,79 +88,100 @@ public ChannelPipeline getPipeline() { | |
| @Override | ||
| protected void doConnect() throws Throwable { | ||
| long start = System.currentTimeMillis(); | ||
| ChannelFuture future = bootstrap.connect(getConnectAddress()); | ||
| InetSocketAddress connectAddress = getConnectAddress(); | ||
| ChannelFuture future = bootstrap.connect(connectAddress); | ||
| long connectTimeout = getConnectTimeout(); | ||
| long deadline = start + connectTimeout; | ||
| try { | ||
| boolean ret = future.awaitUninterruptibly(getConnectTimeout(), TimeUnit.MILLISECONDS); | ||
|
|
||
| if (ret && future.isSuccess()) { | ||
| Channel newChannel = future.getChannel(); | ||
| newChannel.setInterestOps(Channel.OP_READ_WRITE); | ||
| try { | ||
| // Close old channel | ||
| Channel oldChannel = NettyClient.this.channel; // copy reference | ||
| if (oldChannel != null) { | ||
| try { | ||
| if (logger.isInfoEnabled()) { | ||
| logger.info("Close old netty channel " + oldChannel + " on create new netty channel " | ||
| + newChannel); | ||
| while (true) { | ||
| boolean ret = future.awaitUninterruptibly(connectTimeout, TimeUnit.MILLISECONDS); | ||
|
|
||
| if (ret && future.isSuccess()) { | ||
| Channel newChannel = future.getChannel(); | ||
| newChannel.setInterestOps(Channel.OP_READ_WRITE); | ||
| try { | ||
| // copy reference | ||
| Channel oldChannel = NettyClient.this.channel; | ||
| if (oldChannel != null) { | ||
| try { | ||
| if (logger.isInfoEnabled()) { | ||
| logger.info("Close old netty channel " + oldChannel | ||
| + " on create new netty channel " + newChannel); | ||
| } | ||
| // Close old channel | ||
| oldChannel.close(); | ||
| } finally { | ||
| NettyChannel.removeChannelIfDisconnected(oldChannel); | ||
| } | ||
| oldChannel.close(); | ||
| } finally { | ||
| NettyChannel.removeChannelIfDisconnected(oldChannel); | ||
| } | ||
| } | ||
| } finally { | ||
| if (NettyClient.this.isClosed()) { | ||
| try { | ||
| if (logger.isInfoEnabled()) { | ||
| logger.info("Close new netty channel " + newChannel + ", because the client closed."); | ||
| } finally { | ||
| if (NettyClient.this.isClosed()) { | ||
| try { | ||
| if (logger.isInfoEnabled()) { | ||
| logger.info( | ||
| "Close new netty channel " + newChannel + ", because the client closed."); | ||
| } | ||
| newChannel.close(); | ||
| } finally { | ||
| NettyClient.this.channel = null; | ||
| NettyChannel.removeChannelIfDisconnected(newChannel); | ||
| } | ||
| newChannel.close(); | ||
| } finally { | ||
| NettyClient.this.channel = null; | ||
| NettyChannel.removeChannelIfDisconnected(newChannel); | ||
| } else { | ||
| NettyClient.this.channel = newChannel; | ||
| } | ||
| } | ||
| break; | ||
| } else if (future.getCause() != null) { | ||
| Throwable cause = future.getCause(); | ||
|
|
||
| if (cause instanceof ClosedChannelException) { | ||
| // Netty3.2.10 ClosedChannelException issue, see https://github.com/netty/netty/issues/138 | ||
| connectTimeout = deadline - System.currentTimeMillis(); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @AlbumenJ |
||
| if (connectTimeout > 0) { | ||
| // 6-1 - Retry connect to provider server by Netty3.2.10 ClosedChannelException issue#138. | ||
| logger.warn( | ||
| TRANSPORT_FAILED_CONNECT_PROVIDER, | ||
| "Netty3.2.10 ClosedChannelException issue#138", | ||
| "", | ||
| "Retry connect to provider server."); | ||
| future = bootstrap.connect(connectAddress); | ||
| continue; | ||
| } | ||
| } else { | ||
| NettyClient.this.channel = newChannel; | ||
| } | ||
| RemotingException remotingException = new RemotingException( | ||
| this, | ||
| "client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress() | ||
| + ", error message is:" + cause.getMessage(), | ||
| cause); | ||
|
|
||
| // 6-1 - Failed to connect to provider server by other reason. | ||
| logger.error( | ||
| TRANSPORT_FAILED_CONNECT_PROVIDER, | ||
| "network disconnected", | ||
| "", | ||
| "Failed to connect to provider server by other reason.", | ||
| cause); | ||
|
|
||
| throw remotingException; | ||
| } else { | ||
|
|
||
| RemotingException remotingException = new RemotingException( | ||
| this, | ||
| "client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress() | ||
| + " client-side timeout " + getConnectTimeout() + "ms (elapsed: " | ||
| + (System.currentTimeMillis() - start) + "ms) from netty client " | ||
| + NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()); | ||
|
|
||
| // 6-2 - Client-side timeout. | ||
| logger.error( | ||
| TRANSPORT_CLIENT_CONNECT_TIMEOUT, | ||
| "provider crash", | ||
| "", | ||
| "Client-side timeout.", | ||
| remotingException); | ||
|
|
||
| throw remotingException; | ||
| } | ||
| } else if (future.getCause() != null) { | ||
| Throwable cause = future.getCause(); | ||
|
|
||
| RemotingException remotingException = new RemotingException( | ||
| this, | ||
| "client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress() | ||
| + ", error message is:" + cause.getMessage(), | ||
| cause); | ||
|
|
||
| // 6-1 - Failed to connect to provider server by other reason. | ||
| logger.error( | ||
| TRANSPORT_FAILED_CONNECT_PROVIDER, | ||
| "network disconnected", | ||
| "", | ||
| "Failed to connect to provider server by other reason.", | ||
| cause); | ||
|
|
||
| throw remotingException; | ||
| } else { | ||
|
|
||
| RemotingException remotingException = new RemotingException( | ||
| this, | ||
| "client(url: " + getUrl() + ") failed to connect to server " | ||
| + getRemoteAddress() + " client-side timeout " | ||
| + getConnectTimeout() + "ms (elapsed: " + (System.currentTimeMillis() - start) | ||
| + "ms) from netty client " | ||
| + NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion()); | ||
|
|
||
| // 6-2 - Client-side timeout. | ||
| logger.error( | ||
| TRANSPORT_CLIENT_CONNECT_TIMEOUT, | ||
| "provider crash", | ||
| "", | ||
| "Client-side timeout.", | ||
| remotingException); | ||
|
|
||
| throw remotingException; | ||
| } | ||
| } finally { | ||
| if (!isConnected()) { | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should limit the maximum times here