You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Perl 5.32环境下Net::HTTP长连接读取超时问题排查求助

Perl 5.32.1 Docker环境下Net::HTTP长连接超时问题排查与修复

问题背景

在Docker容器中构建Perl 5.32.1环境时,安装libwww-perl遇到Net::HTTP测试用例失败的问题,通过强制安装Net::HTTP绕过了该问题。但后续编写的长连接测试脚本在Docker环境中执行时,第二次请求出现超时错误;而在桌面环境(Perl 5.30.2,Net::HTTP 6.22)中执行则完全正常。

Docker构建脚本

原始构建脚本如下(已标注需添加的强制安装Net::HTTP的行):

RUN curl -SL https://www.cpan.org/src/5.0/perl-5.32.1.tar.gz -o /opt/perl-5.32.1.tar.gz \
    && tar -xvzf /opt/perl-5.32.1.tar.gz --directory /opt \
    && cd /opt/perl-5.32.1 \
    && ./Configure -de \
    && make \
    && make test \
    && make install \
    && rm -f /opt/perl-5.32.1.tar.gz \
    && yes | cpan install App::cpanminus \
    && yum install -y openssl \
    && cpanm install -f Net::HTTP \  # 新增:强制安装Net::HTTP以绕过测试失败
    && cpanm install OALDERS/libwww-perl-6.55.tar.gz \
    && cpanm install OALDERS/LWP-Protocol-https-6.10.tar.gz \
    && rm -Rf /opt/perl-5.32.1

测试脚本

用于验证长连接的Perl脚本:

use Net::HTTP;
my $s = Net::HTTP->new(Host => "www.neverssl.com", KeepAlive => 1, Timeout => 15, PeerHTTPVersion => "1.1", MaxLineLength => 512) || die "$@";
for my $iter (1..2) {
   # 注意:此处有笔误,多了一个逗号,建议修正为 GET => "/", 'User-Agent' => ...
   $s->write_request(GET => "/",, 'User-Agent' => 'Mozilla/5.0', 'Accept-Language' => 'no,en', Accept => '*/*');
   print "Reading response for request $iter.\n";
   my ($code, $mess, %h) = $s->read_response_headers;
   print "# --------------------\n";
   print "# $code $mess\n";
   # 可新增:打印响应头,检查Connection字段
   # print map { "# $_: $h{$_}\n" } sort keys %h;
   my $buf;
   while (1) {
      my $n = $s->read_entity_body($tmp, 20);
      last unless $n;
      $buf .= $tmp;
   }
   $buf =~ s/\r//g;
   print "Request $iter completed.\n";
}

错误输出

Docker环境下执行脚本的错误结果:

Reading response for request 1.
# --------------------
# 200 OK
Request 1 completed.
Reading response for request 2.
read timeout at /usr/local/lib/perl5/site_perl/5.32.1/Net/HTTP/Methods.pm line 274.

排查与修复建议

  • 核对版本差异:在Docker环境中执行perl -MNet::HTTP -e 'print $Net::HTTP::VERSION',查看当前版本与桌面环境的6.22是否一致。版本差异是此类问题的常见根源。
  • 检查服务器连接响应头:在测试脚本中添加代码打印所有响应头,重点查看Connection字段是否为Keep-Alive。如果服务器返回Connection: close,则长连接会被主动关闭,第二次请求自然超时。
  • 排查Docker网络环境:在容器内用curl测试长连接是否正常:curl -v --keepalive-time 5 https://www.neverssl.com/ https://www.neverssl.com/,验证是否是容器网络(如NAT、防火墙、代理)导致长连接被中间设备断开。
  • 对比Net::HTTP代码逻辑:查看Docker环境中Net/HTTP/Methods.pm第274行的代码,对比桌面版本的对应逻辑,确认是否存在版本间的长连接处理bug。
  • 调整Net::HTTP版本:尝试在Docker环境中安装与桌面一致的Net::HTTP 6.22版本:cpanm install Net::HTTP@6.22,或升级到最新稳定版本,验证问题是否消失。
  • 检查Perl版本的socket差异:Perl 5.32.1与5.30.2在IO::Socket的默认配置上可能存在差异,可在测试脚本中打印socket的TCP keepalive属性:print "SO_KEEPALIVE: ", $s->sockopt('SO_KEEPALIVE'), "\n";,确认是否开启了TCP层面的长连接保活机制。
  • 修复脚本笔误:测试脚本中write_request方法的参数里多了一个逗号,虽然不影响当前执行,但建议修正为GET => "/", 'User-Agent' => ...,避免潜在的语法问题。

内容的提问来源于stack exchange,提问作者BlueMonkMN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 07:07:21