소켓은 무엇을하는 것이 끊지? 다음에 무슨 일이 일어날 것인가?

사람의 순수한 마음, 생활은 단맛과 기쁨이 가득합니다. - 톨스토이

소켓이 표시 서비스 압력 측정 먼저 끊지 정보, 나중에 최근 Node.js를 서비스 마이그레이션 K8S 용기 Shiyou에서이 문제를보고 해결 및 발견 인해 CPU, 메모리, 크기 선박의 검증 후 때문에 제한되고, 여기에 소켓을 끊고, 해결책은 무엇 어떤 상황입니다에서 무슨 일이 있었는지의 요약입니다.

저자에 관하여 : 공유와 같은 젊은 왕 후 월 90, Nodejs 개발자, 인증의 뮤 클래스 네트워크, 사랑의 기술, 관심을 지불하시기 바랍니다 Nodejs 기술 스택 과 오픈 소스 프로젝트 Github에서이 www.nodejs.red

소켓 끊지 위로는 무엇입니까

여기에 또한 질문을 면접 질문로 사용할 수 있습니다, 소켓은 무엇을 끊고있다?

끊고, 의미가 영어로 번역 끊지 삭제 그것은 또한 소켓 (링크)로 이해 될 수있다 끊으 소켓. 이는 이유에 대해 생각해야한다면 아마도 더 많거나 적은이 충족됩니다 사용에 언어에 상관없이, 그냥 몰라? 예를 들어, Node.js를 시스템에 서버 기본 시간 초과가 요청이 시간을 초과하는 경우 클라이언트가 요청을 반환하고자 할 때, HTTP 서버가이 요청 링크를 종료합니다 (server.timeout 볼 수) 2 이분 http로 제공 소켓이 있었다 "끊어"것을 발견 오류를 끊지 소켓을보고됩니다.

질문을 이해하거나 문제를 재현하는 작은 데모에서 다음과 같은 연습을 원하고 그 무슨 소켓 요령에 대해 더 배우고 Node.js를 HTTP 관련 소스 코드와 결합 하는가? 이 문제에 대한 논의가있다, 당신은 위의 모든 스택 오버 플로우를 보면 추천도있다 stackoverflow.com/questions/1이 ... .

재현 소켓 끊지 최대

서버

삼초 후 HTTP 서비스 정의 / 타임 아웃 지연 응답 인터페이스 설정 열기

const http = require('http');
const port = 3020;

const server = http.createServer((request, response) => {
    console.log('request url: ', request.url);

    if (request.url === '/timeout') {
        setTimeout(function() {
            response.end('OK!');
        }, 1000 * 60 * 3)
    }
}).listen(port);

console.log('server listening on port ', port);
复制代码

클라이언트

const http = require('http');
const opts = {
  hostname: '127.0.0.1',
  port: 3020,
  path: '/timeout',
  method: 'GET',
};

http.get(opts, (res) => {
  let rawData = '';
  res.on('data', (chunk) => { rawData += chunk; });
  res.on('end', () => {
    try {
      console.log(rawData);
    } catch (e) {
      console.error(e.message);
    }
  });
}).on('error', err => {
  console.error(err);
});
复制代码

다음과 같은 오류를보고 할 서버 죽일 직접이 이분에 대해 클라이언트를 다시 시작하거나 후 서버를 시작한 후 해당 오류 스택을 볼 수 있습니다

Error: socket hang up
    at connResetException (internal/errors.js:570:14)
    at Socket.socketOnEnd (_http_client.js:440:23)
    at Socket.emit (events.js:215:7)
    at endReadableNT (_stream_readable.js:1183:12)
    at processTicksAndRejections (internal/process/task_queues.js:80:21) {
  code: 'ECONNRESET'
}
复制代码

이 말은 오류를 끊으 소켓보고됩니다 왜 HTTP 클라이언트, Node.js를 HTTP 코드가 어떤 반응을 얻고 없습니다 인해를 찾을 수 클라이언트 서버 소스가 다음 소켓이 종료 된 것으로, ( '소켓 요령에 L440의 connResetException를 트리거 보면 최대 ') 오류입니다.

// https://github.com/nodejs/node/blob/v12.x/lib/_http_client.js#L440

function socketOnEnd() {
  const socket = this;
  const req = this._httpMessage;
  const parser = this.parser;

  if (!req.res && !req.socket._hadError) {
    // If we don't have a response then we know that the socket
    // ended prematurely and we need to emit an error on the request.
    req.socket._hadError = true;
    req.emit('error', connResetException('socket hang up'));
  }
  if (parser) {
    parser.finish();
    freeParser(parser, req, socket);
  }
  socket.destroy();
}
复制代码

해결 끊지 소켓

1 세트는 HTTP 서버 소켓 타임 아웃

서버가 2 분이면 시간 제한이 소켓이 자동으로 파괴 될 경우 수신 0 경우, server.setTimeout를 호출하여 시간 제한 많은 수를 조정할 수 있습니다 (밀리 초),,, 방법을 기본 시간 제한을 다음과 Node.js를 HTTP 서버의 소스 코드를 참조하십시오 시간 제한 메커니즘 해제

// https://github.com/nodejs/node/blob/v12.x/lib/_http_server.js#L348
function Server(options, requestListener) {
  // ...

  this.timeout = kDefaultHttpServerTimeout; // 默认为 2 * 60 * 1000
  this.keepAliveTimeout = 5000;
  this.maxHeadersCount = null;
  this.headersTimeout = 40 * 1000; // 40 seconds
}
Object.setPrototypeOf(Server.prototype, net.Server.prototype);
Object.setPrototypeOf(Server, net.Server);


Server.prototype.setTimeout = function setTimeout(msecs, callback) {
  this.timeout = msecs;
  if (callback)
    this.on('timeout', callback);
  return this;
};
复制代码

수정 된 코드는 아래에 도시된다 :

const server = http.createServer((request, response) => {
    console.log('request url: ', request.url);

    if (request.url === '/timeout') {
        setTimeout(function() {
            response.end('OK!');
        }, 1000 * 60 * 3)
    }
}).listen(port);

server.setTimeout(0); // 设置超时时间
复制代码

당신이 설정되지 않은 경우의 setTimeout이 오류 확률의 많은 해당 서비스가 조사 과정을 것입니다 매우 느린 및 기타 비정상적인 문제가있는 경우, 재 시도를 시작하는 큐의 클라이언트 HTTP에서이 잘못된 끝 캡처 수행 할 수있다.

ECONNRESET VS ETIMEDOUT

ECONNRESET 및 ETIMEDOUT의 차이를 말할 여기 있습니다

ECONNRESET는 타임 아웃을 읽어 : 서버가 { "ECONNRESET" "코드"느린 발생 일반적으로 응답하지 때, } , 예를 들어, 오류 소켓 예를 들어 위에서 설명한 끊습니다.

ETIMEDOUT 링크에 대한 시간 제한 , 타임 아웃을 설정하는 상기 링크 수단은 상기 클라이언트와 예를 요청하기위한 요청 모듈 다음 원격 서버에서 발생한다.

const request = require('request');

request({
  url: 'http://127.0.0.1:3020/timeout',
  timeout: 5000,
}, (err, response, body) => {
  console.log(err, body);
});
复制代码

에러 스택은 다음과 같은 경우 : 위 예 후 5 초 지속 기간에 대해 { 'ETIMEDOUT'는 코드}보고한다 :

Error: ETIMEDOUT
    at Timeout._onTimeout (/Users/test/node_modules/request/request.js:677:15)
    at listOnTimeout (internal/timers.js:531:17)
    at processTimers (internal/timers.js:475:7) {
  code: 'ETIMEDOUT'
}
复制代码

추천

출처juejin.im/post/5de0ddbf51882523467752b8