我需要编写一个服务器程序,它将打开并保存5个实时Telnet,SSH和各种服务器连接,同时它会监听另一端的JSONRPC调用。
打开和维护5个连接并监听请求时没问题:
# 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);
},
);
但是现在我一直试图找出最好的方法(即非阻塞,AnyEvent方式)在5名工人中分配队列,这就是我的函数send_params_to_connection_queue()
。
任何模块建议都值得赞赏,虽然我试图避免使用POE,因为这应该是非常小的服务器,除非没有其他明智的选择,否则我'通过。
答案 0 :(得分:3)
在YAPC :: NA 2011,我了解了一个名为ZeroMQ的非常好的排队系统。使用Perl绑定Direct Perl Bindings和AnyEvent bindings。
|----- ssh worker JSONRPC-Listener-EventLoop---->QueueingSystem---|----- telnet worker |----- etc.
答案 1 :(得分:2)
只有你知道什么是“最好的”,但是有一个关于如何做到这一点的一般模式,也许这是你真正的问题。
基本上,你需要一个队列,比如一个数组,它存储所有尚未发送的请求:
我的@queue;
然后,每次要执行请求时,首先将数据推送到队列中,然后调用“调度程序”函数:
sub do_req { 我的($ data,$ cb)= @_; 推@queue,[$ data,$ cb]; 调度; }
日程安排功能的目的是选择一名工人并开火 下一个请求:
子调度程序{ @queue或返回; #与空队列无关
for my $worker (@workers) {
if ("$worker is free") {
my ($data, $cb) = @{ shift @queue };
$worker->doit (sub {
&scheduler;
$cb->(@_); # call original callback
});
return;
}
}
}
这样做是为了找到一个自由工作者,向它发送请求(“doit”),以及 当它完成后,它再次调用调度程序。
由您决定工人是否“免费”取决于您。例如,你 总是可以选择具有最少数量未完成请求的工作人员。 或者您可以选择一个工作人员,例如,少于5个未完成的请求。 或者无论哪种方式最好。
重要的是,每当一个工人获得自由(因为一份工作) 完成后,再次调用调度程序,为下一个作业排队。
这样你可以对工人施加任意限制,同时不要忘记 关于你需要做的但由于这个限制而无法发送的工作。
这种技术有许多变异,但基本思想始终是 相同:第一个队列的东西,然后有一个你之后调用的函数 排队和完成作业后,应该分配排队 工作
事件发言时,您可能需要发送一个事件 请求:创建/排队新作业/请求时,以及未完成时 工作完成了。