Skip to content

Commit 243da4d

Browse files
authored
Retry connect to provider server by catching ClosedChannelException (#15209)
1 parent 5f04865 commit 243da4d

File tree

1 file changed

+89
-66
lines changed
  • dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty

1 file changed

+89
-66
lines changed

dubbo-remoting/dubbo-remoting-netty/src/main/java/org/apache/dubbo/remoting/transport/netty/NettyClient.java

+89-66
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.apache.dubbo.remoting.RemotingException;
2626
import org.apache.dubbo.remoting.transport.AbstractClient;
2727

28+
import java.net.InetSocketAddress;
29+
import java.nio.channels.ClosedChannelException;
2830
import java.util.concurrent.Executors;
2931
import java.util.concurrent.TimeUnit;
3032

@@ -86,79 +88,100 @@ public ChannelPipeline getPipeline() {
8688
@Override
8789
protected void doConnect() throws Throwable {
8890
long start = System.currentTimeMillis();
89-
ChannelFuture future = bootstrap.connect(getConnectAddress());
91+
InetSocketAddress connectAddress = getConnectAddress();
92+
ChannelFuture future = bootstrap.connect(connectAddress);
93+
long connectTimeout = getConnectTimeout();
94+
long deadline = start + connectTimeout;
9095
try {
91-
boolean ret = future.awaitUninterruptibly(getConnectTimeout(), TimeUnit.MILLISECONDS);
92-
93-
if (ret && future.isSuccess()) {
94-
Channel newChannel = future.getChannel();
95-
newChannel.setInterestOps(Channel.OP_READ_WRITE);
96-
try {
97-
// Close old channel
98-
Channel oldChannel = NettyClient.this.channel; // copy reference
99-
if (oldChannel != null) {
100-
try {
101-
if (logger.isInfoEnabled()) {
102-
logger.info("Close old netty channel " + oldChannel + " on create new netty channel "
103-
+ newChannel);
96+
while (true) {
97+
boolean ret = future.awaitUninterruptibly(connectTimeout, TimeUnit.MILLISECONDS);
98+
99+
if (ret && future.isSuccess()) {
100+
Channel newChannel = future.getChannel();
101+
newChannel.setInterestOps(Channel.OP_READ_WRITE);
102+
try {
103+
// copy reference
104+
Channel oldChannel = NettyClient.this.channel;
105+
if (oldChannel != null) {
106+
try {
107+
if (logger.isInfoEnabled()) {
108+
logger.info("Close old netty channel " + oldChannel
109+
+ " on create new netty channel " + newChannel);
110+
}
111+
// Close old channel
112+
oldChannel.close();
113+
} finally {
114+
NettyChannel.removeChannelIfDisconnected(oldChannel);
104115
}
105-
oldChannel.close();
106-
} finally {
107-
NettyChannel.removeChannelIfDisconnected(oldChannel);
108116
}
109-
}
110-
} finally {
111-
if (NettyClient.this.isClosed()) {
112-
try {
113-
if (logger.isInfoEnabled()) {
114-
logger.info("Close new netty channel " + newChannel + ", because the client closed.");
117+
} finally {
118+
if (NettyClient.this.isClosed()) {
119+
try {
120+
if (logger.isInfoEnabled()) {
121+
logger.info(
122+
"Close new netty channel " + newChannel + ", because the client closed.");
123+
}
124+
newChannel.close();
125+
} finally {
126+
NettyClient.this.channel = null;
127+
NettyChannel.removeChannelIfDisconnected(newChannel);
115128
}
116-
newChannel.close();
117-
} finally {
118-
NettyClient.this.channel = null;
119-
NettyChannel.removeChannelIfDisconnected(newChannel);
129+
} else {
130+
NettyClient.this.channel = newChannel;
131+
}
132+
}
133+
break;
134+
} else if (future.getCause() != null) {
135+
Throwable cause = future.getCause();
136+
137+
if (cause instanceof ClosedChannelException) {
138+
// Netty3.2.10 ClosedChannelException issue, see https://github.com/netty/netty/issues/138
139+
connectTimeout = deadline - System.currentTimeMillis();
140+
if (connectTimeout > 0) {
141+
// 6-1 - Retry connect to provider server by Netty3.2.10 ClosedChannelException issue#138.
142+
logger.warn(
143+
TRANSPORT_FAILED_CONNECT_PROVIDER,
144+
"Netty3.2.10 ClosedChannelException issue#138",
145+
"",
146+
"Retry connect to provider server.");
147+
future = bootstrap.connect(connectAddress);
148+
continue;
120149
}
121-
} else {
122-
NettyClient.this.channel = newChannel;
123150
}
151+
RemotingException remotingException = new RemotingException(
152+
this,
153+
"client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress()
154+
+ ", error message is:" + cause.getMessage(),
155+
cause);
156+
157+
// 6-1 - Failed to connect to provider server by other reason.
158+
logger.error(
159+
TRANSPORT_FAILED_CONNECT_PROVIDER,
160+
"network disconnected",
161+
"",
162+
"Failed to connect to provider server by other reason.",
163+
cause);
164+
165+
throw remotingException;
166+
} else {
167+
168+
RemotingException remotingException = new RemotingException(
169+
this,
170+
"client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress()
171+
+ " client-side timeout " + getConnectTimeout() + "ms (elapsed: "
172+
+ (System.currentTimeMillis() - start) + "ms) from netty client "
173+
+ NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion());
174+
175+
// 6-2 - Client-side timeout.
176+
logger.error(
177+
TRANSPORT_CLIENT_CONNECT_TIMEOUT,
178+
"provider crash",
179+
"",
180+
"Client-side timeout.",
181+
remotingException);
182+
183+
throw remotingException;
124184
}
125-
} else if (future.getCause() != null) {
126-
Throwable cause = future.getCause();
127-
128-
RemotingException remotingException = new RemotingException(
129-
this,
130-
"client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress()
131-
+ ", error message is:" + cause.getMessage(),
132-
cause);
133-
134-
// 6-1 - Failed to connect to provider server by other reason.
135-
logger.error(
136-
TRANSPORT_FAILED_CONNECT_PROVIDER,
137-
"network disconnected",
138-
"",
139-
"Failed to connect to provider server by other reason.",
140-
cause);
141-
142-
throw remotingException;
143-
} else {
144-
145-
RemotingException remotingException = new RemotingException(
146-
this,
147-
"client(url: " + getUrl() + ") failed to connect to server "
148-
+ getRemoteAddress() + " client-side timeout "
149-
+ getConnectTimeout() + "ms (elapsed: " + (System.currentTimeMillis() - start)
150-
+ "ms) from netty client "
151-
+ NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion());
152-
153-
// 6-2 - Client-side timeout.
154-
logger.error(
155-
TRANSPORT_CLIENT_CONNECT_TIMEOUT,
156-
"provider crash",
157-
"",
158-
"Client-side timeout.",
159-
remotingException);
160-
161-
throw remotingException;
162185
}
163186
} finally {
164187
if (!isConnected()) {

0 commit comments

Comments
 (0)