распределённая очередь заданий Смирнов В.А. Меженин М.Г. Доклад по дисциплине «Распределённые объектные технологии» ЮУрГУ 2012
Немного теории… 2
Более сложные веб-приложения Асинхронная обработка данных – Flickr – изменение размера фотографий Синхронное обновление БД – Like, +1, «Мне нравится» 3
4 ПользовательВеб-сервис ОчередьРабочий Размещаем запрос Рабочий
5 ПользовательВеб-сервис ОчередьРабочий Задание выполняется Рабочий
Как всё устроено 6 ПользовательВеб-сервис ОчередьРабочий Пользователь получает результат Рабочий
Advanced Message Queuing Protocol – открытый протокол для передачи сообщений между компонентами системы Передаёт сообщения с помощью очередей Существуют свободные реализации – … хотя и был разработан для банковских нужд в JPMorgan Chase & Co. 7
8 Приложение Точка обмена Очередь Точка обмена Приложение Сервер сообщений Приложение Клиенты
Fanout – все очереди Direct – согласно ключу маршрутизации Topic – маска Headers – по заголовку сообщения 9
Похожая архитектура Задания как сообщения Результаты как сообщения … Celery! 10
11 Распределённая очередь заданий на Python
12 На основе очередей сообщений Быстрая Распределённая! Параллельная! Планирование – проще, чем cron! Синхронные и асинхронные операции Группировка задач
13 Удалённое управление заданиями Маршрутизация – на основе маршрутизации AMQP Диспетчер задач Уведомления Интеграция с Django!
14 Рабочий Redis … Хранилище результатов
…и немного практики. 15
16 Программы – Redis-server Пакеты – Django – Celery – django-celery – django-celery-with-redis – redis Дополнительно – South – Selenium – PIL
17 Устанавливаем Redis Создаём виртуальную среду, ставим пакеты Разворачиваем Django-проект Прописываем дополнительные настройки INSTALLED_APPS += ('djcelery',)... BROKER_URL = 'redis://localhost:6379/0'... CELERY_RESULT_BACKEND = 'redis' CELERY_REDIS_HOST = 'localhost' CELERY_REDIS_PORT = 6379 CELERY_REDIS_DB = 0... import djcelery djcelery.setup_loader()
18 Celery автоматически распознаёт задания в файлах tasks.py приложений some_app models.py views.py urls.py tasks.py from celery.decorators import def my_task(self, arg): #исходный код задания tasks.py:
19 Рабочие: > python manage.py celeryd Django-сервер: > python manage.py runserver
20 views.py from my_project.some_app.tasks import my_task def some_view(request):... value = "hello" my_task.delay(value)
21 views.py from my_project.some_app.tasks import my_task def some_view(request):... value = "hello" my_task.get(value)
22 tasks.py # -*- coding: utf-8 -*- from celery.task import task from PIL import Image from django.core.files import File from selenium import webdriver import datetime import os import def make_screenshot(screenshot): # делаем скриншот driver = webdriver.Firefox() driver.get(screenshot.url) fd, filename = tempfile.mkstemp('.png')...
23 views.py # -*- coding: utf-8 -*- import urlparse from django.shortcuts import * from django import forms from shootr.core.models import Bundle, Screenshot from shootr.core.tasks import make_screenshot class ScreenshotForm(forms.Form): def save(self): bundle = Bundle.objects.create() for url in self.cleaned_data['urls']: shot = Screenshot.objects.create(bundle=bundle, url=url) make_screenshot.delay(shot) return bundle...
24 Домашняя страница
25 Вводим адреса нескольких сайтов
26 Рабочие принялись за дело Мы видим страницу с будущими скриншотами
27 Некоторые уже отработали
28 Все задачи выполнены
29 Advanced Message Passing Protocol – открытый протокол для передачи сообщений между компонентами системы Очереди заданий – для сложных асинхронных веб-приложений Celery – распределённая очередь заданий на Python