经常遇到来自MongoDB perl驱动程序的异常

时间:2014-02-26 16:19:35

标签: perl mongodb

Web应用程序正在运行,但在我的日志错误中经常遇到此异常

can't get db response, not connected at ../MongoDB/Cursor.pm line 160.

invalid header received at ../MongoDB/Cursor.pm line 160.

can't locate object method "new" via package "MongoDB::Timestamp" at ../MongoDB/Collection.pm line 370.

Perl驱动程序

MongoDB服务器“版本2.4.8”

  • 1位主人
  • 2复制

MongoDB服务器状态连接服务器有时会达到限制连接

"connections" : {
        "current" : 20000,
        "available" : 0,
        "totalCreated" : NumberLong(73428104)
 },

这是我从MongoDB获取连接的代码

sub get_mongodb {
my ($self) = @_;

#master/slave
my $mode    = $self->mode;

#get db name
my $db      = $self->db;

my $obj = $self->{'o_mongodb_' . $mode . '_' . $db};

unless($obj) {
    my %opt;

    #result get_con
    #{
    #    'db'    => 'mongo',
    #    'host'  => [
    #            '10.10.10.1:27017',
    #            '10.10.10.2:27017',
    #            '10.10.10.3:27017'
    #       ]
    #}
    my $con = $self->get_con($db);

    if($mode eq 'master') {
        $opt{find_master} = 1;
    }
    else {
        $opt{find_master} = 0;
    }

    $opt{timeout}       = 50000;
    $opt{query_timeout} = -1;

    my @host    = @{$con->{host}};
    @host       = $self->{t}->util->shuffle(@host);
    $opt{host}  = 'mongodb://' . join(',', @host);

    my @opt = %opt;
    my $client;

    eval { 
        local $SIG{__DIE__}; 
        $client = MongoDB::MongoClient->new(@opt);
    };

    if(!$@) {
        $obj = $self->{'o_mongodb_' . $mode . '_' . $db} = $client->get_database($con->{db});
    }
    else {
        return 0;   
    }
}

if($mode eq 'master') {
    $MongoDB::Cursor::slave_okay = 0;
}
else {
    $MongoDB::Cursor::slave_okay = 1;   
}

return $obj;
}   

我的代码有错吗?谢谢你的时间。

2 个答案:

答案 0 :(得分:0)

你显然没有连接。从您的评论中可以清楚地看出这一点,因为您正在与导致命中数据库的每个请求建立新连接。

您可以尝试的一件事是减少timeout值。默认为20000ms,您实际上设置的更高。结果,连接“徘徊”,并且繁忙的服务器将很快建立起来。

更好的策略是实现连接池。 Perl驱动程序中没有默认功能,但有一个guide on the site可以为您提供有关如何实施的一些指导。

作为自己构建的替代方法,您可能需要查看具有连接池策略的MongoDBx::Class

基本前提是你想要为每个请求建立一个新连接,而是从一个不允许你的app的可用池重新使用耗尽可用的连接。您还会发现操作时间明显更快,而且没有每次建立连接的开销。

答案 1 :(得分:0)

我也有这个问题,如果你有很多不能关闭的连接,请查看mongodb.log

https://jira.mongodb.org/browse/PERL-264