>웹 프론트엔드 >JS 튜토리얼 >6년간 존재했던 원사 버그를 기록하고 분석

6년간 존재했던 원사 버그를 기록하고 분석

青灯夜游
青灯夜游앞으로
2022-11-04 19:29:421575검색

6년간 존재했던 원사 버그를 기록하고 분석

최근 원사 버그를 발견했는데 6년째 존재하고 있는 걸 발견했습니다. 몇 가지 분석과 조사를 거쳐 6가지 해결책을 제시했습니다. . .

1. 문제 설명

최근 제가 맡은 여러 프로젝트의 패키지 관리자는 yarn@v1.22.19입니다. 종속성 설치 후 성공 여부에 관계없이 네트워크 연결이 됩니다. 문제는 항상 발생하고 발생합니다. 카드가 오랫동안 멈춰 있으면 다음과 같은 여러 줄의 예외 로그가 나타납니다. 정보 네트워크 연결에 문제가 있는 것 같습니다... . 6년간 존재했던 원사 버그를 기록하고 분석yarn@v1.22.19,在安装依赖后无论是否成功,总是出现网络连接问题而且会卡很长时间,然后会出现几行这样的异常日志:info There appears to be trouble with your network connection. Retrying...6년간 존재했던 원사 버그를 기록하고 분석

有时一些神奇的包(比如 node-sass)出现异常会导致安装失败,结果卡了半天才发现失败,真的让人很崩溃。另外在yarngithub 仓库中有数十条相关的 issue,时间跨度从2016年到2022年足足6年,原因和方案众说纷纭。我很好奇这到底是个什么神奇的问题居然6年都没解决,因此决定一探究竟。【相关教程推荐:nodejs视频教程 、编程视频

6년간 존재했던 원사 버그를 기록하고 분석

2、问题排查

2.1、关键词搜索

2.1.1、搜索 github

碰到没啥思路的问题和报错,第一技巧是搜它。在yarngithub 仓库中搜索报错信息 There appears to be trouble with your network connection,可以看到结果中有1个相关代码和91个相关 issue。在 issue 里找了一会没找到合适的方案,接着进入下一步:搜索代码。6년간 존재했던 원사 버그를 기록하고 분석

2.1.2、搜索代码

由于网络原因这里直接转到本地 yarn 的安装目录进行查找。用 vscode 打开 yarn 的安装目录(我的本地目录是~/.volta/tools/image/yarn/1.22.19),全局搜索关键词 There appears to be trouble with your network connection。可以看到结果同样只有1个,整串错误信息赋值给了一个变量offlineRetrying6년간 존재했던 원사 버그를 기록하고 분석

全局搜索关键词offlineRetrying 共2处结果,除去上一步的结果只有1处引用。这里的代码主要是抛出异常和重试,没有更多关键词可以挖掘。接下来进入调试环节,在 offlineRetrying 这行代码前面打个断点,调试看看具体错误信息和上下文。6년간 존재했던 원사 버그를 기록하고 분석

2.2、程序调试

2.2.1、确定调试命令

安装依赖需要运行命令 yarn, 那要怎么调试它呢?yarn 是一个 npm 包,执行时实际是调用 node xxx.js,而这个 xxx.js 一般配置在 package.jsonbin 字段中。从下图可以看到 yarn 对应的文件是 ./bin/yarn.js,所以可以使用这行调试命令:node --inspect-brk ~/.volta/tools/image/yarn/1.22.19/bin/yarn.js。(关于 Node.js 的调试可以参考官方文档6년간 존재했던 원사 버그를 기록하고 분석

2.2.2、开始调试

先在变量 offlineRetrying 所在的代码行cli.js:66099때때로 마법같은 An 패키지(예: node-sass)에 이상이 있으면 설치에 실패하게 되며, 결과적으로 오류가 발견되기까지 오랜 시간 동안 설치가 중단되어 정말 답답합니다. 또한 yarngithub 웨어하우스에는 2016년부터 2022년까지 6년 동안 수십 개의 관련 문제가 있으며 그 이유와 솔루션 의견은 다양합니다. 6년 동안 풀리지 않았던 이것이 어떤 마법의 문제인지 너무 궁금해서 알아보기로 했습니다. [권장 관련 튜토리얼: nodejs 동영상 튜토리얼, 프로그래밍 비디오 6년간 존재했던 원사 버그를 기록하고 분석

🎜6년간 존재했던 원사 버그를 기록하고 분석🎜

🎜2. 문제 해결🎜🎜

🎜2.1. 키워드 검색🎜

🎜2.1.1. github 검색🎜

🎜 아이디어도 없이 문제와 오류가 발생했는데, 1장 비결은 그것을 검색해 보세요. yarngithub 저장소에서 네트워크 연결에 문제가 있는 것 같습니다라는 오류 메시지를 검색해 보면 해당 항목이 1개 있는 것을 확인할 수 있습니다. 결과의 코드 및 91 관련 문제. 문제에서 잠시 검색했지만 적합한 해결 방법을 찾지 못해 다음 단계인 코드 검색으로 진행했습니다. 6년간 존재했던 원사 버그를 기록하고 분석🎜

🎜2.1.2. 코드 검색🎜

🎜네트워크상의 이유로 로컬 yarn 설치 디렉터리로 직접 이동하여 검색하세요. vscode를 사용하여 yarn의 설치 디렉터리를 엽니다(내 로컬 디렉터리는 ~/.volta/tools/image/yarn/1.22.19입니다). , 글로벌 검색 키워드 네트워크 연결에 문제가 있는 것 같습니다. 결과도 하나뿐이고 전체 오류 메시지가 offlineRetrying 변수에 할당되어 있음을 알 수 있습니다. 6년간 존재했던 원사 버그를 기록하고 분석🎜🎜전체 검색 키 offlineRetrying이라는 단어에 대한 결과가 2개 있습니다. 이전 단계의 결과를 제외하면 참조는 1개뿐입니다. 여기의 코드는 주로 예외와 재시도를 발생시키며, 더 이상 알아낼 키워드가 없습니다. 그런 다음 디버깅 프로세스에 들어가서 offlineRetrying 코드 줄 앞에 중단점을 놓고 디버그하여 특정 오류 메시지와 컨텍스트를 확인합니다. 6년간 존재했던 원사 버그를 기록하고 분석🎜

🎜2.2. 프로그램 디버깅🎜

🎜2.2.1 디버깅 명령 결정🎜

🎜종속성을 설치하려면 다음을 실행해야 합니다. yarn 명령, 어떻게 디버깅하나요? yarnnpm 패키지입니다. 실행되면 실제로 node xxx.js를 호출하고 이 xxx.js는 일반적으로 package.jsonhref="https://docs.npmjs.com/cli/v6/configuring-npm/package-json#bin" target="_blank">bin🎜에 구성되어 있습니다. 코드> 필드에 있습니다. 아래 그림에서 볼 수 있듯이 <code>yarn의 해당 파일은 ./bin/yarn.js이므로 다음 디버깅 명령 줄을 사용할 수 있습니다. 노드 --inspect-brk ~/.volta/tools/image/yarn/1.22.19/bin/yarn.js. (Node.js 디버깅에 대해서는 공식 문서🎜)6년간 존재했던 원사 버그를 기록하고 분석 🎜

🎜2.2.2. 디버깅 시작🎜

🎜먼저 offlineRetrying 변수가 있는 코드 줄로 이동합니다. cli .js:66099 앞에 🎜debugger🎜 문을 추가하세요. 🎜🎜

그런 다음 비즈니스 프로젝트의 루트 디렉터리로 돌아가 디버깅 명령 node --inspect-brk ~/.volta/tools/image/yarn/1.22.19/bin/yarn.js를 실행합니다. . 이때 프로그램은 디버깅 도구가 연결되기를 기다리며 멈추고 다음 로그를 출력합니다:  6년간 존재했던 원사 버그를 기록하고 분석node --inspect-brk ~/.volta/tools/image/yarn/1.22.19/bin/yarn.js。此时程序挂起等待调试工具连接,并打印出以下日志:6년간 존재했던 원사 버그를 기록하고 분석

接着打开 chrome 内置的调试页面 chrome://inspect/#devices,找到文件路径相同的 Target,点击 inspect按钮开始调试。

6년간 존재했던 원사 버그를 기록하고 분석

接着 chrome 会打开一个独立的 DevTools 窗口,由于使用的是 node --inspect-brk 命令,此时 DevTools 自动断点在被调试文件的起始位置,需要按下 F8 跳过该断点继续执行。6년간 존재했던 원사 버그를 기록하고 분석

等待一小段时间后,DevTools 停在之前添加的断点处,可以看到这是一个超时异常,导致异常的请求是GET: https://yarnpkg.com/latest-version。使用 curl 请求这个链接,结果是 210s 超时。使用代理访问这个链接可以成功,但是请求被重定向到 classic.yarnpkg.com/latest-vers…,其返回结果是 1.22.196년간 존재했던 원사 버그를 기록하고 분석

至此问题基本清楚了,主要是请求超时并且多次重试导致了文章开头的问题,可以使用代理规避这个问题。如果排查到此结束就没意思了。

2.2.3、深入排查

为了进一步了解 yarn 为什么要请求 yarnpkg.com/latest-vers…,以该链接为关键词在代码中搜索,找到了这个关键词链条:https://yarnpkg.com/latest-version -> SELF_UPDATE_VERSION_URL ->  _checkUpdate -> checkUpdate,实际调用关系则正好相反,具体如下图:

6년간 존재했던 원사 버그를 기록하고 분석

6년간 존재했던 원사 버그를 기록하고 분석

6년간 존재했던 원사 버그를 기록하고 분석

3、确定原因

前面已经推断出超时链接的调用关系是: checkUpdate ->  _checkUpdate  ->  SELF_UPDATE_VERSION_URL -> https://yarnpkg.com/latest-version,再结合 checkUpdate函数的注释和代码来看,每次执行 yarn 安装命令的时候都会请求 yarnpkg.com/latest-vers…,从而检查是否有新版本需要更新。但是这个链接访问超时而且失败后会重试,默认的超时时间为 30s 重试次数为 4 次,所以安装完成后还会卡 120s 程序才会真正结束。

4、解决方案

引发问题的关键因素有3个:检查更新、超时、重试,因此可以从优化网络、调整超时时间、跳过检查更新3个方向去解决问题,以下有6个解决方案可以参考。

4.1、优化网络

这个思路很容易想到,既然访问超时,那就提升请求速度。

  • 【方案1】使用代理优化网络(推荐)
$ yarn install --proxy "http://{domain}:{port}" --https-proxy "http://{domain}:{port}"

以我的开发环境举例,命令长这样:

yarn install --proxy "http://10.180.55.191:7890" --https-proxy "http://10.180.55.191:7890"

4.2、调整超时时间

这个思路比较直接,适用场景更多些,如果其他方法不奏效可以试试。

  • 【方案2】修改 network-timeout(看情况)

默认超时时间为 30s 可以改小为 2s,修改后异常依然存在,但是可以让检查更新快速失败不用等几分钟。

yarn install --network-timeout 2000

有一部分开发者表示出现异常是因为某些大型 npm 包安装太久超过了默认超时时间 30s,因此也可以把network-timeout 改得更大避免异常。

4.3、跳过检查更新

这个思路的解决方案主要来自 checkUpdate

그런 다음 chrome 내장 디버깅 페이지 chrome://inspect/#devices를 엽니다. 대상을 찾은 후 검사 버튼을 클릭하여 디버깅을 시작하세요. 🎜🎜6년간 존재했던 원사 버그를 기록하고 분석🎜🎜계속 chrome은 독립적인 DevTools 창을 엽니다. node --inspect-brk 명령이 사용되므로 DevTools는 code> 자동 중단점은 디버깅 중인 파일의 시작 부분에 있습니다. 중단점을 건너뛰고 실행을 계속하려면 F8을 눌러야 합니다. 6년간 존재했던 원사 버그를 기록하고 분석🎜🎜기다려주세요 잠시 후 DevTools가 이전에 추가된 중단점에서 중지됩니다. 예외를 발생시킨 요청은 GET: https://yarnpkg.com/입니다. 최신 버전 . curl을 사용하여 이 링크를 요청하면 210초 시간 초과가 발생합니다. 프록시를 사용하여 이 링크에 액세스하면 성공하지만 요청이 classic.yarnpkg.com/latest-vers…, 반환 결과는 1.22.19입니다. 6년간 존재했던 원사 버그를 기록하고 분석🎜🎜지금까지 문제는 기본적으로 이 문서의 시작 부분에 있는 문제가 주로 요청 시간 초과 및 여러 번의 재시도 때문에 발생한다는 것이 분명합니다. 이 문제를 방지하려면 프록시를 사용할 수 있습니다. 여기서 조사가 끝나면 지루할 것 같다. 🎜

2.2.3, 심층 조사

🎜 yarnyarn에서 요청해야 하는 이유를 더 자세히 이해하기 위해 yarnpkg.com/latest-vers…
, 이 링크를 키워드로 사용하여 코드에서 검색한 결과 다음과 같습니다. 키워드 체인: https://yarnpkg.com/latest-version -> SELF_UPDATE_VERSION_URL -> , 실제 호출 관계는 아래와 같이 정반대입니다. 🎜🎜6년간 존재했던 원사 버그를 기록하고 분석🎜🎜6년간 존재했던 원사 버그를 기록하고 분석🎜🎜이미지. png🎜

3. 이유 파악

🎜이미 호출 관계가 다음과 같이 추론되었습니다. 시간 초과 링크는 checkUpdate -> SELF_UPDATE_VERSION_URL -> version을 입력한 다음 와 결합합니다. checkUpdate 함수의 주석 및 코드로 판단하면 yarnpkg.com/latest-vers…에서 업데이트해야 할 새 버전이 있는지 확인하세요. 그러나 이 링크 액세스는 시간 초과되어 실패 후 다시 시도됩니다. 기본 시간 초과는 30초이고 재시도 횟수는 4회이므로 설치가 완료된 후에도 프로그램이 실제로 종료되기 전까지 120초 동안 계속 정체됩니다. 🎜

4. 해결 방법

🎜문제를 일으키는 세 가지 주요 요소는 업데이트 확인, 시간 초과, 최적화를 위한 재시도입니다. 문제를 해결하는 방법에는 네트워크, 시간 초과 조정, 업데이트 확인 건너뛰기 등 세 가지가 있습니다. 참고할 수 있는 해결 방법은 다음과 같습니다. 🎜

4.1. 네트워크 최적화

🎜이 아이디어는 액세스 시간이 초과되므로 생각하기 쉽습니다. 🎜
  • [옵션 1] 프록시를 사용하여 네트워크 최적화(권장)
$ yarn config set disable-self-update-check true$ yarn install
🎜 내 개발 환경을 예로 들면 명령은 다음과 같습니다. 🎜
$ yarn config set lastUpdateCheck 1e13
$ yarn install

4.2 시간 제한 조정

🎜이 아이디어는 비교적 간단하며 더 많은 시나리오에 적용할 수 있습니다. 🎜
  • [옵션 2] 네트워크 시간 초과 수정(상황에 따라 다름)
🎜기본 시간 초과는 30초이며 2초로 변경할 수 있습니다. 수정 후에도 예외가 여전히 존재합니다. 하지만 업데이트는 확인할 수 있습니다. 몇 분을 기다리지 않고 빠르게 실패합니다. 🎜
$ yarn install --non-interactive
🎜일부 개발자는 일부 대형 npm 패키지가 너무 오랫동안 설치되어 기본 시간 초과인 30초를 초과하여 예외가 발생했다고 말했습니다. 따라서 네트워크 시간 초과도 a로 변경할 수 있습니다. 예외를 방지하려면 더 큰 값을 사용하세요. 🎜

4.3. 업데이트 확인 건너뛰기

🎜이 아이디어에 대한 해결책은 주로 checkUpdate에서 나옵니다. > 기능의 여러 종료 조건. 🎜
  • 【方案3】修改配置禁止检查更新(推荐)
$ yarn config set disable-self-update-check true$ yarn install
  • 【方案4】修改配置把上次更新时间调到百年后(推荐)
$ yarn config set lastUpdateCheck 1e13
$ yarn install
  • 【方案5】执行命令时禁用交互式提示(推荐)
$ yarn install --non-interactive
  • 【方案6】修改代码跳过检查更新(不推荐)
    • 找到 yarn 的安装目录注释 checkUpdate 的调用,具体代码行为 cli.js:7261,修改后长这样:// this.checkUpdate();
    • 也可以修改其他可以阻断 checkUpdate 函数的代码...

5、最后

以上主要是分享一些问题分析排查的经验,另外也提供了一些 yarn install 超时异常的解决方案,希望能对前端同学们有所帮助。

在快写完这篇文章的时候,yarnpkg.com/latest-vers… 已经可以正常访问,不知道还会不会有人再遇到这个问题。

另外我在 yarngithub issue 中回复了以上的解决方案,希望前端同学们少受点折磨,也希望官方早点修复这个6年陈的老Bug。?

更多编程相关知识,请访问:编程教学!!

위 내용은 6년간 존재했던 원사 버그를 기록하고 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제