[英]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.