代码之家  ›  专栏  ›  技术社区  ›  André Schild

如何关闭Net::LDAP::Server

  •  2
  • André Schild  · 技术社区  · 7 年前

    我有一个基于 Net::LDAP::Server 模块。 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;
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   zdim    7 年前

    显示的代码不处理 Net::Server 本身 ::PreForkSimple 除上述信号外。

    有一个 server_close 中的方法 网络::服务器 为了这个。但问题所指的同名方法似乎就是你的答案 Listener

    因此,如果这是在信号处理程序中调用的方法,那么服务器永远不会正确关闭,其现有的子级也会保留。你需要打电话 服务器关闭 网络::服务器 对象,或自行安排 服务器关闭 方法调用父对象的方法。

    网络::服务器 Process Flow 解释

    $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::PreForkSimple Shutdown

    每个Fork和PreFork的个性都通过退出信号支持优雅的关机。当接收到退出时,家长会给孩子发信号,然后等待他们退出。

    然后在下面 Hot Deploy

    但我希望关闭它不需要这个,当然不是最后一个。

        2
  •  0
  •   Nathan Mills    7 年前

    while (1) while ($pidfile->running()) process_request 应该会成功的。设置 $continue 处理\u请求 子例程忽略该变量。

    当然,这需要 $pidfile 因为它不在 处理\u请求