programing

Node.js의 ECONNRESET 오류를 디버깅하려면 어떻게 해야 합니까?

instargram 2023. 5. 17. 22:28
반응형

Node.js의 ECONNRESET 오류를 디버깅하려면 어떻게 해야 합니까?

채팅 웹 앱으로 Socket.io 을 사용하여 Express.js 애플리케이션을 실행하고 있는데 24시간 동안 5번 정도 무작위로 다음 오류가 발생합니다.노드 프로세스는 영구적으로 래핑되고 즉시 다시 시작됩니다.

문제는 Express를 다시 시작하면 사용자가 방에서 쫓겨나고 아무도 원하지 않는다는 것입니다.

웹 서버는 HAProxy에 의해 프록시됩니다.웹 소켓 및 플래시 소켓 전송만 사용하면 소켓 안정성 문제가 없습니다.저는 이것을 일부러 재현할 수 없습니다.

은 노드 에 대한 입니다.v0.10.11:

    events.js:72
            throw er; // Unhandled 'error' event
                  ^
    Error: read ECONNRESET     //alternatively it s a 'write'
        at errnoException (net.js:900:11)
        at TCP.onread (net.js:555:19)
    error: Forever detected script exited with code: 8
    error: Forever restarting script for 2 time

EDIT (2013-07-22)

socket.io 클라이언트 오류 처리기와 탐지되지 않은 예외 처리기를 모두 추가했습니다.오류가 발생한 것 같습니다.

    process.on('uncaughtException', function (err) {
      console.error(err.stack);
      console.log("Node NOT Exiting...");
    });

그래서 저는 그것이 Socket.io 문제가 아니라 제가 하는 다른 서버에 대한 HTTP 요청이거나 MySQL/Redis 연결이라고 생각합니다.문제는 오류 스택이 코드 문제를 식별하는 데 도움이 되지 않는다는 것입니다.로그 출력은 다음과 같습니다.

    Error: read ECONNRESET
        at errnoException (net.js:900:11)
        at TCP.onread (net.js:555:19)

원인을 어떻게 알 수 있습니까?오류에서 더 많은 것을 얻으려면 어떻게 해야 합니까?

좋아요, 그렇게 장황하진 않지만, 여기 롱존에 대한 스택 추적이 있습니다.

    Exception caught: Error ECONNRESET
    { [Error: read ECONNRESET]
      code: 'ECONNRESET',
      errno: 'ECONNRESET',
      syscall: 'read',
      __cached_trace__:
       [ { receiver: [Object],
           fun: [Function: errnoException],
           pos: 22930 },
         { receiver: [Object], fun: [Function: onread], pos: 14545 },
         {},
         { receiver: [Object],
           fun: [Function: fireErrorCallbacks],
           pos: 11672 },
         { receiver: [Object], fun: [Function], pos: 12329 },
         { receiver: [Object], fun: [Function: onread], pos: 14536 } ],
      __previous__:
       { [Error]
         id: 1061835,
         location: 'fireErrorCallbacks (net.js:439)',
         __location__: 'process.nextTick',
         __previous__: null,
         __trace_count__: 1,
         __cached_trace__: [ [Object], [Object], [Object] ] } }

플래시 소켓 정책 파일을 제공합니다.

    net = require("net")
    net.createServer( (socket) =>
      socket.write("<?xml version=\"1.0\"?>\n")
      socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
      socket.write("<cross-domain-policy>\n")
      socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
      socket.write("</cross-domain-policy>\n")
      socket.end()
    ).listen(843)

이것이 원인이 될 수 있습니까?

이미 짐작하셨을 겁니다. 연결 오류입니다.

"ECONNRESET"은 TCP 대화의 다른 쪽이 갑자기 연결의 끝을 닫았다는 것을 의미합니다.이는 하나 이상의 응용 프로그램 프로토콜 오류 때문일 수 있습니다.API 서버 로그를 보고 불만 사항이 있는지 확인할 수 있습니다.

그러나 오류를 확인하고 잠재적으로 문제를 디버그할 수 있는 방법도 찾고 있으므로 유사한 질문과 관련하여 스택 오버플로 시 게시된 "NodeJS에서 소켓 중단 오류를 디버그하는 방법"을 살펴봐야 합니다.

개발을 위한 빠르고 더러운 솔루션:

longjohn을 사용하면 비동기 작업을 포함하는 긴 스택 추적을 얻을 수 있습니다.

깨끗하고 올바른 용액:기술적으로 노드에서는 이벤트를 내보내고 아무도 듣지 않을 때마다 이벤트가 던져집니다.던지지 않게 하려면 청취자를 붙여 직접 처리합니다.그러면 오류를 더 많은 정보와 함께 기록할 수 있습니다.

통화 그룹에 대해 한 명의 수신기를 사용하려면 도메인을 사용하고 런타임에 다른 오류를 탐지할 수 있습니다.http(Server/Client)와 관련된 각 비동기 작업이 코드의 다른 부분과 비교하여 다른 도메인 컨텍스트에 있는지 확인하십시오. 도메인은 자동으로 다음을 수신합니다.error이벤트를 생성하고 이를 자체 처리기로 전파합니다.따라서 해당 핸들러만 듣고 오류 데이터를 얻을 수 있습니다.또한 무료로 더 많은 정보를 얻을 수 있습니다.

EDIT (2013-07-22)

위에 쓴 것처럼:

"ECONNRESET"은 TCP 대화의 다른 쪽이 갑자기 연결의 끝을 닫았다는 것을 의미합니다.이는 하나 이상의 응용 프로그램 프로토콜 오류 때문일 수 있습니다.API 서버 로그를 보고 불만 사항이 있는지 확인할 수 있습니다.

또한 임의의 시간에 다른 쪽이 과부하가 되어 결과적으로 연결이 끊어집니다.만약 그렇다면, 정확히 어떤 것에 연결하느냐에 따라 다릅니다.

하지만 한 가지 확실한 것은 TCP 연결에 읽기 오류가 발생하여 예외가 발생한다는 것입니다.당신이 당신의 편집에 올린 오류 코드를 보면 그것을 확인할 수 있습니다.

플래시 정책 파일을 제공하기 위해 가지고 있던 간단한 tcp 서버가 원인이었습니다.이제 핸들러를 사용하여 오류를 감지할 수 있습니다.

# serving the flash policy file
net = require("net")

net.createServer((socket) =>
  //just added
  socket.on("error", (err) =>
    console.log("Caught flash policy server socket error: ")
    console.log(err.stack)
  )

  socket.write("<?xml version=\"1.0\"?>\n")
  socket.write("<!DOCTYPE cross-domain-policy SYSTEM \"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd\">\n")
  socket.write("<cross-domain-policy>\n")
  socket.write("<allow-access-from domain=\"*\" to-ports=\"*\"/>\n")
  socket.write("</cross-domain-policy>\n")
  socket.end()
).listen(843)

노드 업그레이드 후 앱 오류가 발생하기 시작한 것과 유사한 문제가 있었습니다.이 항목은 Node 릴리스 v0.9.10에서 찾을 수 있습니다.

  • net: ECONNRESET(벤 노르트휘스)을 억압하지 마십시오.

이전 버전은 클라이언트의 중단 시 오류가 발생하지 않습니다.클라이언트의 연결이 끊어지면 노드에 ECONNRESET 오류가 발생합니다.저는 이것이 노드를 위해 의도된 기능이라고 생각합니다. 그래서 (적어도 저에게는) 오류를 처리하는 것이 수정 사항이었고, 저는 당신이 발견되지 않은 예외에서 했다고 생각합니다.비록 내가 net.socket 핸들러에서 그것을 처리하지만요.

이를 입증할 수 있습니다.

간단한 소켓 서버를 만들고 Node v0.9.9 및 v0.9.10을 가져옵니다.

require('net')
    .createServer( function(socket) 
    {
           // no nothing
    })
    .listen(21, function()
     {
           console.log('Socket ON')
    })

v0.9.9를 사용하여 시작한 다음 이 서버로 FTP를 시도합니다.Windows에 있고 FTP 클라이언트가 있기 때문에 FTP 및 포트 21만 사용하고 있지만 텔넷 클라이언트는 사용할 수 없습니다.

그러면 클라이언트 쪽에서 연결을 끊으면 됩니다.(그냥 Ctrl-C를 하는 중입니다)

노드 v0.9.9를 사용하는 경우 오류가 표시되지 않으며 노드 v.0.9.10 이상을 사용하는 경우 오류가 표시됩니다.

운영 환경에서 v.0.10을 사용하는데 오류가 발생합니다.다시 말씀드리지만, 이것은 의도된 것이며 해결책은 코드의 오류를 처리하는 것입니다.

오늘도 같은 문제가 있었습니다.조사한 결과 매우 유용한 node.js 옵션을 발견했습니다.훨씬 더 상세하고 유용한 오류 스택 추적을 제공할 뿐만 아니라 응용프로그램 충돌 시 코어 파일을 저장하여 추가 디버그를 허용합니다.

또한 개발 중에 ECONNRESET 오류가 발생합니다. 제가 해결하는 방법은 서버를 시작하기 위해 demon을 사용하지 않고 그냥 사용하는 입니다."node server.js"서버를 시작하기 위해 문제를 해결했습니다.

이상하지만, 저한테는 효과가 있었어요, 이제 다시는 ECONRESET 오류를 볼 수 없습니다.

저는 같은 문제에 직면해 있었지만 다음과 같이 배치하여 완화했습니다.

server.timeout = 0;

앞에server.listen.serverHTTP 서버입니다.기본 시간 초과는 API 설명서에 따라 2분입니다.

예, 정책 파일을 제공하면 충돌이 발생할 수 있습니다.

반복하려면 코드에 지연을 추가하십시오.

net.createServer( function(socket) 
{
    for (i=0; i<1000000000; i++) ;
    socket.write("<?xml version=\"1.0\"?>\n");
…

및사를 합니다.telnet포트에 연결합니다.지연이 만료되기 전에 텔넷의 연결을 끊으면 소켓에서 충돌(확인되지 않은 예외)이 발생합니다.쓰기는 오류를 발생시킵니다.

여기서 충돌을 방지하려면 소켓을 읽고 쓰기 전에 오류 처리기를 추가하십시오.

net.createServer(function(socket)
{
    for(i=0; i<1000000000; i++);
    socket.on('error', function(error) { console.error("error", error); });
    socket.write("<?xml version=\"1.0\"?>\n");
}

위의 연결 해제를 시도하면 충돌 대신 로그 메시지가 표시됩니다.

작업이 끝나면 지연을 제거하는 것을 기억하십시오.

간 " " " " " " " " " " (" " " " " " " " " " " " " " " " " " " " " 을 설정한 수 .server.maxConnections매우 낮은 값으로

노드의 core libnet.js에서 호출됩니다.clientHandle.close()또한 ECONNRESET 오류가 발생합니다.

if (self.maxConnections && self._connections >= self.maxConnections) {
  clientHandle.close(); // causes ECONNRESET on the other end
  return;
}

ECONRESET은 서버 측에서 TCP 연결을 닫고 서버에 대한 사용자의 요청이 충족되지 않을 때 발생합니다.서버는 잘못된 연결을 참조하고 있다는 메시지로 응답합니다.

서버가 잘못된 연결로 요청을 보내는 이유는 무엇입니까?

클라이언트와 서버 간의 킵얼라이브 연결을 사용 가능으로 설정했다고 가정합니다.킵얼라이브 타임아웃은 15초로 구성됩니다.즉, 킵얼라이브가 15초 동안 유휴 상태이면 연결 닫기 요청을 전송합니다.그래서 15초 후에 서버는 클라이언트에게 연결을 닫으라고 말합니다.그러나 서버가 이 요청을 보낼 때 클라이언트는 이미 이동 중인 새 요청을 서버 끝으로 보냅니다.이 연결이 지금 유효하지 않기 때문에 서버가 ECONRESET 오류와 함께 거부합니다.따라서 서버 엔드에 대한 요청 수가 적어 문제가 발생합니다.따라서 킵얼라이브를 비활성화하면 정상적으로 작동합니다.

저도 이 오류가 있었고 며칠 동안 디버깅하고 분석한 후에 해결할 수 있었습니다.

나의 해결책

저에게 VirtualBox(도커용)는 문제였습니다.VM에 포트 포워딩이 구성되어 있는데 포워딩 포트에서만 오류가 발생했습니다.

일반적인 결론

다음과 같은 관찰을 통해 제가 투자해야 했던 업무 일수를 절약할 수 있습니다.

  • 나의 경우, 이 문제는 한 포트의 localhost에서 localhost로의 연결에서만 발생했습니다. -> 이러한 상수 중 하나를 변경하면 문제가 해결됩니다.
  • 저는 이 문제가 제 기계에서만 발생했습니다 -> 다른 사람이 시도하게 해주세요.
  • 저는 문제가 잠시 후에 발생하여 안정적으로 재현할 수 없었습니다.
  • 내 문제를 노드나 express(debug-) 도구로 검사할 수 없습니다. -> 시간 낭비하지 마십시오.

-> VM, 방화벽 등과 같은 네트워크(-설정)에 문제가 있는지 확인합니다. 이것이 문제의 원인일 수 있습니다.

저는 다른 네트워크에 연결하는 것만으로 문제를 해결했습니다.그것은 가능한 문제 중 하나입니다.

위에서 논의한 바와 같이, ECONNRESET은 TCP 대화가 갑자기 연결의 끝을 닫았다는 것을 의미합니다.

인터넷 연결로 인해 일부 서버에 연결할 수 없습니다.저의 경우 mLab(MongoDB 데이터베이스를 호스팅하는 클라우드 데이터베이스 서비스)에 연결하려고 했습니다.그리고 제 ISP가 차단하고 있습니다.

저는 다음을 통해 이 문제를 해결했습니다.

  • 와이파이/이더넷 연결을 끄고 켭니다.
  • 입력한 내용:npm update터미널에서 npm을 업데이트합니다.
  • 세션에서 로그아웃하고 다시 로그인하려고 했습니다.

그 후에도 같은 npm 명령어를 사용해 보았는데, 좋은 점은 잘 되었다는 것입니다.나는 그것이 그렇게 간단한지 확신할 수 없었습니다.

저는 센토스 7을 사용하고 있습니다.

저는 이것을 방금 알았습니다, 적어도 제 사용 사례에서는요.

나는 받고 있었습니다.ECONNRESET제 클라이언트가 설정된 방식은 API 호출로 서버를 매우 빠르게 공격하는 것으로 밝혀졌습니다. 단 한 번만 엔드포인트에 도달하면 됩니다.

제가 그것을 고쳤을 때, 오류가 사라졌습니다.

저도 같은 문제가 있었는데 Node.js 버전이 문제였던 것 같습니다.

이전 버전의 Node.js(10.14.2)를 설치했는데 nvm을 사용하여 모든 것이 정상이었습니다(여러 버전의 Node.js를 설치하고 한 버전에서 다른 버전으로 빠르게 전환할 수 있습니다).

이것은 "깨끗한" 해결책은 아니지만, 일시적으로 도움이 될 수 있습니다.

소켓에 이러한 옵션을 추가해 보십시오.io:

const options = { transports: ['websocket'], pingTimeout: 3000, pingInterval: 5000 };

이것이 당신에게 도움이 되기를 바랍니다!

노드 JS 소켓이 비차단 IO입니다.다른 소스의 비차단 io 연결을 사용하는 것을 고려합니다.예를 들어 노드에서 차단 Java 소켓을 사용하는 경우 몇 초 동안만 작동하고 이후 오류가 발생합니다.셀렉터를 사용하여 비차단 연결(예: 소켓 채널)을 구현하여 이 문제를 완화합니다.

먼저 앱을 실행하면 ECONNRESET이 되고 ECONNREFUSED와 같은 오류가 발생합니다.노드 앱을 실행하는 동안 이 두 가지 문제에 모두 직면했습니다.두 문제 모두 wampserver를 시작하지 않았기 때문에 이 문제가 발생한 것으로 나타났습니다.저는 wampserver의 도움으로 데이터를 얻기 위해 앱에서 mysql 데이터베이스를 사용하고 있습니다.wampserver를 시작한 다음 노드 앱을 실행하여 이 문제를 해결합니다.잘 작동합니다.노드 또는 노드 데몬을 사용하여 노드 응용 프로그램을 실행할 수 있습니다. 저의 경우에는 문제가 되지 않습니다.

임시 솔루션으로 시도하고 작업한 옵션이 거의 없음

  1. 노드를 사용하는 경우 다음을 사용하여 다른 노드 버전 간 전환 시도node use #version#나를 위해 일했습니다.
  2. 인터넷 연결 전환 시도

언급URL : https://stackoverflow.com/questions/17245881/how-do-i-debug-error-econnreset-in-node-js

반응형