We use a lot of busy OpenLDAP servers and a lot of Perl, with
persistent Net::LDAP connections to the servers. The problem is:
How good is the connection to the server?
I found that:
{
my $ldap;
sub ldapopen {
if ( not $ldap ) {
$ldap = Net::LDAP->new('localhost');
}
return $ldap;
}
}
doesn't work to determine the viability of the connection. Truth is
insufficient.
So next we tried
if ( not $ldap or not $ldap->socket ) {
...
}
and still this didn't catch timed out connections.
Now we are doing things like this:
[$BASE is the DN of the top-level "suffix" entry]
{
my $ldap;
if ( $ldap and $ldap->socket ) {
my $result = $ldap->search(
base => $BASE,
scope => 'base',
filter => '(objectClass=*)',
);
loginfo "Testing result of search for $BASE";
if ( $result and not $result->code ) {
return $ldap if $result->count() == 1;
}
}
loginfo '(Re)connecting to LDAP server';
$ldap = Net::LDAP->new( 'localhost' );
return $ldap;
}
which is two searches for one, rather overkill.
Radiator, the Perl RADIUS server from open.com uses a rather complex
piece of code to check the life of the socket.
How does everyone else cope with this problem?
If we use non-persistent connections, then we run out of TCP sockets
under heavy load.
-- Nick Urbanik http://nicku.org 808-71011 nick.urba...@optusnet.com.au
GPG: 7FFA CDC7 5A77 0558 DC7A 790A 16DF EC5B BB9D 2C24 ID: BB9D2C24
I disclaim, therefore I am.
On 22 February 2012 18:20, Nick Urbanik <nick.urba...@optusnet.com.au> wrote:
> Dear Folks,
> We use a lot of busy OpenLDAP servers and a lot of Perl, with
> persistent Net::LDAP connections to the servers. The problem is:
> How good is the connection to the server?
Not that I'm an expert perl coder, or know Net::LDAP that well ... but
if you hit that snag (, would it make sense to have a look at
>On 22 February 2012 18:20, Nick Urbanik <nick.urba...@optusnet.com.au> wrote:
>> Dear Folks,
>> We use a lot of busy OpenLDAP servers and a lot of Perl, with
>> persistent Net::LDAP connections to the servers. The problem is:
>> How good is the connection to the server?
>Not that I'm an expert perl coder, or know Net::LDAP that well ... but
>if you hit that snag (, would it make sense to have a look at
Thanks for the suggestion. I have looked at the code, which does no
more to verify the aliveness of the connection beyond attempt a bind.
Perhaps that is a better check than doing a base scoped search for the
top-level entry in the directory tree, I don't know.
But surely we are far from alone in dealing with this problem. The
problem is this:
1. For a busy server, using persistent LDAP connections is essential.
2. These connections time out.
3. The code needs to verify that the connection is still alive before
depending on it to do an operation we care about.
So how do you all solve item 3?
-- Nick Urbanik http://nicku.org 808-71011 nick.urba...@optusnet.com.au
GPG: 7FFA CDC7 5A77 0558 DC7A 790A 16DF EC5B BB9D 2C24 ID: BB9D2C24
I disclaim, therefore I am.
--On Thursday, February 23, 2012 9:19 AM +1100 Nick Urbanik
<nick.urba...@optusnet.com.au> wrote:
> But surely we are far from alone in dealing with this problem. The
> problem is this:
> 1. For a busy server, using persistent LDAP connections is essential.
> 2. These connections time out.
Why are the connections timing out? Do you have a limit set on how long a connection can be idle set in your LDAP configuration?
--Quanah
--
Quanah Gibson-Mount
Sr. Member of Technical Staff
Zimbra, Inc
A Division of VMware, Inc.
--------------------
Zimbra :: the leader in open source messaging and collaboration
Tell me this is silly and that if I change it, all will be well!
-- Nick Urbanik http://nicku.org 808-71011 nick.urba...@optusnet.com.au
GPG: 7FFA CDC7 5A77 0558 DC7A 790A 16DF EC5B BB9D 2C24 ID: BB9D2C24
I disclaim, therefore I am.
This means that you are telling the server to disconnect all persistent connections after they have been idle for 5 minutes. Given that you seem to want your persistent connections to persist, this may not be the wisest of settings.
--Quanah
--
Quanah Gibson-Mount
Sr. Member of Technical Staff
Zimbra, Inc
A Division of VMware, Inc.
--------------------
Zimbra :: the leader in open source messaging and collaboration
On 22/02/12 16:56 -0800, Quanah Gibson-Mount wrote:
>--On Thursday, February 23, 2012 11:48 AM +1100 Nick Urbanik ><nick.urba...@optusnet.com.au> wrote:
>>idletimeout 300
>This means that you are telling the server to disconnect all >persistent connections after they have been idle for 5 minutes.
>Given that you seem to want your persistent connections to persist, >this may not be the wisest of settings.
Okay, so if I change this to 24 hours, then (as I understand it; am I
wrong?) there would be a failure every day. How do I verify that the
connection still works then?
-- Nick Urbanik http://nicku.org 808-71011 nick.urba...@optusnet.com.au
GPG: 7FFA CDC7 5A77 0558 DC7A 790A 16DF EC5B BB9D 2C24 ID: BB9D2C24
I disclaim, therefore I am.
On Feb 22, 2012, at 5:22 PM, Nick Urbanik <nick.urba...@optusnet.com.au> wrote:
> Dear Quanah,
> On 22/02/12 16:56 -0800, Quanah Gibson-Mount wrote:
>> --On Thursday, February 23, 2012 11:48 AM +1100 Nick Urbanik <nick.urba...@optusnet.com.au> wrote:
>>> idletimeout 300
>> This means that you are telling the server to disconnect all persistent connections after they have been idle for 5 minutes. Given that you seem to want your persistent connections to persist, this may not be the wisest of settings.
> Okay, so if I change this to 24 hours, then (as I understand it; am I
> wrong?) there would be a failure every day. How do I verify that the
> connection still works then?
>On Wed, Feb 22, 2012 at 6:14 PM, Larry Lile <larry.l...@dreamworks.com> wrote:
> I've always just trapped for the disconnect at the operation,
> this is also a convenient place to check for referrals.
> # XXX Check for I/O Error on update, reconnect and
> # XXX retry if possible. This could be much more sophisticated.
> $ldap = ldap_open($ldap) and $result = $entry->update($ldap)
> if $result->code == LDAP_OPERATIONS_ERROR and
> $result->error =~ m!I/O Error!i;
> ldap_open is the same function I use to open an LDAP server
> normally. When passed an existing LDAP object it will attempt
> to shut it down as cleanly as possible.
But it seems that you are aiming for *non*-persistent connections; it
seems to me that you are closing the connection if it exists.
The problem there is that if there is a very high load, and there are
many connections and disconnections, it is possible to consume too
many TCP connections. (Our LDAP servers can be *very* busy).
What we are aiming for is to maintain a *persistent* LDAP connection,
but to determine when it has failed before depending on it.
> On 22/02/12 18:16 -0800, Larry Lile wrote:
>> On Wed, Feb 22, 2012 at 6:14 PM, Larry Lile <larry.l...@dreamworks.com> wrote:
>> I've always just trapped for the disconnect at the operation,
>> this is also a convenient place to check for referrals.
>> # XXX Check for I/O Error on update, reconnect and
>> # XXX retry if possible. This could be much more sophisticated.
>> $ldap = ldap_open($ldap) and $result = $entry->update($ldap)
>> if $result->code == LDAP_OPERATIONS_ERROR and
>> $result->error =~ m!I/O Error!i;
>> ldap_open is the same function I use to open an LDAP server
>> normally. When passed an existing LDAP object it will attempt
>> to shut it down as cleanly as possible.
> But it seems that you are aiming for *non*-persistent connections; it
> seems to me that you are closing the connection if it exists.
> The problem there is that if there is a very high load, and there are
> many connections and disconnections, it is possible to consume too
> many TCP connections. (Our LDAP servers can be *very* busy).
> What we are aiming for is to maintain a *persistent* LDAP connection,
> but to determine when it has failed before depending on it.
This code is used for persistent connections, as you have seen there
is no good way to detect that the server has closed your connection.
The most effective method is to trap the socket I/O error, reconnect
and re execute the failed command. Persistent or not, expect to lose
your connection at any time and recover.
You could reach through and turn on keep alives on the underlying
socket. That isn't the best solution either since it doesn't address
what happens if the server itself goes away. The error check will
also recover that as well.
My LDAP server run about 10k ops/sec. They also disconnect any client
that has been idle for 300 seconds.
>> I haven't tested this code
>> in a while, $result->error =~ m!I/O Error!i may not be correct
>> since the latest updates to Net::LDAP.
>> sub ldap_open
>> {
>> my $ldap = shift;
>> ...
>> if ($ldap)
>> {
>> warn "\nConnection to ", $ldap->{net_ldap_host},
>> " broken, attempting to reconnect.\n"
>> if $opt_v;
>> # XXX Try to close the socket as best we can.
>> close $ldap->{net_ldap_socket};
>> foreach my $server (split(/\s+/, $ldap_opt{'host'}))
>> {
>> ($server, my $port) = split(/:/, $server, 2);
>> $port = $ldap_opt{'port'} if ! $port;
>> last if lc $server eq lc $ldap->{net_ldap_host};
>> push @servers, shift @servers;
>> }
>> }
>> The remainder of the code builds a connection to the LDAP server as usual
>> returning it's object to the c
>> Pardon the interruption there. =)
>> The remainder of the code builds a connection to the LDAP server as usual
>> returning it's object to the caller.
> --
> Nick Urbanik http://nicku.org 808-71011 nick.urba...@optusnet.com.au
> GPG: 7FFA CDC7 5A77 0558 DC7A 790A 16DF EC5B BB9D 2C24 ID: BB9D2C24
> I disclaim, therefore I am.
> On 22/02/12 16:56 -0800, Quanah Gibson-Mount wrote:
>> --On Thursday, February 23, 2012 11:48 AM +1100 Nick Urbanik <
>> nick.urba...@optusnet.com.au> wrote:
>>> idletimeout 300
>> This means that you are telling the server to disconnect all persistent
>> connections after they have been idle for 5 minutes. Given that you seem
>> to want your persistent connections to persist, this may not be the wisest
>> of settings.
> Okay, so if I change this to 24 hours, then (as I understand it; am I
> wrong?) there would be a failure every day. How do I verify that the
> connection still works then?
I've always just trapped for the disconnect at the operation,
this is also a convenient place to check for referrals.
# XXX Check for I/O Error on update, reconnect and
# XXX retry if possible. This could be much more sophisticated.
$ldap = ldap_open($ldap) and $result = $entry->update($ldap)
if $result->code == LDAP_OPERATIONS_ERROR and
$result->error =~ m!I/O Error!i;
ldap_open is the same function I use to open an LDAP server
normally. When passed an existing LDAP object it will attempt
to shut it down as cleanly as possible. I haven't tested this code
in a while, $result->error =~ m!I/O Error!i may not be correct
since the latest updates to Net::LDAP.
sub ldap_open
{
my $ldap = shift;
...
if ($ldap)
{
warn "\nConnection to ", $ldap->{net_ldap_host},
" broken, attempting to reconnect.\n"
if $opt_v;
# XXX Try to close the socket as best we can.
close $ldap->{net_ldap_socket};
foreach my $server (split(/\s+/, $ldap_opt{'host'}))
{
($server, my $port) = split(/:/, $server, 2);
$port = $ldap_opt{'port'} if ! $port;
last if lc $server eq lc $ldap->{net_ldap_host};
push @servers, shift @servers;
}
}
The remainder of the code builds a connection to the LDAP server as usual
returning it's object to the c
-- Larry
Hi Mom! [Just in case my e-mail ever ends up in the Wall Street Journal
> On Wed, Feb 22, 2012 at 5:22 PM, Nick Urbanik <
> nick.urba...@optusnet.com.au> wrote:
>> Dear Quanah,
>> On 22/02/12 16:56 -0800, Quanah Gibson-Mount wrote:
>>> --On Thursday, February 23, 2012 11:48 AM +1100 Nick Urbanik <
>>> nick.urba...@optusnet.com.au> wrote:
>>>> idletimeout 300
>>> This means that you are telling the server to disconnect all persistent
>>> connections after they have been idle for 5 minutes. Given that you seem
>>> to want your persistent connections to persist, this may not be the wisest
>>> of settings.
>> Okay, so if I change this to 24 hours, then (as I understand it; am I
>> wrong?) there would be a failure every day. How do I verify that the
>> connection still works then?
> I've always just trapped for the disconnect at the operation,
> this is also a convenient place to check for referrals.
> # XXX Check for I/O Error on update, reconnect and
> # XXX retry if possible. This could be much more sophisticated.
> $ldap = ldap_open($ldap) and $result = $entry->update($ldap)
> if $result->code == LDAP_OPERATIONS_ERROR and
> $result->error =~ m!I/O Error!i;
> ldap_open is the same function I use to open an LDAP server
> normally. When passed an existing LDAP object it will attempt
> to shut it down as cleanly as possible. I haven't tested this code
> in a while, $result->error =~ m!I/O Error!i may not be correct
> since the latest updates to Net::LDAP.
> sub ldap_open
> {
> my $ldap = shift;
> ...
> if ($ldap)
> {
> warn "\nConnection to ", $ldap->{net_ldap_host},
> " broken, attempting to reconnect.\n"
> if $opt_v;
> # XXX Try to close the socket as best we can.
> close $ldap->{net_ldap_socket};
> foreach my $server (split(/\s+/, $ldap_opt{'host'}))
> {
> ($server, my $port) = split(/:/, $server, 2);
> $port = $ldap_opt{'port'} if ! $port;
> last if lc $server eq lc $ldap->{net_ldap_host};
> push @servers, shift @servers;
> }
> }
> The remainder of the code builds a connection to the LDAP server as usual
> returning it's object to the c
Pardon the interruption there. =)
The remainder of the code builds a connection to the LDAP server as usual
returning it's object to the caller.
-- Larry
Hi Mom! [Just in case my e-mail ever ends up in the Wall Street Journal