Perl 带有AnyEvent的主辅助服务器
我需要编写一个服务器程序,在服务器监听另一端的JSONRPC调用时,它将打开并保持5个实时Telnet、SSH和到服务器的各种连接 我在打开和维护5个连接以及侦听请求方面没有问题:Perl 带有AnyEvent的主辅助服务器,perl,events,asynchronous,Perl,Events,Asynchronous,我需要编写一个服务器程序,在服务器监听另一端的JSONRPC调用时,它将打开并保持5个实时Telnet、SSH和到服务器的各种连接 我在打开和维护5个连接以及侦听请求方面没有问题: # workers: open_myconnections( 1..5 ); my $w1 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(1) }); my $w2 = AnyEvent->timer
# workers:
open_myconnections( 1..5 );
my $w1 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(1) });
my $w2 = AnyEvent->timer (interval => $seconds, cb => sub { keep_conn_alive(2) });
...
# now listen for requests
use AnyEvent::JSONRPC::Lite;
# master:
my $server = jsonrpc_server '127.0.0.1', '4423';
$server->reg_cb(
queue_up => sub {
my ($res_cv, @params) = @_;
my $res = send_params_to_connection_queue( @params );
$res_cv->result($res);
},
);
但现在我一直在努力找出在5个工作进程中分配队列的最佳方式(即非阻塞方式),这就是我的函数send_params_to_connection_queue()
所做的
任何模块建议都是值得赞赏的,尽管我试图避免使用,因为这应该是一个非常小的服务器,除非没有其他合理的选择,否则我会通过。在YAPC::NA 2011,我了解了一个非常好的排队系统,名为ZeroMQ。在和处使用Perl绑定 |-----ssh工作者 JSONRPC侦听器EventLoop-->QueuengSystem-->--telnet worker |-----等等。
在YAPC::NA 2011上,我了解了一个非常好的排队系统ZeroMQ。在和处使用Perl绑定 |-----ssh工作者 JSONRPC侦听器EventLoop-->QueuengSystem-->--telnet worker |-----等等。 只有你知道什么是“最好的”,但如何做到这一点有一个一般的模式,也许这才是你真正的问题 基本上,您需要一个队列,比如一个数组,用于存储所有尚未发送的请求: 我的@queue 然后,每次要执行请求时,首先将数据推送到队列上,然后调用“调度程序”函数: 子do_需求{ 我的($data,$cb)=@; 推送@queue,[$data,$cb]; 调度程序; } 日程安排功能的目的是选择一名工作人员并启动 下一请求: 子调度器{ @排队或返回;#与空队列无关
for my $worker (@workers) {
if ("$worker is free") {
my ($data, $cb) = @{ shift @queue };
$worker->doit (sub {
&scheduler;
$cb->(@_); # call original callback
});
return;
}
}
}
这样做的目的是找到一个自由工作者,向其发送请求(“doit”),然后
完成后,它会再次调用调度程序
这取决于你如何决定一个工人是否“自由”。比如你
始终可以选择未完成请求数最少的工作进程。
或者,您可以选择一个具有(比如)少于5个未完成请求的工作人员。
或者哪种方式最好
重要的是,无论何时,一个工人可能会获得自由(因为一份工作
完成),再次调用调度程序,以对下一个作业进行排队
这样,您可以在不忘记的情况下对工人施加任意限制
关于您需要执行但由于此限制无法发送的作业
这项技术有很多变量,但基本思想始终是
相同:首先是队列,然后有一个函数,您可以在之后调用这两个函数
排队和作业完成后,哪个应分发排队的
工作
在event speak中,有两个事件可能需要发送
请求:创建/排队新作业/请求时,以及未完成的
工作完成了。只有你知道什么是“最好的”,但如何做到这一点有一个通用模式,也许这才是你真正的问题
基本上,您需要一个队列,比如一个数组,用于存储所有尚未发送的请求:
我的@queue
然后,每次要执行请求时,首先将数据推送到队列上,然后调用“调度程序”函数:
子do_需求{
我的($data,$cb)=@;
推送@queue,[$data,$cb];
调度程序;
}
日程安排功能的目的是选择一名工作人员并启动
下一请求:
子调度器{
@排队或返回;#与空队列无关
for my $worker (@workers) {
if ("$worker is free") {
my ($data, $cb) = @{ shift @queue };
$worker->doit (sub {
&scheduler;
$cb->(@_); # call original callback
});
return;
}
}
}
这样做的目的是找到一个自由工作者,向其发送请求(“doit”),然后
完成后,它会再次调用调度程序
这取决于你如何决定一个工人是否“自由”。比如你
始终可以选择未完成请求数最少的工作进程。
或者,您可以选择一个具有(比如)少于5个未完成请求的工作人员。
或者哪种方式最好
重要的是,无论何时,一个工人可能会获得自由(因为一份工作
完成),再次调用调度程序,以对下一个作业进行排队
这样,您可以在不忘记的情况下对工人施加任意限制
关于您需要执行但由于此限制无法发送的作业
这项技术有很多变量,但基本思想始终是
相同:首先是队列,然后有一个函数,您可以在之后调用这两个函数
排队和作业完成后,哪个应分发排队的
工作
在event speak中,有两个事件可能需要发送
请求:创建/排队新作业/请求时,以及未完成的
工作完成。我不确定在这种情况下分发的确切含义,您能详细说明吗?我的意思是,将传入的请求分配给5个可用的工作人员之一。我不确定在这种情况下分发的确切含义,您能详细说明吗?我的意思是,将传入请求分配给5个可用工作进程中的一个。还有AnyMQ和AnyEvent::MP(后者仅在您有多个进程/节点时才有意义)AnyEvent::MP非常棒!我可能会用这个。但我的问题是Net::OpenSSH和Telnet阻塞了库,这使得使用事件队列变得非常困难。您使用非阻塞主事件循环,它以非阻塞方式将阻塞服务(Telnet等)要完成的工作排队,主循环还设置了一个回调函数,这样当队列工作器完成阻塞调用时,它可以向运行回调的主循环发回信号,通常对数据进行后处理,并将数据包发送给事件请求者。我在上面的回复中画了一幅图。还有AnyMQ和AnyEvent::MP(后者只在有多个进程/节点时才有意思)AnyEvent::MP很棒!我可能会用它