Pull to refresh

Обслуживание тысяч запросов в секунду на примере XBT Tracker

Reading time 5 min
Views 7.6K
Server optimization *
Недавно проводили тест, результаты которого показали, что одно приложение обрабатывает 2000 запросов в секунду на скромном сервере, где это было не единственной нагрузкой. При этом результат каждого запроса записывается в 3-5 таблиц в MySQL. Честно говоря, меня такой результат удивил, поэтому решил поделиться с хабрасообществом описанием архитектуры этого приложения. Подобный подход применим от баннерных показов до чатов и микроблогов, надеюсь кому-нибудь покажется интересным.

Во-первых, это приложение однопоточное. Всё делается одним процессом, работа с сокетами — неблокирующими epoll/select, никаких ожидающих ввода/вывода потоков (threads). С развитием HTTP, сначала появлением Keep-Alive, затем AJAX и набирающим популярность COMET, количество постоянных соединений с веб-сервером растёт, на нагруженных проектах измеряется тысячами и даже десятками тысяч, и если для каждого создавать свой поток (thread) со своим стеком и постоянно переключаться между ними — ресурсов сервера очень быстро не хватит.

Второй ключевой момент — что один SELECT… WHERE pk in (k1, k2, ..., kN) выполняется быстрее, чем несколько SELECT… WHERE pk=… Выполняя работу с базой данных большими пачками можно уменьшить не только число запросов в секунду, но и общую нагрузку.
Читать дальше →
Total votes 69: ↑67 and ↓2 +65
Comments 41

Что такое «асинхронная событийная модель», и почему сейчас она «в моде»

Reading time 15 min
Views 53K
Node.JS *
Sandbox
Сейчас в тематических интернетах модно слово «Node.js». В этой небольшой статье мы попробуем понять («на пальцах»), откуда всё это взялось, и чем такая архитектура отличается от привычной нам архитектуры с «синхронным» и «блокирующим» вводом/выводом в коде приложения (обычный сайт на PHP + MySQL), запущенного на сервере приложений, работающем по схеме «по потоку (или процессу) на запрос» (классический Apache Web Server).
Читать дальше →
Total votes 163: ↑152.5 and ↓10.5 +142
Comments 130

Ruby NoName Podcast S04E07

Reading time 1 min
Views 628
Ruby *

Подкаст


http://ruby.rpod.ru/273046.html

Новости




Специальный гость


Леонид Никаноров



Читать дальше →
Total votes 20: ↑16 and ↓4 +12
Comments 5

Акторы и AJAX

Reading time 10 min
Views 1.8K
Java *
Sandbox
Для написания программ, выполняющих параллельные вычисления, широко применяются потоки (threads). При том, что потоки позволяют достаточно гибко организовывать парраллелизм в программах, они обладают рядом недостатков. Дело в том, что потоки разделяют между собой память. Это значит, что очень легко по неосторожности нарушить целостность программы. Побороть это можно с помощью блокировок, которые позволяют некоторому коду получать эксклюзивный доступ к обшему ресурсу. Однако, сами блокировки, помимо того, что их нужно не забывать проставлять, порождают, в свою очередь, проблемы. Одна из самых страшных проблем — это возможность породить deadlock. Впрочем, даже без этого написание действительно хорошо работающей многопоточной программы превращается в ювелирный труд.

Но у потоков есть альтернативы. Из известных мне — модель акторов (actors) и software transaction memory. Героем этой статьи, как понятно из заголовка, являются первые. Впрочем, по STM есть достаточно много статей в интернете, которые удовлетворят ваше любопытство.

Читать дальше →
Total votes 28: ↑23 and ↓5 +18
Comments 7

Реактивный манифест

Reading time 12 min
Views 51K
System Analysis and Design *Concurrent computing *
Translation
В последние годы требования к приложениям значительно изменились. Десятки серверов, время отклика в несколько секунд, оффлайновое обслуживание, которое могло длиться часами, гигабайты данных — такими были большие приложения буквально несколько лет назад. Сегодня же приложения работают абсолютно на всём, начиная с простых мобильников и заканчивая кластерами из тысячи процессоров. Пользователи ожидают миллисекундного времени отклика и стопроцентного аптайма, в то время как данные выросли до петабайтов.

Первоначально эту нишу занимали крупные инновационные интернет-компании типа Google или Twitter, однако такие требования к приложениям начали всплывать во многих областях индустрии. Финансовые и телекоммуникационные компании первыми начали внедрять новые практики, чтобы удовлетворить новым требованиям, а теперь подтягиваются и остальные.

Новые требования требуют новых технологий. Предыдущие решения делали упор на управляемые сервера и контейнеры. Масштабирование достигалось засчёт покупки более крутых серверов и использования многопоточности. Для добавления новых серверов приходилось применять комплексные, неэффективные и дорогие проприетарные решения.

Однако прогресс не стоит на месте. Архитектура приложений эволюционировала в соответствии с изменившимися требованиями. Приложения, разработанные на основе этой архитектуры, мы называем Реактивными Приложениями. Такая архитектура позволяет программистам создавать событийно-ориентированные, масштабируемые, отказоустойчивые и отзывчивые приложения — приложения, работающие в реальном времени и обеспечивающие хорошее время реакции, основанные на масштабируемом и отказоустойчивом стеке и которые легко развернуть на многоядерных и облачных архитектурах. Эти особенности критически важны для реактивности.

Читать дальше →
Total votes 24: ↑21 and ↓3 +18
Comments 15

Пишем на JS в функционально-декларативном стиле

Reading time 9 min
Views 21K
Website development *JavaScript *Programming *Erlang/OTP *Functional Programming *
Tutorial


Введение


Я люблю функциональные языки за их простоту, ясность и предсказуемость. Пишу в основном на Elixir / Erlang / OTP, пробовал другие языки, но Erlang с его акторами пока мне гораздо ближе чем например Lisp или Haskell. Как известно Erlang == web, а у чего-либо написанного для веба порой бывает клиентский веб-интерфейс: html, css, js — содержимое. Увы js это стандарт современного веба, для него есть библиотеки почти под любую задачу почти на все случаи жизни, да и это более-менее единственное доступное средство что-то выполнить в браузере на стороне клиента. Поэтому нам всё-таки нужен js. Сперва мне подумалось «Лямбды и функции высшего порядка есть, значит писать на js будет просто. Выучу синтаксис и буду писать так же как пишу в Erlang/Lisp/Haskell». Как же я ошибался.
Читать дальше →
Total votes 32: ↑22 and ↓10 +12
Comments 31

Проверка проекта Microsoft Orleans с помощью PVS-Studio

Reading time 14 min
Views 16K
Programming *.NET *C# *Microsoft Azure *

Введение


Всем доброго времени суток.

Вначале маленький Disclaimer для сомневающихся: да, за этот пост я, возможно, получу лицензию на PVS-Studio для проверки открытого проекта Microsoft Orleans. А может и не получу, как фишка ляжет-с. Нет, с компанией "СиПроВер" я напрямую никак не связан и написал этот пост по своей инициативе.

А теперь перейдем к сути.

PVS-Studio 6.0, как заявляет официальный сайт компании, это статический анализатор кода, ориентированный на простоту использования и поиск ошибок на этапе написания кода.

И относительно недавно, компания зарелизила версию, поддерживающую проверку C# проектов. Чем мы собственно и будем проверять проект Microsoft Orleans.

Кстати, команда PVS-Studio тоже проверяла проект Orleans на предмет выявленных ошибок, но я их немного опередил и они любезно предоставили мне свою КДПВ ("картинку для привлечения внимания") с неизменно радующим единорогом.

PVS-Unicorn-In-Clouds

Много технического текста, немного драмы и несколько очевидных выводов.
Total votes 35: ↑24 and ↓11 +13
Comments 14

Kino: communication frawemork на NetMQ. Краткое описание

Reading time 8 min
Views 4.4K
Programming *.NET *
Sandbox

Лет 8 назад я начал работать в команде, которая разрабатывала один сервис. Интерфейс сервиса был достаточно прост, всего 4 метода, и выполнял он одну единственную задачу. В течение всего этого времени код постоянно изменялся: реализовались новые бизнес-правила и ограничения, добавлялась версионность. В один прекрасный момент, front-end‘у понадобился очень небольшой функционал, который был «зарыт» глубоко в сервисе. Реализация необходимой функции была разработана в виде компоненты и не представляло никаких проблем дать к ней доступ из сервиса через дополнительный метод… Кроме одной: нарушалась логическая связанность методов сервиса, то есть его «внутренности» начали становиться «внешностями».


Проблему можно было бы решить, если преобразовать все эти небольшие внутренние компоненты, к которым потребовался доступ извне, в отдельные сервисы. В таком случае, front-end мог бы получить доступ к их функционалу; основной же сервис стал бы более компактным и его роль сводилась к оркестровке вызовов.


Мы использовали WCF для построения сервисов. Разворачивать сервис в 50 строчек кода на WCF, как минимум на 3-4 серверах, с load-balancer‘ом, новыми URL‘ами и прочими наворотами, казалось не очень хорошей идеей. А хотелось какой-то легкости, перспективы…


Несколько лет спустя я принимал участие в другом проекте на Workflow Foundation. Глядя на то, что получалось в XAML-редакторе, я подумал: «А почему-бы не представить весь workflow, как последовательность сообщений»?

Читать дальше →
Total votes 12: ↑12 and ↓0 +12
Comments 5

Пишем собственный хитрый thread_pool-диспетчер для SObjectizer-а

Reading time 20 min
Views 2.3K
Open source *Programming *C++ *

О чем эта статья?


Одной из основных отличительных черт C++ного фреймворка SObjectizer является наличие диспетчеров. Диспетчеры определяют где и как акторы (агенты в терминологии SObjectizer-а) будут обрабатывать свои события: на отдельной нити, на пуле рабочих нитей, на одной общей для группы акторов нити и т.д.

В состав SObjectizer-а уже входит восемь штатных диспетчеров (плюс еще один в наборе расширений для SObjectizer-а). Но даже при всем этом многообразии встречаются ситуации, когда под конкретную специфическую задачу имеет смысл сделать собственного диспетчера. В статье как раз и рассматривается одна из таких ситуаций и показывается как можно сделать собственный диспетчер, если штатные диспетчеры по каким-то причинам нас не устраивают. А заодно будет показано как просто поменять поведение приложения всего лишь привязав одного и того же актора к разным диспетчерам. Ну и еще несколько интересных мелочей и не очень мелочей.

В общем, если кому-то интересно прикоснуться к деталям реализации одного из немногих живых и развивающихся акторных фреймворков для C++, то можно смело читать дальше.

Преамбула


Недавно один из пользователей SObjectizer-а рассказал про специфическую проблему, с которой ему довелось столкнуться в процессе использования SObjectizer-а. Смысл в том, что на базе SObjectizer-овских агентов разрабатывается приложение для управления подключенными к компьютеру устройствами. Часть операций (а именно операция инициализации и переинициализации устройства) выполняется синхронно, что приводит к блокировке рабочей нити на некоторое время. Операции же ввода-вывода осуществляются асинхронно, поэтому иницирование чтения/записи и обработка результата чтения-записи выполняются значительно быстрее и не блокируют рабочую нить надолго.
Читать дальше →
Total votes 11: ↑11 and ↓0 +11
Comments 12

Давайте заглянем SObjectizer-у под капот

Reading time 15 min
Views 3.6K
Open source *Programming *C++ *
Продолжаем знакомить читателей с открытым C++ным фреймворком под названием SObjectizer. Наш фреймворк упрощает разработку сложных многопоточных приложений за счет того, что C++программисту становятся доступны более высокоуровневые инструменты, позаимствованные из Модели Акторов, CSP и Publish-Subscribe. При этом, как бы высокопарно это не звучало, SObjectizer является одним из немногих открытых, живых и развивающихся акторных фреймворков для C++.

Мы уже посвятили SObjectizer-у более десятка статей на Хабре. Но все равно читатели жалуются на наличие «белых пятен» в понимании того, как SObjectizer работает и как взаимосвязаны между собой различные типы сущностей, которыми оперирует SObjectizer.

В этой статье мы попробуем заглянуть под капот SObjectizer-у и постараемся «на пальцах» и в картинках объяснить из чего он состоит и как, в общих чертах, он работает.
Читать дальше →
Total votes 13: ↑13 and ↓0 +13
Comments 4

Добавляем распределенность в SObjectizer-5 с помощью MQTT и libmosquitto

Reading time 25 min
Views 2.6K
Open source *Programming *C++ *
Когда-то в SObjectizer-4 «из коробки» была доступна возможность построения распределенных приложений. Но не всегда это работало так хорошо, как хотелось бы. В итоге в SObjectizer-5 от поддержки распределенности в самом ядре SObjectizer-а мы отказались (подробнее этот вопрос рассматривается здесь). Отказались в пользу того, чтобы под конкретную задачу можно было выбрать конкретный транспорт с учетом особенностей этой самой задачи. Написав для этого соответствующую обвязку, которая будет скрывать от программиста детали работы выбранного транспорта.

В данной статье мы попробуем рассказать об одной такой обвязке вокруг MQTT и libmosquttio, посредством которой была реализована возможность взаимодействия частей распределенного приложения.
Читать дальше →
Total votes 11: ↑11 and ↓0 +11
Comments 2

Shrimp: масштабируем и раздаем по HTTP картинки на современном C++ посредством ImageMagic++, SObjectizer и RESTinio

Reading time 16 min
Views 5.6K
Open source *Programming *C++ *


Предисловие


Наша небольшая команда занимается развитием двух OpenSource инструментов для C++разработчиков — акторного фреймворка SObjectizer и встраиваемого HTTP-сервера RESTinio. При этом мы регулярно сталкиваемся с парой нетривиальных вопросов:

  • какие фичи добавлять в библиотеку, а какие оставлять «за бортом»?
  • как наглядно показывать «идеологически правильные» способы использования библиотеки?

Хорошо, когда ответы на такие вопросы появляются по ходу использования наших разработок в реальных проектах, когда разработчики приходят к нам со своими жалобами или хотелками. За счет удовлетворения хотелок пользователей мы наполняем свои инструменты функциональностью, которая продиктована самой жизнью, а не «высосана из пальца».

Но до нас доходит информация далеко не о всех проблемах и сложностях, с которыми сталкиваются пользователи. И не всегда мы можем использовать полученную информацию и, особенно, примеры кода, в своих публичных материалах.

Поэтому иногда мы сами для себя выдумываем небольшие задачки, решая которые мы вынужденно превращаемся из разработчиков инструментов в пользователей. Это позволяет нам взглянуть на собственные инструменты другими глазами и самим понять, что хорошо, что не очень, чего не хватает, а чего слишком много.

Сегодня мы хотим рассказать как раз об одной такой «небольшой» задачке, в которой естественным образом объединились SObjectizer и RESTinio.

Масштабирование и раздача картинок. Почему именно это?


В качестве небольшой демо-задачи для самих себя мы выбрали HTTP-сервер, который раздает по запросам отмасштабированные картинки. Вы складываете изображения в какой-то каталог, запускаете HTTP-сервер, делаете к нему запрос вида:
Читать дальше →
Total votes 21: ↑20 and ↓1 +19
Comments 13

Развиваем Shrimp: контролируем параллельные запросы, логируем через spdlog и еще…

Reading time 13 min
Views 1.9K
Open source *Programming *C++ *


На прошлой неделе мы рассказали про свой небольшой демо-проект Shrimp, который наглядно показывает, как можно использовать C++ные библиотеки RESTinio и SObjectizer в более-менее похожих на реальность условиях. Shrimp — это маленькое приложение на C++17, которое посредством RESTinio принимает HTTP-запросы на масштабирование изображений и обслуживает эти запросы в многопоточном режиме посредством SObjectizer-а и ImageMagick++.

Проект оказался более чем полезным для нас самих. Копилка хотелок для расширения функциональности RESTinio и SObjectizer заметно пополнилась. Кое что уже даже нашло свое воплощение в совсем свежей версии RESTinio-0.4.7. Так что мы решили не останавливаться на самой первой и самой тривиальной версии Shrimp-а, а сделать еще одну-две итераций вокруг этого проекта. Если кому-то интересно что и как мы сделали за это время, милости просим под кат.
В качестве спойлера: речь пойдет о том, как мы избавились от параллельной обработки идентичных запросов, как добавили в Shrimp логирование с помощью отличной библиотеки spdlog, а также сделали команду принудительного сброса кэша трансформированных картинок.
Читать дальше →
Total votes 9: ↑8 and ↓1 +7
Comments 0

Делаем Shrimp еще полезнее: добавляем перекодирование картинок в другие форматы

Reading time 13 min
Views 2.6K
Open source *Programming *C++ *


С начала 2017-го года наша небольшая команда разрабатывает OpenSource-библиотеку RESTinio для встраивания HTTP-сервера в C++ приложения. К своему большому удивлению мы время от времени получаем вопросы из категории «А для чего может потребоваться встраиваемый HTTP-сервер на C++?» К сожалению, на простые вопросы отвечать сложнее всего. Иногда лучшим ответом является пример кода.

Пару месяцев назад мы затеяли небольшой демо-проект Shrimp, который наглядно демонстрирует типичный сценарий, под который «затачивается» наша библиотека. Демо-проект представляет из себя простой Web-сервис, который получает запросы на масштабирование хранящихся на сервере картинок и который отдает в ответ картинку нужного пользователю размера.

Этот демо-проект хорош тем, что в нем, во-первых, требуется интеграция с давным-давно написанным и исправно работающим кодом на C или C++ (в данном случае это ImageMagick). Поэтому должно быть понятно, почему имеет смысл встраивать HTTP-сервер в C++ приложение.

И, во-вторых, в данном случае требуется асинхронная обработка запросов, дабы HTTP-сервер не блокировался пока выполняется масштабирование картинки (а это может занимать сотни миллисекунд или даже секунды). А разработку RESTinio мы затеяли именно потому, что не смогли найти вменяемый C++ный встраиваемый сервер, ориентированный именно на асинхронную обработку запросов.

Работу на Shrimp-ом мы построили итеративным путем: сперва была сделана и описана самая простая версия, которая только масштабировала картинки. Затем мы устранили ряд недочетов первой версии и описали это во второй статье. Наконец дошли руки расширить функциональность Shrimp-а еще раз: добавилось преобразование картинок из одного формата в другой. О том, как это было сделано и пойдет речь в данной статье.
Читать дальше →
Total votes 15: ↑15 and ↓0 +15
Comments 9

Четыре года развития SObjectizer-5.5. Как SObjectizer изменился за это время?

Reading time 22 min
Views 1.2K
Open source *Programming *C++ *
Первая версия SObjectizer-а в рамках ветки 5.5 вышла чуть больше четырех лет назад — в начале октября 2014-го года. А сегодня увидела свет очередная версия под номером 5.5.23, которая, вполне возможно, закроет историю развития SObjectizer-5.5. По-моему, это отличный повод оглянуться назад и посмотреть, что же было сделано за минувшие четыре года.

В этой статье я попробую тезисно разобрать наиболее важные и знаковые изменения и нововведения: что было добавлено, зачем, как это повлияло на сам SObjectizer или его использование.

Возможно, кому-то такой рассказ будет интересен с точки зрения археологии. А кого-то, возможно, удержит от такого сомнительного приключения, как разработка собственного акторного фреймворка для C++ ;)
Читать дальше →
Total votes 14: ↑12 and ↓2 +10
Comments 0

Как писать unit-тесты для акторов? Подход SObjectizer-а

Reading time 17 min
Views 1.8K
Open source *Programming *C++ *
Акторы упрощают многопоточное программирование за счет ухода от общего разделяемого изменяемого состояния. Каждый актор владеет собственными данными, которые никому не видны. Взаимодействуют акторы только посредством асинхронных сообщений. Поэтому самые кошмарные ужасы многопоточности в виде гонок и дедлоков при использовании акторов не страшны (хотя у акторов есть свои заморочки, но сейчас не об этом).

В общем, писать многопоточные приложения с использованием акторов легко и приятно. В том числе и потому, что сами акторы пишутся легко и непринужденно. Можно даже сказать, что написание кода актора — это самая простая часть работы. Но вот когда актор написан, то возникает очень хороший вопрос: «Как проверить правильность его работы?»

Вопрос, действительно, очень хороший. Нам его регулярно задают когда мы рассказываем про акторов вообще и про SObjectizer в частности. И до недавнего времени мы могли отвечать на этот вопрос лишь общими словами.

Но вот вышла версия 5.5.24, в которой появилась экспериментальная поддержка возможности unit-тестирования акторов. И в данной статье мы попытаемся рассказать о том, что это, как этим пользоваться и с помощью чего это было реализовано.
Читать дальше →
Total votes 14: ↑12 and ↓2 +10
Comments 0

«Современные» обедающие философы на C++ посредством акторов и CSP

Reading time 35 min
Views 13K
Open source *Programming *C++ *

Некоторое время назад ссылка на статью "Modern dining philosophers" распространилась по ресурсам вроде Reddit и HackerNews. Статья интересная, она показывает несколько решений этой известной задачи, реализованных на современном C++ с использованием task-based подхода. Если кто-то это статью еще не читал, то имеет смысл потратить время и прочесть ее.


Однако, не могу сказать, что представленные в статье решения мне показались простыми и понятными. Вероятно это как раз из-за использования тасков. Слишком уж их много создается и диспетчируется посредством разнообразных диспетчеров/сериализаторов. Так что не всегда понятно, где, когда и какие задачи выполняются.


При этом task-based подход не является единственным возможным для решения подобных задач. Почему бы не посмотреть, как задача "обедающих философов" решается посредством моделей Акторов и CSP?


Посему попробовал посмотреть и реализовал несколько решений этой задачи как с использованием Акторов, так и с использованием CSP. Код этих решений можно найти в репозитории на GitHub-е. А под катом пояснения и объяснения, так что кому интересно, милости прошу под кат.

Читать дальше →
Total votes 28: ↑26 and ↓2 +24
Comments 54

Строительные блоки распределенных приложений. Нулевое приближение

Reading time 5 min
Views 3.3K
System Analysis and Design *Erlang/OTP *Functional Programming *Distributed systems *


Мир не стоит на месте. Прогресс создает новые технологические вызовы. В соответствии с изменившимися требованиями, должна эволюционировать и архитектура информационных систем. Сегодня мы будем говорить о событийно-ориентированной архитектуре, конкурентности, параллельности, асинхронности и о том, как в Erlang можно со всем этим жить мирно.

Читать дальше →
Total votes 10: ↑10 and ↓0 +10
Comments 0

Строительные блоки распределенных приложений. Первое приближение

Reading time 8 min
Views 3.6K
System Analysis and Design *Erlang/OTP *Functional Programming *Distributed systems *


В прошлой статье мы разобрали теоретические основы реактивной архитектуры. Пришло время поговорить о потоках данных, путях реализации реактивных Erlang/Elixir систем и шаблонах обмена сообщениями в них:


  • Request-response
  • Request-Chunked Response
  • Response with Request
  • Publish-subscribe
  • Inverted Publish-subscribe
  • Task distribution
Читать дальше →
Total votes 15: ↑15 and ↓0 +15
Comments 0

Строительные блоки распределенных приложений. Второе приближение

Reading time 8 min
Views 2.5K
System Analysis and Design *Erlang/OTP *Functional Programming *Distributed systems *

Анонс


Коллеги, в середине лета я планирую выпустить еще один цикл статей по проектированию систем массового обслуживания: “Эксперимент VTrade” — попытка написать фреймворк для торговых систем. В цикле будет разобрана теория и практика построения биржи, аукциона и магазина. В конце статьи предлагаю проголосовать за наиболее интересные вам темы.



Это завершающая статья цикла по распределенным реактивным приложениям на Erlang/Elixir. В первой статье можно найти теоретические основы реактивной архитектуры. Вторая статья иллюстрирует основные шаблоны и механизмы построения подобных систем.


Сегодня мы поднимем вопросы развития кодовой базы и проектов в целом.

Читать дальше →
Total votes 17: ↑17 and ↓0 +17
Comments 0
1