HttpClient 및 Close_Wait
서버 B에서 netstat 명령을 실행하면 대량의 연결이 CLOSE_WAIT 상태.
문제 분석:
간단히 말해서 CLOSE_WAIT 수가 너무 많은 것은 수동적인 연결 해제 처리가 부적절하기 때문이다.
내가 말한 장면은 서버 A가 서버 B 위의apache에게 파일 자원을 요청하는 것이다. 정상적인 상황에서 요청이 성공하면 자원을 캡처한 후에 서버 A가 연결을 닫으라는 요청을 한다. 이때 연결을 닫는 것이다. 연결 상태는 우리가 볼 수 있는 TIME_WAIT.만약에 이상이 생기면요?만약 요청한 자원 서버 B에 존재하지 않는다고 가정하면 이때 서버 B가 연결을 닫는 요청을 한다. 서버 A는 연결을 수동적으로 닫은 것이다. 만약에 서버 A가 연결을 수동적으로 닫은 후에 자신이 연결을 풀지 않았다면 CLOSE_WAIT 상태입니다.
그래서 문제는 여전히 절차 안에 있다는 것이 분명하다.
원본 코드 블록:
- try
- {
- client = HttpConnectionManager.getHttpClient();
- HttpGet get = new HttpGet();
- get.setURI(new URI(urlPath));
- HttpResponse response = client.execute(get);
- if (response.getStatusLine ().getStatusCode () != 200) {
- return null;
- }
- HttpEntity entity =response.getEntity();
-
- if( entity != null ){
- in = entity.getContent();
- .....
- }
- return sb.toString ();
-
- }
- catch (Exception e)
- {
- e.printStackTrace ();
- return null;
- }
- finally
- {
- if (isr != null){
- try
- {
- isr.close ();
- }
- catch (IOException e)
- {
- e.printStackTrace ();
- }
- }
- if (in != null){
- try
- {
- <span style="color:#ff0000;">in.close ();</span>
- }
- catch (IOException e)
- {
- e.printStackTrace ();
- }
- }
- }
HttpClient는 우리가 자주 사용하는 InputStream을 사용합니다.close () 는 연결이 닫혔는지 확인하고 위의 코드를 분석합니다. 200이 아닌 연결이 나타나면 이 연결은 연결 탱크 안에서 영원히 경직됩니다. inputStream이 초기화되지 않아서 close () 방법을 사용하지 않습니다.
코드를 약간 수정하여 이상 상황을 더욱 엄밀하게 처리하면 문제를 해결할 수 있다.
- public static String readNet (String urlPath)
- {
- StringBuffer sb = new StringBuffer ();
- HttpClient client = null;
- InputStream in = null;
- InputStreamReader isr = null;
- HttpGet get = new HttpGet();
- try
- {
- client = HttpConnectionManager.getHttpClient();
- get.setURI(new URI(urlPath));
- HttpResponse response = client.execute(get);
- if (response.getStatusLine ().getStatusCode () != 200) {
- get.abort();
- return null;
- }
- HttpEntity entity =response.getEntity();
-
- if( entity != null ){
- in = entity.getContent();
- ......
- }
- return sb.toString ();
-
- }
- catch (Exception e)
- {
- get.abort();
- e.printStackTrace ();
- return null;
- }
- finally
- {
- if (isr != null){
- try
- {
- isr.close ();
- }
- catch (IOException e)
- {
- e.printStackTrace ();
- }
- }
- if (in != null){
- try
- {
- in.close ();
- }
- catch (IOException e)
- {
- e.printStackTrace ();
- }
- }
- }
- }
HttpGet을 호출하는 abort를 표시합니다. 그러면 이번 연결이 바로 중단됩니다. 이상이 발생했을 때 호출을 표시해야 합니다. 왜냐하면 이상이 InputStream in에서 값을 부여한 후에 던진 것이라고 누가 보증할 수 있기 때문입니다.
more:
우선 서버 프로그램이 CLOSE_에 있는 경우WAIT 상태라면 소켓이 수동적으로 닫힌다는 뜻입니다!
클라이언트 측이 현재 연결을 자발적으로 끊으면 쌍방이 이 TCP 연결을 닫는 데 총 4개의 패킷이 필요하기 때문이다.
Client –-> FIN –-> Server
Client <–- ACK <–- Server
Client FIN_WAIT_2 ; Server CLOSE_WAIT 。
Client <–- FIN <–- Server
Server FIN Client,Server LAST_ACK 。
Client –-> ACK –-> Server
Client ACK, Server CLOSED 。
Server 프로그램이 CLOSE_LAST_ 대신 WAIT 상태ACK 상태는 아직 클라이언트에게 FIN을 보내지 않았다는 것을 설명한다. 그러면 연결을 닫기 전에 많은 데이터를 보내거나 다른 일을 해야 하기 때문에 이 FIN 패키지를 보내지 않았을 수도 있다.
일반적으로 하나의 CLOSE_WAIT는 최소 2시간의 시간을 유지합니다. (이 시간은 외부 네트워크 서버가 일반적으로 조정합니다. 그렇지 않으면 너무 위험합니다.)만약 깡패가 특별히 프로그램을 썼다면, 너에게 CLOSE_WAIT, 소모
당신의 자원은 방출되는 순간을 기다리지 못하면 시스템이 붕괴를 해결합니다.
TCP/IP 매개 변수를 수정하여 이 시간을 단축할 수 있습니다: tcp_ 수정keepalive_*시리즈 파라미터는 이 문제를 해결하는 데 도움이 된다.
하지만 사실은 우리 프로그램 코드에 문제가 있어서,
more:
최근에 httpclient 전송 서비스를 했는데 서버에 항상 close_가 많더라고요.wait 상태의 연결, 그리고 이 연결이 닫히지 않아서 서버가 새로운 네트워크 연결을 만들 수 없어서 응답을 멈출 수 없습니다.
나중에 인터넷에서 검색해 보니 해결 방법도 간단합니다. 연결을 다시 사용하려면 연결 관리자를 사용해서 연결 관리자에서 연결을 얻고 정해진 시간에 연결 관리자로 빈 연결을 방출합니다.httpclient는 SimpleHttpConnectionManager를 자체적으로 가지고 있습니다.
Java 코드
- closeIdleConnections(long idleTimeout)
이런 방법.
링크를 다시 사용할 필요가 없다면 httpmethod에서 만들 때 http 헤더 정보를 설정하면 됩니다
Java 코드
- httpmethod.setRequestHeader("Connection", "close");
이렇게 하면 짜증나는 close_기다려.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.