最新消息:

Net::SSH::Perl 连接远程主机慢的原因

Perl admin 2952浏览 0评论

发现自己写的跳板程序,连接总是很慢。慢到没法接受了,远程主机连接都要 10 多秒,只有自己动手来解决。因为我一直是使用的 Net::SSH::Perl 。还是只能基于这个模块来修改。因为接口之类最完善,也最 Perl 化。

其实我个人非常喜欢 Net::SSH2,因为速度非常快,不过接口是在没法接受。

在处理连接慢之前,其实都查过网上所有的其它同学写的文章了,大家一致认为是 Math::BigInt、Math::BigInt::GMP 和 Math::BigInt::Pari 这几个模块没装的原因。然后我发现我都安装了,还使用 cpanm 来重装了一次。结果没有变化。只能自己来追原因了。

我使用 @CGI.NET 同学推荐的 NYTProf 来跟程序到底那个地方慢。然后打开 HTML 来看看。
netsshperl
我们看到,第一个地方花了 21 秒,就用在连接的上面,点开接着查看源代码,最后测试是下面这段代码有问题。

sub _create_socket {
    my $ssh = shift;
    my $sock = gensym;
 
    my ($p,$end,$delta) = (0,1,1); # normally we use whatever port we can get
       ($p,$end,$delta) = (1023,512,-1) if $ssh->{config}->get('privileged');
 
    # allow an explicit bind address
    my $addr = $ssh->{config}->get('bind_address');
    $addr = inet_aton($addr) if $addr;
    ($p,$end,$delta) = (10000,65535,1) if $addr and not $p;
    $addr ||= INADDR_ANY;
 
    for(; $p != $end; $p += $delta) {
        socket($sock, AF_INET, SOCK_STREAM, getprotobyname('tcp') || 0) ||
            croak "Net::SSH: Can't create socket: $!";
        last if not $p or bind($sock, sockaddr_in($p,$addr));
        if ($! =~ /Address already in use/i) {
            close($sock) or warn qq{Could not close socket: $!n};
            next;
        }  
        croak "Net::SSH: Can't bind socket to port $p: $!";
    }  
    if($p) {
        $ssh->debug("Allocated local port $p.");
        $ssh->{config}->set('localport', $p);
    }  
 
    $sock;
}

因为我是使用 root 用户,所以默认的这个时候加了一个 bind 来对客户端端口进行绑定。这个时候因为 root 用户,所以是绑定的 1024 端口以后。我单独给上面的代码拿出来测试时,发现在最简单的 socket 的连接上。只要 bind 的端口小于 1024 都会非常非常慢。原因未知,我也没法解决。

使用 strace 来跟的时候,发现也是停止在这个绑定以后的连接。只要加了 bind 连接就常常超时。

bind(3, {sa_family=AF_INET, sin_port=htons(1023), sin_addr=inet_addr("0.0.0.0")}, 16) = 0
connect(3, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("xxx.xxx.xxx.xxx")}, 16

以我对 TCP/IP 的理解,好象没法解决这个问题了,原因只能靠大家来解决了。
我只能让整个流程绑定的端口指向 1024 以上,这种变态的方式来解决。也就是默认在 new 这个 Net::SSH::Perl 的对象的时候,加上一个 privileged => 0,来让我绑定都是以 1024 以上来绑定端口自由分配。
在这个地方做做记录,如果有相同的同学也发现自己写的 Net::SSH::Perl 很慢,可以考虑一下是不是相同的问题。

转载请注明:爱开源 » Net::SSH::Perl 连接远程主机慢的原因

您必须 登录 才能发表评论!