[ISSUE #6367] Add IOReactorExceptionHandler to avoid IOReactor out of loop when meet unknown Network error. (#6441)
* Add IOExceptionHandler to handle the Exception form IOReactor. * remove the systemProperties for create ConnectionManager. * fix the javadoc.
This commit is contained in:
parent
ab1f543b9f
commit
2b186bc3fe
@ -26,9 +26,22 @@ import com.alibaba.nacos.common.tls.TlsHelper;
|
||||
import com.alibaba.nacos.common.tls.TlsSystemConfig;
|
||||
import com.alibaba.nacos.common.utils.BiConsumer;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.config.Registry;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.ssl.DefaultHostnameVerifier;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
|
||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
|
||||
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
|
||||
import org.apache.http.impl.nio.reactor.IOReactorConfig;
|
||||
import org.apache.http.nio.conn.NHttpClientConnectionManager;
|
||||
import org.apache.http.nio.conn.NoopIOSessionStrategy;
|
||||
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
|
||||
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
|
||||
import org.apache.http.nio.reactor.IOReactorException;
|
||||
import org.apache.http.nio.reactor.IOReactorExceptionHandler;
|
||||
import org.apache.http.protocol.RequestContent;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import javax.net.ssl.HostnameVerifier;
|
||||
@ -77,7 +90,65 @@ public abstract class AbstractHttpClientFactory implements HttpClientFactory {
|
||||
.setDefaultRequestConfig(getRequestConfig())
|
||||
.setMaxConnTotal(originalRequestConfig.getMaxConnTotal())
|
||||
.setMaxConnPerRoute(originalRequestConfig.getMaxConnPerRoute())
|
||||
.setUserAgent(originalRequestConfig.getUserAgent()).build()));
|
||||
.setUserAgent(originalRequestConfig.getUserAgent())
|
||||
.setConnectionManager(getConnectionManager(originalRequestConfig))
|
||||
.build()));
|
||||
}
|
||||
|
||||
/**
|
||||
* create the {@link NHttpClientConnectionManager}, the code mainly from {@link HttpAsyncClientBuilder#build()}.
|
||||
* we add the {@link IOReactorExceptionHandler} to handle the {@link IOException} and {@link RuntimeException}
|
||||
* thrown by the {@link org.apache.http.impl.nio.reactor.BaseIOReactor} when process the event of Network.
|
||||
* Using this way to avoid the {@link DefaultConnectingIOReactor} killed by unknown error of network.
|
||||
*
|
||||
* @param originalRequestConfig request config.
|
||||
* @return {@link NHttpClientConnectionManager}.
|
||||
*/
|
||||
private NHttpClientConnectionManager getConnectionManager(HttpClientConfig originalRequestConfig) {
|
||||
SSLContext sslcontext = SSLContexts.createDefault();
|
||||
HostnameVerifier hostnameVerifier = new DefaultHostnameVerifier();
|
||||
SchemeIOSessionStrategy sslStrategy = new SSLIOSessionStrategy(sslcontext, null, null, hostnameVerifier);
|
||||
|
||||
final DefaultConnectingIOReactor ioreactor;
|
||||
try {
|
||||
ioreactor = new DefaultConnectingIOReactor(getIoReactorConfig());
|
||||
} catch (IOReactorException e) {
|
||||
assignLogger().error("[NHttpClientConnectionManager] Create DefaultConnectingIOReactor failed", e);
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
// if the handle return true, then the exception thrown by IOReactor will be ignore, and will not finish the IOReactor.
|
||||
ioreactor.setExceptionHandler(new IOReactorExceptionHandler() {
|
||||
|
||||
@Override
|
||||
public boolean handle(IOException ex) {
|
||||
assignLogger().warn("[NHttpClientConnectionManager] handle IOException, ignore it.", ex);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(RuntimeException ex) {
|
||||
assignLogger().warn("[NHttpClientConnectionManager] handle RuntimeException, ignore it.", ex);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
Registry<SchemeIOSessionStrategy> registry = RegistryBuilder.<SchemeIOSessionStrategy>create()
|
||||
.register("http", NoopIOSessionStrategy.INSTANCE)
|
||||
.register("https", sslStrategy)
|
||||
.build();
|
||||
final PoolingNHttpClientConnectionManager poolingmgr = new PoolingNHttpClientConnectionManager(ioreactor, registry);
|
||||
|
||||
int maxTotal = originalRequestConfig.getMaxConnTotal();
|
||||
if (maxTotal > 0) {
|
||||
poolingmgr.setMaxTotal(maxTotal);
|
||||
}
|
||||
|
||||
int maxPerRoute = originalRequestConfig.getMaxConnPerRoute();
|
||||
if (maxPerRoute > 0) {
|
||||
poolingmgr.setDefaultMaxPerRoute(maxPerRoute);
|
||||
}
|
||||
return poolingmgr;
|
||||
}
|
||||
|
||||
protected IOReactorConfig getIoReactorConfig() {
|
||||
|
Loading…
Reference in New Issue
Block a user