我的项目使用apache超文本传输协议html" target="_blank">客户端向超文本传输协议服务器发送超文本传输协议请求。但是奇怪的事情发生了。我设置连接超时为10秒,套接字超时为10秒。对于每一天,大多数请求时间(大约100个请求)是100ms-200ms,但是左(大约10个请求)将抛出连接超时异常,这意味着连接建立时间是10s以上。我不知道发生了什么。
我的电话是:
HttpUtils。post(主机,空,参数,“UTF-8”,1000010000)
下面是异常堆栈跟踪。
org.apache.http.conn.ConnectTimeoutException: Connect to ***.***.***.***:80 [] failed: connect timed out
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:134)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:319)
at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:363)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:219)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
at HttpUtils.post(HttpUtils.java:201)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.apache.http.conn.socket.PlainConnectionSocketFactory.connectSocket(PlainConnectionSocketFactory.java:72)
at org.apache.http.impl.conn.HttpClientConnectionOperator.connect(HttpClientConnectionOperator.java:125)
... 84 more
和我的超文本传输协议后客户端:
import java.io.IOException;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.net.ssl.SSLContext;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpUtils {
private static final Logger logger = LoggerFactory.getLogger(HttpUtils.class);
private static int SocketTimeout = 3000;// 3秒
private static int ConnectTimeout = 3000;// 3秒
private static Boolean SetTimeOut = true;
public static CloseableHttpClient getHttpClient() {
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory> create();
ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
registryBuilder.register("http", plainSF);
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
TrustStrategy anyTrustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
SSLContext sslContext = SSLContexts.custom().useTLS().loadTrustMaterial(trustStore, anyTrustStrategy).build();
LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
registryBuilder.register("https", sslSF);
} catch (KeyStoreException e) {
throw new RuntimeException(e);
} catch (KeyManagementException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
Registry<ConnectionSocketFactory> registry = registryBuilder.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(registry);
HttpClientBuilder hcb = HttpClientBuilder.create();
return hcb.setConnectionManager(connManager).build();
}
public static String get(String url, Map<String,String> queries) throws IOException {
String responseBody = "";
// CloseableHttpClient httpClient=HttpClients.createDefault();
CloseableHttpClient httpClient = getHttpClient();
StringBuilder sb = new StringBuilder(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator<Map.Entry<String,String>> iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String,String> entry = (Map.Entry<String,String>) iterator.next();
if (firstFlag) {
sb.append("?" + (String) entry.getKey() + "=" + (String) entry.getValue());
firstFlag = false;
} else {
sb.append("&" + (String) entry.getKey() + "=" + (String) entry.getValue());
}
}
}
HttpGet httpGet = new HttpGet(sb.toString());
if (SetTimeOut) {
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(SocketTimeout).setConnectTimeout(ConnectTimeout).build();
httpGet.setConfig(requestConfig);
}
try {
CloseableHttpResponse response = httpClient.execute(httpGet);
int status = response.getStatusLine().getStatusCode();
if (status == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
responseBody = EntityUtils.toString(entity);
// EntityUtils.consume(entity);
} else {
System.out.println("http return status error:" + status);
throw new ClientProtocolException("Unexpected response status: " + status);
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
httpClient.close();
}
return responseBody;
}
public static String post(String url, Map<String,String> queries, Map<String,String> params, String chatset,int socketTimeout,int connectTimeout) throws IOException {
String responseBody = "";
CloseableHttpClient httpClient = getHttpClient();
StringBuilder sb = new StringBuilder(url);
if (queries != null && queries.keySet().size() > 0) {
boolean firstFlag = true;
Iterator<Map.Entry<String,String>> iterator = queries.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String,String> entry = (Map.Entry<String,String>) iterator.next();
if (firstFlag) {
sb.append("?" + (String) entry.getKey() + "=" + (String) entry.getValue());
firstFlag = false;
} else {
sb.append("&" + (String) entry.getKey() + "=" + (String) entry.getValue());
}
}
}
// 指定url,和http方式
HttpPost httpPost = new HttpPost(sb.toString());
if (SetTimeOut) {
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(socketTimeout).setConnectTimeout(connectTimeout).build();
httpPost.setConfig(requestConfig);
}
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
if (params != null && params.keySet().size() > 0) {
Iterator<Map.Entry<String,String>> iterator = params.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String,String> entry = (Map.Entry<String,String>) iterator.next();
nvps.add(new BasicNameValuePair((String) entry.getKey(), (String) entry.getValue()));
}
}
// Consts.UTF_8
httpPost.setEntity(new UrlEncodedFormEntity(nvps, chatset));
CloseableHttpResponse response = httpClient.execute(httpPost);
try {
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
HttpEntity entity = response.getEntity();
// do something useful with the response body
// and ensure it is fully consumed
responseBody = EntityUtils.toString(entity);
// EntityUtils.consume(entity);
} else {
System.out.println("http return status error:" + response.getStatusLine().getStatusCode());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
response.close();
}
return responseBody;
}
public static String post(String url, Map<String,String> queries, Map<String,String> params, String chatset) throws IOException {
return post( url, queries, params,chatset,SocketTimeout,ConnectTimeout);
}
}
从堆栈跟踪中,我们可以看到超时发生在连接建立期间,而不是数据传输期间。我想详细的原因在于其中一个:
1.正在等待池中的可用连接线程
2.无法连接到远程主机。
谁能给我一些建议?
您可以增加连接池日志记录位置org。阿帕奇。http。impl。连接=调试
https://hc.apache.org/httpcomponents-client-ga/logging.html所以,当异常发生时,您将看到池中有多少打开的连接。异常显示HttpClient尝试建立新连接,这意味着打开的连接少于池大小。
>
由于以下原因,客户端无法连接到远程主机:
这意味着池中没有活动连接。然后,您需要嗅探网络流量,以找出问题所在,正如dave_thompson_085所建议的那样。
某些防火墙/防病毒程序正在阻止客户端与服务器的连接,在这种情况下,池中可能存在连接。(如果这是请求服务器的唯一进程)
我在其中一个POJO中使用javax.validation.constraints.NotNull,如下所示: 然后,即使我为两个字段都使用 null 值制作 Abc 的对象,它也不会引发任何异常。知道为什么吗? 例如。 不会抛出任何异常。
抛出异常的行为是否可能抛出不同的异常? 为了抛出异常,必须(可选地)分配新对象,并调用其构造函数(隐式调用fillinstacktrace)。在某些情况下,听起来像addSupressed也被称为。那么如果没有足够的内存会发生什么呢?JVM是否需要预分配内置异常?例如,(1/0)会抛出OutOfMemoryError而不是ArithmeticException吗? 此外,构造函数是一个方法调用,因
我的Java代码使用共享的ApacheHttpClient 4.4。1.我将每个POST请求级别上的连接超时、套接字超时和连接请求超时设置为100毫秒。它大部分时间都很好用。然而,在大量请求(压力测试)时,HttpClient忽略这些超时;请求可能需要20秒或更长时间。这是我的密码: 在某些情况下,我会得到如下日志记录: 2018-10-26 14:18:45496[my-thread-1]调试c
我注意到,在这个javadoc中,https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.UncaughtExceptionHandler.htmlUncaughtExceptionHandler用于发生异常但未被捕获的情况。但是,那个线程会悄悄地失败吗?我想是的,因为它是异步进行业务的,但我正在调查我们的一个进程的相关问题,我很惊讶现
问题内容: 我正在尝试从服务器中获取数据。有时我的代码由于导致失败。这是为什么?这个问题是什么原因造成的? 问题答案: 如果在DNS服务器中发生了打cup,则可能会发生这种情况。除了使DNS服务器更强大或寻找另一台服务器之外,您还可以使用完整的IP地址代替主机名。这样,就无需根据主机名查找IP地址。但是,我宁愿解决DNS问题,也更喜欢DNS,因为IP地址可能会不时更改。
我使用的是SpringBoot2.2。2.发布,version 在 超时失败统计(总计=30,活动=1,空闲=29,等待=163) 有29个空闲连接,仍然发生超时故障。