与mod_perl2 moose应用程序的DB连接太多

Har*_*ens 3 perl moose mod-perl2

我有一个基于mod_perl2的Web应用程序,需要连接到mysql数据库.我已经以驼鹿角色实现了SQL连接细节.

简化后,该角色如下所示:

package Project::Role::SQLConnection;

use Moose::Role;
use DBIx::Connector;

has 'connection' => (is => 'rw', lazy_build => 1);
has 'dbh' => (is => 'rw', lazy_build => 1);
has 'db'    => ( is => 'rw', default => 'alcatelRSA');
has 'port'  => ( is => 'rw', default => 3306);
has 'host'  => ( is => 'rw', default => '10.125.1.21');
has 'user'  => ( is => 'rw', default => 'tools');
has 'pwd'   => ( is => 'rw', default => 'alcatel');


#make sure connection is still alive...
before dbh => sub {
    my $self = shift;
    $self->connection->run(fixup => sub { $_->do('show tables') });
};

sub _build_dbh {
    my $self = shift;
    return $self->connection->dbh;
}

sub _build_connection {
    my $self = shift;
    my $dsn = 'DBI:mysql:'.$self->db.';host='.$self->host.';port='.$self->port;
    my $conn = DBIx::Connector->new($dsn, $self->user, $self->pwd);
    return $conn;
}

no Moose::Role;
1;
Run Code Online (Sandbox Code Playgroud)

然后我在所有需要使用a连接到DB的moose类中使用此角色

 with qw(Project::Role::SQLConnection);
Run Code Online (Sandbox Code Playgroud)

声明.

虽然这在创建一些对象时效果很好,但是在创建许多对象时很快就会遇到麻烦.例如,在httpd日志中,我收到错误:

DBI connect('alcatelRSA; host = 10.125.1.21; port = 3306','tools',...)失败:C上的连接太多:/Perl/site/lib/DBIx/Connector.pm第30行

我想过每次使用DBIx :: Connectors"disconnect"调用来关闭与数据库的连接,但是根据需要,打开/关闭连接的性能影响似乎很大.

你对这个问题有什么其他建议吗?

Eth*_*her 6

DBIx :: Connector对象超出范围时,您是否正在复制dbh并在其中使用它?文档明确指出不要这样做.而是保存DBIx :: Connector对象本身,并dbh使用handles属性中的选项将方法调用委托给它.

这就是我所做的(我实际上昨天刚刚发布了这个代码以回应另一个问题;有趣的是DB问题是如何包装的):

has dbixc => (
    is => 'ro', isa => 'DBIx::Connector',
    lazy_build => 1,
    # DO NOT save a copy of the dbh. Use this accessor every time, as
    # sometimes it will change unexpectedly!
    handles => [ qw(dbh) ],
);

sub _build_dbixc
{
    my $this = shift;
    DBIx::Connector->new(
        $this->dsn,
        $this->username,
        $this->password,
        $this->connect_options,
    );
}

sub call_dbh
{
    my $this = shift;
    my $method = shift;
    my @args = @_;

    # the normal behaviour -- pings on every dbh access
    #return $this->dbh->$method(@args);

    # the smart behaviour -- presume the DB connection still works
    $this->dbixc->run(fixup => sub { $_->$method(@args) });
}
Run Code Online (Sandbox Code Playgroud)

您可能还想查看允许的mod_perl进程数.每个单独的进程或线程不一定必须有自己的数据库连接,但可能有一个以上的-所以你可能还需要确保只有上面的代码运行(即一个数据库管理对象建立)只有一次,每个进程,并构建此类对象的每次后续尝试都只返回现有对象的副本.一个简单的方法是使用MooseX :: Singleton,但这引入了自己的其他设计问题.