Л9: Взаимодействие веб-приложений

29
Инфраструктура веб- приложений Сергей Лихобабин Техносфера . 2014

description

Л9: Взаимодействие веб-приложений

Transcript of Л9: Взаимодействие веб-приложений

Page 1: Л9: Взаимодействие веб-приложений

Инфраструктура веб-приложений

Сергей Лихобабин

Техносфера. 2014

Page 2: Л9: Взаимодействие веб-приложений

Запуск фоновых процессов. Cron.

Очереди сообщений и задач. RabbitMQ, Celery.

Real-time сообщения.

Полнотекстовый поиск. Sphinx.

Использование NoSQL хранилищ. Memcached,Redis, Tarantool.

Page 3: Л9: Взаимодействие веб-приложений

Типичные задачиМассовый импорт данных

Массовый экспорт данных

Расчет рейтингов (например, лучшие вопросы)

Очистка устаревших данных

И вообще все периодические работы

Статистика, статистика, статистика

Page 4: Л9: Взаимодействие веб-приложений

Cron – стандартный планировщик задач в linux

Задача = команда оболочки (bash) в linux

Page 5: Л9: Взаимодействие веб-приложений

Проблемы

Скрипт может работать долго

Скрипт может в принципе не успеватьобработать нужный объем данных

Скрипт может потреблять много ресурсов

В каждом скрипте нужно настраиватьокружение: соединение с базой, пути к файлами т.п.

Не чаще раза в минуту

Page 6: Л9: Взаимодействие веб-приложений

Решения

Использовать блокировку файлов (flock)

Распараллелить обработку. Запускатьнесколько процессов

Запускать скрипты на отдельной машине.Использовать scribe для перемещения логов

Использовать management command (в Django)

Cron плохо масштабируется, дает задержки

Page 7: Л9: Взаимодействие веб-приложений

Очереди сообщений

Page 8: Л9: Взаимодействие веб-приложений

Архитектура очередей

Page 9: Л9: Взаимодействие веб-приложений

Преимущества очередейАсинхронная связь и буферизация

Масштабируемость

Балансировка и эластичность нагрузки

Гарантированная доставка

Page 10: Л9: Взаимодействие веб-приложений

Пример (отправкасобытий)

import pika params = pika.ConnectionParameters(host='localhost')connection = pika.BlockingConnection(params) channel = connection.channel() channel.queue_declare(queue='hello') channel.basic_publish( exchange='', routing_key='hello', body='{ "id": 10, "msg": "hello world!"}')connection.close()

Page 11: Л9: Взаимодействие веб-приложений

Пример (получениесобытий)

import pika params = pika.ConnectionParameters(host='localhost')connection = pika.BlockingConnection()channel = connection.channel()channel.queue_declare(queue='hello')

def callback(ch, method, properties, body): print " [x] Received %r" % (body,) ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_consume(callback, queue='hello')channel.start_consuming()

Page 12: Л9: Взаимодействие веб-приложений

Что еще нужно дляхорошей очереди

Протокол передачи параметров задач

Получение результатов

Слежение за worker – процессами

Нужное количество

Ограничение нагрузки

Борьба с падениями

Борьба с утечками памяти

Удобный мониторинг

Page 13: Л9: Взаимодействие веб-приложений

CeleryРаботает поверх RabbitMQ, MongoDB, Redis, DB

Задача = функция python

Удобный интерфейс запуска задач

Замена Cron

Page 14: Л9: Взаимодействие веб-приложений

Архитектура Celery

Page 15: Л9: Взаимодействие веб-приложений

Описание задач Celery from celery import Celery app = Celery('tasks', broker='amqp://guest@localhost//'

def _poor_fib(x): ## глупая реализация фибоначи

@app.task def fib(x): print _poor_fib(x) @app.periodic_task(run_every=timedelta(seconds=60)) def cronlike(): print "Look at me! I'm a cron“

Page 16: Л9: Взаимодействие веб-приложений

Вызов задач Celery ## views.py – код вашего приложения

from tasks import fib

fib.delay(10) result = fib.delay(20) print result.get(timeout=10)

Page 17: Л9: Взаимодействие веб-приложений

Асинхронная доставкасообщений

Polling (каждые 10 секунд…)

LongPolling (Comet)

ServerPush

WebSockets

Page 18: Л9: Взаимодействие веб-приложений
Page 19: Л9: Взаимодействие веб-приложений

Nginx mod_push location /publish/ { set $push_channel_id $arg_cid; # id канала push_store_messages off; # не храним сообщения push_publisher; # включаем отправку allow 127.0.0.1; deny all;}

location /listen/ { push_subscriber_concurrency broadcast; # всем! set $push_channel_id $arg_cid; # id канала default_type application/json; # MIME тип сообщения push_subscriber; # включаем доставку}

Page 20: Л9: Взаимодействие веб-приложений

Comet client-side function comet (id, onmessage) { $.get('http://host/listen/', { cid: id }) .done(function(data) { onmessage(data); comet(id, onmessage); }) .fail(function(data) { comet(id, onmessage); }); }

comet(123, function(data) { console.log(data); });

Page 21: Л9: Взаимодействие веб-приложений

Отправка сообщений import urllib2 request = urllib2.Request( 'http://localhost/publish/', '{"hello": 1}', {})

# Может занять много времени response = urllib2.urlopen(request) print response

Page 22: Л9: Взаимодействие веб-приложений
Page 23: Л9: Взаимодействие веб-приложений

Полнотекстовый поиск

Page 24: Л9: Взаимодействие веб-приложений

Особенности SphinxЛегкая интеграция с базами и приложениями

Batch и real-time индексы

Гибкий язык поисковых запросов

SQL – like syntax

Хорошие функции релевантности

Масштабирование

Page 25: Л9: Взаимодействие веб-приложений

In-memory storage

Page 26: Л9: Взаимодействие веб-приложений

Memcached import memcache mc = memcache.Client(['127.0.0.1:11211'], debug=0) mc.set("some_key", "Some value") value = mc.get("some_key")

mc.set("another_key", 3) mc.delete("another_key")

mc.set("key", "1") mc.incr("key") mc.decr("key")

Page 27: Л9: Взаимодействие веб-приложений

Memcached import memcache mc = memcache.Client(['127.0.0.1:11211'], debug=0)

def heavy_func(arg1): result = db.get('complex sql') ** 100500; result = template(result) # some very heavy computation :) return result

def fast_func(arg1): result = mc.get(str(arg1)) if result is None: result = heavy_func(arg1) mc.set(str(arg1), result) return result

Page 28: Л9: Взаимодействие веб-приложений

Полезные ссылкиhttp://www.rabbitmq.com/getstarted.html -RabbitMQ

http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html - Celery

http://sphinxsearch.com/docs/2.0.9/ - Sphinx

Page 29: Л9: Взаимодействие веб-приложений

Спасибо за внимание

Сергей Лихобабин

[email protected]