我刚开始学习ZeroMQ,想要在学习的同时构建一个分布式的网络爬虫作为一个例子。
我的想法是使用PHP编写一个"server",它接受爬行应该从哪里开始的url。
工作人员(C# cli)将不得不爬行该url,提取链接,并将它们推回服务器上的堆栈中。服务器一直将堆栈中的urls发送给工作人员。也许redis会跟踪所有爬行的urls,所以我们不会多次抓取站点,并且能够提取当前进程的统计信息。
我希望服务器能够均匀地分配任务,注意新的/丢失的工作人员,并在员工没有响应时重新分发urls。
为什么PHP用于服务器:我只是对PHP非常满意,仅此而已。我不想让这个例子/测试项目变得更复杂。
为什么C#为仆从:因为它运行在大多数windows机器上。我可以把可执行文件交给不同的朋友,他们可以执行它,并帮助我测试我的项目。
爬行过程和redis功能不是我问题的一部分。
我的第一种方法是推拉模式,它通常适用于我的场景,但不知道它是仆从。我想我需要一个中间商/路由器经纪人,我必须自己处理工人的意识。
我找到了this question,但我不确定我是否理解答案.
我要求提供一些如何影响zmq的提示。经销商的做法正确吗?有什么办法能让员工自动意识到吗?我认为我需要一些资源/示例,还是您认为我只需要深入了解zmq指南?
然而,一些指向正确方向的暗示将是很棒的:)
干杯
发布于 2013-10-17 02:09:06
我正在构建一个作业/任务分发程序,它的工作原理至少与您的爬虫相同。以下是我学到的一些东西:
定义所有事件
服务器和爬虫之间的通信将基于系统中发生的不同事情,例如将工作从服务器发送到爬虫,或者爬虫向服务器发送心跳消息。定义系统的事件类型;它们是用例:
DISPATCH_WORK_TO_CRAWLER_EVENT
CRAWLER_NODE_STATUS_EVENT
...定义消息标准
服务器和爬虫之间的所有通信都应该使用ZMsg进行,因此定义一个组织框架的标准,如下所示:
Frame1: "Crawler v1.0" //this is a static header
Frame2: <event type> //ex: "CRAWLER_NODE_STATUS_EVENT"
Frame3: <content xml/json/binary> //content that applies to this event (if any)现在,您可以创建消息验证器来验证在对等点之间接收到的ZMsgs,因为您有一个所有消息都必须遵循的标准约定。
服务器
使用服务器上的单个ROUTER与爬虫进行异步和双向通信。此外,使用PUB套接字广播心跳消息。
不要阻塞路由器套接字,使用POLLER每5s或任何东西循环一次,这允许服务器定期执行其他事情,比如向爬行器广播心跳事件;如下所示:
Socket rtr = .. //ZMQ.ROUTER
Socket pub = .. //ZMQ.PUB
ZMQ.Poller poller = new ZMQ.Poller(2)
poller.register( rtr, ZMQ.Poller.POLLIN)
poller.register( pub, ZMQ.Poller.POLLIN)
while (true) {
ZMsg msg = null
poller.poll(5000)
if( poller.pollin(0)){
//messages from crawlers
msg = ZMsg.recvMsg(rtr)
}
//send heartbeat messages
ZMsg hearbeatMsg = ...
//create message content here,
//publish to all crawlers
heartbeatMsg.send(pub)
}为了解决有关员工意识的问题,一种简单有效的方法使用FIFO堆栈和心跳消息,如下所示:
这是一种简单而有效的基于工人可用性的分配工作的方法,而不是盲目地分发工作。查看lbbroker.php示例,概念是相同的。
爬虫(工人)
工作人员应该使用一个DEALER套接字和一个SUB。DEALER是异步通信的主套接字,子订阅来自服务器的心跳消息。当工作人员接收到心跳消息时,它将响应到经销商套接字上的服务器。
Socket dlr = .. //ZMQ.DEALER
Socket sub = .. //ZMQ.SUB
ZMQ.Poller poller = new ZMQ.Poller(2)
poller.register( dlr, ZMQ.Poller.POLLIN)
poller.register( sub, ZMQ.Poller.POLLIN)
while (true) {
ZMsg msg = null
poller.poll(5000)
if( poller.pollin(0)){
//message from server
msg = ZMsg.recvMsg(dlr)
}
if( poller.pollin(1)){
//heartbeat message from server
msg = ZMsg.recvMsg(sub)
//reply back with status
ZMsg statusMsg = ...
statusMsg.send(dlr)
}剩下的你自己算出来。通过PHP的例子,构建东西,打破它,构建更多,这是你学习的唯一途径!
玩得开心,希望它能帮上忙!
https://stackoverflow.com/questions/19405005
复制相似问题