簡體   English   中英

如何關閉Net :: LDAP :: Server

[英]How to shutdown Net::LDAP::Server

我有一個基於使用Net::LDAP::Server模塊的Perl LDAP服務器。 要使其在Linux中作為服務運行,我使用Net::Server::PreForkSimple庫。

到目前為止,一切正常,但是當我關閉服務時,子進程不會關閉。

關閉所有進程的正確方法是什么?

當我發送SIGTERM信號時,將調用server_close方法,但沒有其他反應。 從這一點開始,終止的子項不再重新啟動,但是等待工作的子項不會終止。

#!/usr/bin/perl

#chkconfig: 345 80 05
#description: LDAP Server for Innovaphone

use strict;
use warnings;

package Listener;

use Net::Server;
use base 'Net::Server::PreForkSimple';

my $continue = 1;

...

sub process_request {
    my $self = shift;

    my $in  = *STDIN{IO};
    my $out = *STDOUT{IO};

    my $sock         = $self->{server}->{client};
    my $peer_address = $sock->peerhost();
    my $peer_port    = $sock->peerport();
    logwarn( "Connection accepted from $peer_address : $peer_port" );

    my $handler = InnoLdapServer->new($sock);

    while ( 1 ) {
        my $finished = $handler->handle;
        return if $finished;
    }
}

...

sub server_close {
    logmsg( "Server close called" );
    $continue = 0;
}

# Start daemon
Proc::Daemon::Init();

my $pidfile = File::Pid->new({ file => "/var/run/inno-ldap.pid" });

if ( $pidfile->running() ) {
    die "Already running";
}

$pidfile->write();

open( STDOUT, '>', "$logpath/inno-ldap.$logName.log" ) or die "Can't open stdout log";
select( ( select( STDOUT ), $| = 1 )[0] );    # make the log file "hot" - turn off buffering

open( STDERR, '>', "$logpath/inno-ldap.$logName.error.log" ) or die "Can't open error log";
select( ( select( STDERR ), $| = 1 )[0] );    # make the log file "hot" - turn off buffering

while ( $continue ) {

    # package main;
    $roothandler = Listener->run(
        port          => [ 636, "389/tcp" ],
        proto         => "ssl",   # use ssl as the default
        ipv           => "*",     # bind both IPv4 and IPv6 interfaces
        user          => "daemon",
        group         => "daemon",
        SSL_key_file  => "/home/root/ssl_cert/server.pem",
        SSL_cert_file => "/home/root/ssl_cert/server.pem",
        max_servers   => 10,
        log_level     => 4
    );
}

$pidfile->remove();

1;

所示代碼與Net::Server本身無關。 ::PreForkSimple擴展; 如果程序被信號終止,則服務器本身需要關閉。 除了提到的信號之外,我們看不到調用代碼以及如何“ 關閉服務 ”。

Net::Server有一個server_close方法。 但是問題所指的同名方法似乎是您的Listener類中的方法,因此它覆蓋了(祖父母)方法。 它只會停止子進程中的進一步工作,並且不會接觸服務器。

因此,如果這是在信號處理程序中調用的方法,則服務器永遠不會正確關閉,並且其現有子代仍然存在。 您需要在Net::Server對象上調用server_close ,或者安排自己的server_close方法來調用父級的方法。

流程下的Net::Server文檔說明

在服務器關閉階段( $self->server_close ),以下內容表示程序流:

 $self->close_children; # if any $self->post_child_cleanup_hook; if (Restarting server) { $self->restart_close_hook(); $self->hup_server; } $self->shutdown_sockets; $self->server_exit; 

如果由於某種原因未對Net::Server對象或Listener對象的父對象上的server_close進行調用,請嘗試使用工作流程中列出的各個方法。

Shutdown下的Net :: Server :: PreForkSimple “個性”中也列出了信號

Fork和PreFork的每個角色都通過QUIT信號支持正常關機。 收到QUIT后,父母將向孩子發出信號,然后等待他們退出。

然后在“ 熱部署”下

從2.000版開始,PreForkSimple服務器已接受TTIN和TTOU信號。 收到TTIN時,max_servers增加1。如果收到TTOU信號,max_servers減小1。

但我希望不需要關閉它,當然也不需要最后一個。

process_request中將while (1)循環更改為while ($pidfile->running())應該可以解決問題。 $continue設置為零會阻止更多偵聽器運行,但是據我所知, process_request子例程會忽略該變量。

當然,這將需要早點聲明$pidfile ,因為它在process_request不在范圍內,因為它是在子例程定義之后聲明(並分配)的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM