Skip to content

Commit cf3f3bf

Browse files
committed
Retry connect to provider server by catching ClosedChannelException
1 parent 91b005e commit cf3f3bf

File tree

1 file changed

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

1 file changed

+90
-66
lines changed

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

Lines changed: 90 additions & 66 deletions
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,101 @@ 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.cancel();
148+
future = bootstrap.connect(connectAddress);
149+
continue;
120150
}
121-
} else {
122-
NettyClient.this.channel = newChannel;
123151
}
152+
RemotingException remotingException = new RemotingException(
153+
this,
154+
"client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress()
155+
+ ", error message is:" + cause.getMessage(),
156+
cause);
157+
158+
// 6-1 - Failed to connect to provider server by other reason.
159+
logger.error(
160+
TRANSPORT_FAILED_CONNECT_PROVIDER,
161+
"network disconnected",
162+
"",
163+
"Failed to connect to provider server by other reason.",
164+
cause);
165+
166+
throw remotingException;
167+
} else {
168+
169+
RemotingException remotingException = new RemotingException(
170+
this,
171+
"client(url: " + getUrl() + ") failed to connect to server " + getRemoteAddress()
172+
+ " client-side timeout " + getConnectTimeout() + "ms (elapsed: "
173+
+ (System.currentTimeMillis() - start) + "ms) from netty client "
174+
+ NetUtils.getLocalHost() + " using dubbo version " + Version.getVersion());
175+
176+
// 6-2 - Client-side timeout.
177+
logger.error(
178+
TRANSPORT_CLIENT_CONNECT_TIMEOUT,
179+
"provider crash",
180+
"",
181+
"Client-side timeout.",
182+
remotingException);
183+
184+
throw remotingException;
124185
}
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;
162186
}
163187
} finally {
164188
if (!isConnected()) {

0 commit comments

Comments
 (0)