Я только начал изучать ZeroMQ и хочу создать распределенный webcrawler в качестве примера во время сглаживания.
Моя идея состоит в том, чтобы иметь «сервер», написанный на PHP, который принимает URL-адрес, где должен начаться сканирование.
Рабочим (C # cli) придется сканировать этот URL-адрес, извлечь ссылки и вернуть их обратно в стек на сервере. Сервер продолжает отправлять URL-адреса в стек сотрудникам. Возможно, redis будет отслеживать все просканированные URL-адреса, поэтому мы не сканируем сайты несколько раз и можем извлекать статистику текущего процесса.
Я хотел бы, чтобы сервер распределял задачи равномерно, знал новых / отсутствующих сотрудников и перераспределял URL-адреса, когда рабочий не отвечает.
Почему PHP для сервера: мне очень нравится PHP, вот и все. Я не хочу, чтобы сделать пример / тестовый проект более сложным.
Почему C # для миньонов: потому что он работает на большинстве машин Windows. Я могу предоставить исполняемый файл различным друзьям, которые могут просто выполнить его и помочь мне проверить мой проект.
Процесс обхода и redis функциональность не являются частью моего вопроса.
Первым моим подходом был шаблон PUSH / PULL, который обычно работает для моего сценария, но не знает о его фаворитах. Я думаю, что мне нужен посредник DEALER / ROUTER посередине, и я должен сам справиться с осознанием рабочего.
Я нашел этот вопрос, но я не уверен, понимаю ли я ответ …
Я прошу некоторых советов о том, как импортировать материал zmq. Правильно ли подходит дилер? Есть ли способ получить автоматическое информирование работников? Я думаю, мне нужны некоторые ресурсы / примеры, или вы думаете, что мне просто нужно копать глубже в руководстве zmq?
Однако некоторые намеки на правильное направление были бы замечательными 🙂
ура
Я строю дистрибутор заданий / задач, который работает так же, как и ваш искатель, по крайней мере, в принципе. Вот несколько вещей, которые я узнал:
Связь между сервером и поисковыми роботами будет основана на разных вещах, происходящих в вашей системе, таких как отправка работы с сервера на сканер или искатель, отправляющий на сервер сообщение о сердцебиении. Определите типы событий системы; они являются прецедентами:
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)
Теперь вы можете создавать проверки сообщений для проверки ZMsg, полученных между одноранговыми узлами, поскольку у вас есть стандартное соглашение, за которым должны следовать все сообщения.
Используйте один ROUTER
на сервере для асинхронной и двунаправленной связи с сканерами. Кроме того, используйте PUB
сокет для передачи сообщений о сердцебиении.
Не блокируйте гнездо ROUTER, используйте POLLER
для циклического POLLER
каждые 5 POLLER
или что-то еще, это позволяет серверу периодически выполнять другие действия, например, передавать события биения на сканеры; что-то вроде этого:
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
является основным сокетом для асинхронной связи, и 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 , создавайте материал, разбивайте его, создавайте больше, это единственный способ, которым вы научитесь!
Получайте удовольствие, надеюсь, что это поможет!