解决Chrome 浏览器ERR_INSUFFICIENT_RESOURCES过程

这篇具有很好参考价值的文章主要介绍了解决Chrome 浏览器ERR_INSUFFICIENT_RESOURCES过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、背景

二、下载编译工具depot_tools

三、下载Chromium源码        

四、分析Chromium代码并加日志

四、编译Chrome

五、定位问题

六、解决方案

七、踩坑记录


一、背景

最近公司客服同事经常反馈每到下午四点以后chrome浏览器经常会出现ERR_INSUFFICIENT_RESOURCES 异常,导致客服系统无法正常工作。主要特征就是新打开Tab时会报这个异常,在原来的tab内可以正常的使用。清理一下浏览器缓存,过不了多久还会出现。这个问题我们团队的前端小伙伴也没有遇到过,所以我们在网上也找了很多相关资料,发现有一个篇博客遇到的场景和我们遇到的场景较为相似,因此我们沿着这个思路尝试定位了一下,最终验证了是相同的问题,接下来我把整个的定位和解决的过程描述一下,希望对遇到相关问题的同学有所帮助。

二、下载编译工具depot_tools

       (在下载chrome源码时,确保能正常的访问google) deptool是下载和编译chromium的工具。使用git把deptool工具克隆到本地:

git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

此时fetch、gclient等命令行工具其实已经可以通过绝对路径访问并执行了,不过为了后续操作方便,可以将其加入到PATH中

export PATH="$PATH:/path/to/depot_tools"

完成后,在命令行里测试下 fetch 命令是否可用:

which fetch

三、下载Chromium源码         

因为 gclient、fetch等工具核心下载代码的过程也是依赖于git的,所以有如下git全局设置建议调整下:

git config --global http.postBuffer 524288000
git config --global core.precomposeUnicode true

因为chrommium项目历史悠久,git仓库巨大无比,为更快的完成下载代码,可以忽略历史提交代码的方式拉取能够加快速度。

fetch --no-history chromium

如果拉取失败可以执行以下命令继续拉取,此命令支持断点续传。

gclient sync

四、分析Chromium代码并加日志

用VS打开Chromium/src/services目录,该目录是chrome的基础的系统服务层。搜索ERR_INSUFFICIENT_RESOURCES,发现有100多处,我们发现在services/network/url_loader_factory.cc中有如下代码

void URLLoaderFactory::CreateLoaderAndStartWithSyncClient(
    mojo::PendingReceiver<mojom::URLLoader> receiver,
    int32_t request_id,
    uint32_t options,
    const ResourceRequest& resource_request,
    mojo::PendingRemote<mojom::URLLoaderClient> client,
    base::WeakPtr<mojom::URLLoaderClient> sync_client,
    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) {
 
  // 省略前面代码
  
  bool exhausted = false;
  if (!context_->CanCreateLoader(params_->process_id)) {
    exhausted = true;
  }

  int keepalive_request_size = 0;
  if (resource_request.keepalive && keepalive_statistics_recorder) {
    const size_t url_size = resource_request.url.spec().size();
    size_t headers_size = 0;

    net::HttpRequestHeaders merged_headers = resource_request.headers;
    merged_headers.MergeFrom(resource_request.cors_exempt_headers);

    for (const auto& pair : merged_headers.GetHeaderVector()) {
      headers_size += (pair.key.size() + pair.value.size());
    }

    keepalive_request_size = url_size + headers_size;

    const auto& top_frame_id = *params_->top_frame_id;
    const auto& recorder = *keepalive_statistics_recorder;

    if (!exhausted) {
      if (recorder.num_inflight_requests() >= kMaxKeepaliveConnections ||
          recorder.NumInflightRequestsPerTopLevelFrame(top_frame_id) >=
              kMaxKeepaliveConnectionsPerTopLevelFrame ||
          recorder.GetTotalRequestSizePerTopLevelFrame(top_frame_id) +
                  keepalive_request_size >
              kMaxTotalKeepaliveRequestSize) {
                LOG(ERROR) << "url_loader_factory.cc>>>>CreateLoaderAndStartWithSyncClient>>keepalive_request_size:" << keepalive_request_size
                 << "kMaxTotalKeepaliveRequestSize" << kMaxTotalKeepaliveRequestSize << "recorder.num_inflight_requests()" << recorder.num_inflight_requests()
                 << "kMaxKeepaliveConnections" << kMaxKeepaliveConnections << "recorder.NumInflightRequestsPerTopLevelFrame(top_frame_id) " << recorder.NumInflightRequestsPerTopLevelFrame(top_frame_id)
                 << kMaxKeepaliveConnectionsPerTopLevelFrame << kMaxKeepaliveConnectionsPerTopLevelFrame << " recorder.GetTotalRequestSizePerTopLevelFrame(top_frame_id) + keepalive_request_size " 
                 << recorder.GetTotalRequestSizePerTopLevelFrame(top_frame_id) + keepalive_request_size ;
        exhausted = true;
      }
    }
  }

  if (exhausted) {
    //新增日志便于测试
    LOG(ERROR) << "url_loader_factory.cc>>>>ERR_INSUFFICIENT_RESOURCES";
    URLLoaderCompletionStatus status;
    status.error_code = net::ERR_INSUFFICIENT_RESOURCES;
    status.exists_in_cache = false;
    status.completion_time = base::TimeTicks::Now();
    mojo::Remote<mojom::URLLoaderClient>(std::move(client))->OnComplete(status);
    return;
  }

  //省略后面代码
}

分析services/network/url_loader_factory.cc的CreateLoaderAndStartWithSyncClient方法发现,当exhausted=true时,会抛出ERR_INSUFFICIENT_RESOURCES异常。我们继续查看是在什么场景下exhausted=true。


bool NetworkContext::CanCreateLoader(uint32_t process_id) {
  auto it = loader_count_per_process_.find(process_id);
  uint32_t count = (it == loader_count_per_process_.end() ? 0 : it->second);
  //新增日志便于测试
  LOG(ERROR) << "network_context.cc>>>>CanCreateLoader>>count" << count << "process_id:" << process_id;
  return count < max_loaders_per_process_;
}
  // A count of outstanding requests per initiating process.
  //每一个初始化进程所能承受的最大未完成的请求数。
  std::map<uint32_t, uint32_t> loader_count_per_process_;

  // static constexpr uint32_t kMaxOutstandingRequestsPerProcess = 2700;
  //便于复现问题将数值调整为100=================================================
  static constexpr uint32_t kMaxOutstandingRequestsPerProcess = 100;
  uint32_t max_loaders_per_process_ = kMaxOutstandingRequestsPerProcess;

services/network/network_context.cc的CanCreateLoader方法会根据相同process_id

下的count是否大于kMaxOutstandingRequestsPerProcess的值(默认值为2700),来决定exhausted的值,为了便于复现问题,我把它调整成了100。同时我也加入了相应的日志。

四、编译Chrome

Google的C++项目大多使用ninja这样一个跨平台的编译工具,在mac端ninja底层会调用苹果公司的clang编译器。

由于ninja的编译参数较为复杂,Google又提供了gn 这样一个工具用于 根据当前系统环境生成合适的ninjaFile,此后使用autoninja进行编译时就不用设置任何参数了,直接基于ninjaFile配置文件进行编译。

具体过程如下:

gn gen out/Default

现在会在out目录下生成编译Chrome所需的一系列参数和配置,然后开始编译(整个过程大概耗时8个小时左右,这个取决于电脑配置):

autoninja -C out/Default chrome

编译完成后,你会看到在out目录下出现了 ./out/Default/Chromium.app/Contents/MacOS/Chromium 这样一个可执行文件。

为了能够查看加入的日志,需要使用命令行启动并加上--enable-logging参数

/个人文件目录/chromium/src/out/Default/Chromium.app/Contents/MacOS/Chromium  --enable-logging

这样操作chrome时就会输出相应的日志。

五、定位问题

[38514:19971:1103/151157.874646:ERROR:network_context.cc(915)] network_context.cc>>>>LoaderCreated>>process_id:0 count>>101
[38514:19971:1103/151157.875321:ERROR:url_loader_factory.cc(182)] url_loader_factory.cc>>>>CreateLoaderAndStartWithSyncClient>>url:https://content-autofill.googleapis.com/v1/pages/ChNDaHJvbWUvMTA5LjAuNTM4MS4wEjMJBAwQwvyO8h4SBQ2RYZVOEgUNkWGVThIFDZFhlU4SBQ2BkPF8EgUNgZDxfBIFDZFhlU4SEAkcC8bFxOA28RIFDQbtu_8=?alt=proto
[38514:19971:1103/151157.875475:ERROR:network_context.cc(933)] network_context.cc>>>>CanCreateLoader>>count101process_id:0
[38514:19971:1103/151157.875565:ERROR:url_loader_factory.cc(263)] url_loader_factory.cc>>>>ERR_INSUFFICIENT_RESOURCES
[38514:19971:1103/151157.876158:ERROR:network_context.cc(926)] network_context.cc>>>>LoaderDestroyed>>process_id:0 count>>100

分析发现每次创建新tab时,都会触发process_id:0 的进程,因为前端项目中用到了autofill功能,会不断的触发https://content-autofill.googleapis.com/v1/pages的请求,而本机又无法访问google,会导致process_id:0 的进程中未完成的请求数一直在累加,而我们公司的客服系统会持续工作8个小时往上。这就导致了当每次开启新的tab时会先执行process_id:0 进程的校验逻,进而导致了前面代码中的exhausted=true,但我们再次打开新的tab无论访问任何网站都会抛出ERR_INSUFFICIENT_RESOURCES这个异常。

六、解决方案

我采用的方案是在本地配置host,将*.googleapis.com域名指向了127.0.0.1,这样.googleapis.com的请求会快速结束,进而不会触发chrome的阈值, 进而避免了exhausted=true的情况,后续再也没有收到客服团队反馈相关的问题。

七、踩坑记录

1.如果开启了科学上网,仍然无法拉取代码
fatal: unable to access 'https://chromium.googlesource.com/chromium/tools/depot_tools.git/': Failed to connect to chromium.googlesource.com port 443 after 75123 ms: Operation timed out

 export https_proxy=http://127.0.0.1:7890
 export http_proxy=http://127.0.0.1:7890

2.在克隆大型git仓库时出现问题:

error: RPC failed; curl 18 transfer closed with outstanding read data remain

(错误:RPC失败;curl 18传输已关闭,但仍有未完成的读取数据)

经查原因是curl的postBuffer的默认值太小,我们需要在终端重新配置大小:

//设置全局http.postBuffer为200M,即2000x1024x1024=2097152000 bite
//(如果目标实在大于200M,自行根据实际需求更改)
git config --global http.postBuffer 209715200000
//改完后可查看现有git私有配置列表确定是否成功
git config --list
 

参考:分享一次替Boss直聘企业端Debug的经历 - 知乎

Mac上本地编译Chrome浏览器踩坑笔记(2021.02最新) - 知乎文章来源地址https://www.toymoban.com/news/detail-785032.html

到了这里,关于解决Chrome 浏览器ERR_INSUFFICIENT_RESOURCES过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 解决“您的Chrome 浏览器由组织或机构管理”问题

    Chrome被恶意软件劫持后会出现“您的Chrome 浏览器由组织或机构管理”,表现部分设置为不可用。 解决的办法是根据官方文档:(https://support.google.com/chrome/a/answer/9844476?hl=zh-Hans ) Windows: 1、删除注册表项: HKEY_CURRENT_USERSoftwareGoogleChrome HKEY_CURRENT_USERSoftwarePoliciesGoogleChr

    2024年02月05日
    浏览(48)
  • 解决:VS Code 设置默认打开浏览器 Chrome

    在 VSCode 编辑器中,一般默认打开的浏览器是 Edge 浏览器,而我一般使用 Chrome 浏览器,以及会遇到页面的调试等不同的问题,因此需要将 VSCode 的默认浏览器调整为 Chrome 浏览器; 1.在插件商城中搜索open in browser并安装 2.打开 文件==》首选项==》设置 在搜索栏中搜索Open-in-br

    2024年02月11日
    浏览(40)
  • 解决selenium打开Chrome浏览器自动退出的问题

    好不容易安装好selenium和对应的浏览器驱动器后终于可以运行程序了,结果发现一运行程序后浏览器打开就自动退出了,但是我在Python代码中并没有写driver.quit()方法,上网查了查发现原来是我的selenium版本是4.8.2的,selenium升级到版本4.7.2后,会出现这个浏览器自动退出的问题

    2024年02月11日
    浏览(47)
  • 【已解决】浏览器无法访问页面,ERR_TUNNEL_CONNECTION_FAILED

    【已解决】浏览器无法访问页面,ERR_TUNNEL_CONNECTION_FAILED 无法访问浏览器页面,显示内容如下: 打开其他浏览器,确定是否为Microsoft Edge的问题。 可能是搜索引擎或者注册表的问题, 可以尝试更换搜索引擎或者还原设置。 更换搜索引擎: 点击右上角 … 下拉菜单,选择 设置

    2024年02月02日
    浏览(48)
  • 前端笔记 ---- Chrome 浏览器不能跨域访问解决方案

    1. 需求场景 Chrome 浏览器开发 H5 进行接口联调时,浏览器不允许跨域访问; 想通过浏览器设置,不使用代理等,浏览器可以进行跨域访问。 2. 报错图片 3. 解决方案 3.1 获取Chrome 浏览器安装位置 3.2 设置允许跨域和不验证证书 3.3 cmd 执行设置命令 3.4 组成完整命令 3.5 cmd 运行命

    2024年02月15日
    浏览(33)
  • ERR_UNSAFE_PORT浏览器安全问题导致无法访问的解决方案

    配置好web的https协议的服务器后,使用浏览器访问服务器的时候出现ERR_UNSAFE_PORT无法访问,如下图提示。 img src=“https://juejin.cn/ “点击并拖拽以移动”” style=“margin: auto” / 经过抓取报文分析,并没有抓到访问服务器的报文,定位发现是浏览器的保护机制自动拦截了请求,和

    2024年02月03日
    浏览(75)
  • 找不到和chrome浏览器版本不同的chromedriver的解决方法

    某一天我很久没有chromedriver之后,发现我的google版本是下图这样 打开这个网站下载新版本的chromedriver,我发现没有103.0.5060.114。虽然我不知道为什么没有但是问题总是要解决啊! chromedriver下载地址:http://chromedriver.storage.googleapis.com/index.html 于是我下载了103.0.5060.134版本的chrom

    2024年02月11日
    浏览(38)
  • Mac版chrome谷歌浏览器解决跨域,进行开发调试

    跨域问题一般在浏览器中这样提示 1995年,同源政策由 Netscape 公司引入浏览器。目前,所有浏览器都实行这个政策。 最初,它的含义是指,A 网页设置的 Cookie,B 网页不能打开,除非这两个网页“同源”。所谓“同源”指的是“三个相同”: 协议相同 域名相同 端口相同 同源

    2024年02月02日
    浏览(37)
  • 【已解决】使用selenium启动谷歌Chrome浏览器打开指定网站,页面空白,而使用其它浏览器手动打开该网站则正常

    1、在使用python实现自动化网络爬虫时,我使用到selenium来驱动谷歌Chrome浏览器来打开某一个网页,然后爬取数据,代码如下:    2、但是当执行到driver.get(url)访问网站时,页面是空白的,如下所示,没有正常显示该网站的数据    print输出的网页html也只有如下数据: htmlhea

    2024年02月12日
    浏览(43)
  • Python+Selenium程序执行完,chrome浏览器自动关闭解决方案

    因为把driver = webdriver.Chrome()放在了函数内部,在函数执行完毕之后,程序内所有的步骤都结束了,关于这段程序的进程也就结束了,浏览器包含在内,所以才会自动退出。 设置全局变量,即把打开浏览器的操作放在函数外部,函数执行完毕,浏览器就不会关闭 关闭浏览器代

    2024年02月16日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包