Я отлаживаю одну проблему сброса соединения и мне нужна помощь.
Вот фон
Используя java версии 8, apache httpClient 4.5.2
У меня есть следующая программа, которая успешно работает на Windows 10, 7, но в конечном итоге происходит сброс соединения на виртуальной машине Azure Windows Server 2016.
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
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.util.EntityUtils;
public class TestConnectionReset
{
static PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager();
static {
connManager.setMaxTotal(10);
connManager.setDefaultMaxPerRoute(2);
}
public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException {
while (true) {
HttpClientBuilder clientBuilder = HttpClientBuilder.create();
RequestConfig config = RequestConfig.custom().setConnectTimeout(1800000).setConnectionRequestTimeout(1800000)
.setSocketTimeout(1800000).build();
clientBuilder.setDefaultRequestConfig(config);
clientBuilder.setConnectionManager(connManager);
String userName = "xxxxx";
String password = "xxxxx";
String userNamePasswordPair = String.valueOf(userName) + ":" + password;
String authenticationData = "Basic " + new String((new Base64()).encode(userNamePasswordPair.getBytes()));
HttpPost post = new HttpPost("https://url/rest/oauth/token");
Map<String, String> requestBodyMap = new HashMap<String, String>();
requestBodyMap.put("grant_type", "client_credentials");
String req = getFormUrlEncodedBodyFromMap(requestBodyMap);
StringEntity stringEntity = new StringEntity(req);
post.setEntity(stringEntity);
post.setHeader("Authorization", authenticationData);
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
CloseableHttpClient closeableHttpClient = clientBuilder.build();
HttpResponse response = closeableHttpClient.execute(post);
Header[] hs = response.getAllHeaders();
for (Header header : hs) {
System.out.println(header.toString());
}
System.out.println(EntityUtils.toString(response.getEntity()));
Thread.sleep(10*60*1000L);
}
}
public static String getFormUrlEncodedBodyFromMap(Map<String, String> formData) {
StringBuilder requestBody = new StringBuilder();
Iterator<Map.Entry<String, String>> itrFormData = formData.entrySet().iterator();
while (itrFormData.hasNext()) {
Map.Entry<?, ?> entry = (Map.Entry)itrFormData.next();
requestBody.append(entry.getKey()).append("=").append(entry.getValue());
if (itrFormData.hasNext()) {
requestBody.append("&");
}
}
return requestBody.toString();
}
}
Я использую диспетчер соединений пула httpclient.Первый запрос в первом цикле выполнения выполнен успешно, но последующая итерация цикла for со следующим запросом завершается неудачно.
Мои выводы
Если мы видим базовое сокетное соединение в Windows 10, после того, как 1-й сокет запроса переходит в состояние CLOSE_WAIT, и следующий запрос выполняется с закрытием существующего соединения и созданием новогоподключение.
Фактически сервер закрывает соединение продолжительностью 5 минут.Но Windows 10 может обнаружить его и повторно инициировать соединение при следующем запросе.
Теперь на Windows Server 2016 я вижу, что netstat показывает состояние сокета ESTABLISHED.Означает, что соединение готово к использованию, и оно подключается к тому же соединению, и, наконец, сервер уже закрыло его, что приводит к ошибке сброса соединения.
Я подозреваю, что это экологическая проблема, когда сервер 2016 сохраняет сокет ESTABLISHED даже после того, как сервер завершил его, но в Windows 10 состояние сокета изменилось на CLOSE_WAIT.
Помощь по этому вопросу очень ценится