Реализация api c длительной обработкой запросов
TRANSCRIPT
Реализация API c длительной
обработкой запросов
Жданов Николай
Взаимодействие на уровне сокетовЦикл:1. Соединение с сервером2. Отправка/получение данных3. Отправка/получение данных4. …5. Разъединение.
Взаимодействие по HTTP протоколу (конечные точки)Цикл:1. Соединение2. Отправка данных3. Маршрутизация (выбор конечно точки)4. Получение данных5. Разъеденение
Проблема задержки ответа сервера
REST API?
Структура данных: Очередь(queue, Q)
Item n
Item n-1
…
Item 2
Item 1
Item n + 1
Item 1
Сервер очередей сообщений(message queue, MQ)
Producer 1
Producer 2
Producer 3
Producer 4
Producer 5
Producer 6
Queue 1
Queue 2
exchange
Consumer 1
Consumer 2
Consumer 3
Consumer 4
Consumer 5
Consumer 6
Достоинства очередей сообщений•Слабое связывание•Избыточность•Масштабируемость•Эластичность•Отказоустойчивость
Достоинства очередей сообщений•Гарантированная доставка•Буферизация•Понимание потоков данных•Асинхронность
Варианты реализации MQ
Решения
Облачное Серверное Собственное
Облачные решения• Microsoft Azure
1. Azure Queues 2. Service Bus Queues
• IronMQ• StormMQ • Amazon Simple Queue Service
Серверные решенияНазвание Язык программирования
ActiveMQ JAVA
Apollo JAVA, AMQP
Celery Python
Crossroads I/O C, ZEROMQ
Darner C++
Delayed::Job RUBY, MYSQL
Gearman C
HornetQ JAVA, AMQP, JMS
Zaqar (ex Marconi) OPENSTACK, PYTHON, MONGODB, SQLITE, DURABLE
Apache Kafka JAVA
Название Язык программирования
Kestrel SCALA
nanomsg C, ZEROMQ
NATS GO, NODE, JAVA, RUBY, PYTHON, SCALA
NSQ GO
Apache Qpid JAVA, AMQP, CPP
queue_classic RUBY, POSTGRES
RabbitMQ ERLANG, AMQP
Resque RUBY, REDIS
Sidekiq RUBY, REDIS
ZeroMQ C++
Собственные решения
RabbitMQОсобенности:• Надежность• Гибкая маршрутизация• Кластеризация • Высокая доступность очередей• Поддержка множеством языков программирования• Трассировка• Система плагинов
Пример развертывания RabbitMQУстановка в Ubuntu:
Перезагрузка:
Веб-панель:http://localhost:15672/
sudo apt-get install rabbitmq-server
sudo service rabbitmq-server restart
RabbitMQ: Producer on pythonimport pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
connection.close()
RabbitMQ: Consumer on pythonimport pika
connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))channel = connection.channel()channel.queue_declare(queue='hello')
def callback(ch, method, properties, body): print (" [x] Received {0}“.format(body))
channel.basic_consume(callback, queue='hello', no_ack=True)channel.start_consuming()
RabbitMQ: QueueConsumer 1
Consumer 2
Consumer 3
Consumer 4
RabbitMQ
RabbitMQ: Queue (Реальное распределение)
Consumer 1
Consumer 2
Consumer 3
Consumer 4
RabbitMQ
RabbitMQ: Queue(c prefetchCount = 1)
Consumer 1
Consumer 2
Consumer 3
Consumer 4
RabbitMQ
Ответ на запрос API: БД
Client REST APIServer MQ
Consumer
DatabaseClient REST API
request
Id answer
Id answer
answer
Ответ на запрос API: БД
Client REST APIServer MQ
ConsumerClient REST API
request
Id answer
request answer
answer
Полезные ссылки:• http://habrahabr.ru/post/153431/• https://makeomatic.ru/blog/2013/10/16/RabbitMQ/• http://mqseries.narod.ru/book/webspheremq_1.htm• http://habrahabr.ru/post/149694/• http://habrahabr.ru/company/mailru/blog/216363/• http://queues.io
Спасибо за внимание.