Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Comet-сервер своими руками
Search
Dmitry Demeshchuk
October 24, 2012
Programming
7
1.2k
Comet-сервер своими руками
Мой и Макса Лапшина доклад на Highload++ 2012.
Dmitry Demeshchuk
October 24, 2012
Tweet
Share
More Decks by Dmitry Demeshchuk
See All by Dmitry Demeshchuk
Untitled.pdf
doubleyou
0
120
Other Decks in Programming
See All in Programming
ThorVG Viewer In VS Code
nors
0
640
大規模Cloud Native環境におけるFalcoの運用
owlinux1000
0
240
AtCoder Conference 2025
shindannin
0
920
CSC307 Lecture 04
javiergs
PRO
0
620
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
660
公共交通オープンデータ × モバイルUX 複雑な運行情報を 『直感』に変換する技術
tinykitten
PRO
0
180
実は歴史的なアップデートだと思う AWS Interconnect - multicloud
maroon1st
0
300
ELYZA_Findy AI Engineering Summit登壇資料_AIコーディング時代に「ちゃんと」やること_toB LLMプロダクト開発舞台裏_20251216
elyza
2
970
今こそ知るべき耐量子計算機暗号(PQC)入門 / PQC: What You Need to Know Now
mackey0225
3
190
Combinatorial Interview Problems with Backtracking Solutions - From Imperative Procedural Programming to Declarative Functional Programming - Part 2
philipschwarz
PRO
0
130
dchart: charts from deck markup
ajstarks
3
940
これならできる!個人開発のすゝめ
tinykitten
PRO
0
150
Featured
See All Featured
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
0
3.4k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
1.8k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
The Pragmatic Product Professional
lauravandoore
37
7.1k
BBQ
matthewcrist
89
10k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
1.8k
Ruling the World: When Life Gets Gamed
codingconduct
0
120
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.8k
Ethics towards AI in product and experience design
skipperchong
1
160
Building AI with AI
inesmontani
PRO
1
610
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
0
170
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
9.3k
Transcript
Comet-сервер своими руками Макс Лапшин Дмитрий Демещук
Эволюция веба
Никакого real-time
Немного real-time
Сплошной real-time
После загрузки, современная страница продолжает жить своей жизнью.
Данные поступают по инициативе сервера
Возможные реализации • Периодические запросы на сервер • Comet: •
Long polling • Websockets • Server Sent Events • Прочее гуано (Flash sockets)
• Много запросов впустую • Постоянная загрузка • Задержки Периодические
запросы
• Не требует немедленного ответа • Совместим с keepalive •
Моментальное обновление • Много одновременных подключений • Требуется переподключение Long-polling
• Постоянное соединение • Намного быстрее, чем HTTP • Не
везде поддерживаются • Еще не устоялись как стандарт
Выбор очевиден:* * часто в сочетании с таймером
• Ruby EventMachine • Python Twisted • Node.JS • Erlang
“Стойте, я же могу просто сделать это на чистом PHP!”
None
• CGI - ~1000-2000 • Apache - 1000-5000 • Node.JS
- 1000000 (?) • Erlang - 2277845 Лимит одновременных подключений
None
Хранение внутреннего состояния • MySQL — надежно и очень медленно
• Redis/memcached — ненадежно и медленно • Внутри VM — быстро и опасно • Репликация
Внутреннее состояние хочется реплицировать
Почти всегда нужна доставка сообщений
А еще, очень хочется failover
Нет решений для распределенного комета из коробки • Redis -
master-slave репликация • Memcached - нет сообщений • Postgres - медленно и без репликации
RabbitMQ • Возможность хранения истории • Возможность использования вебсокетов •
Нет long polling из коробки
Все приходится делать самим
Нельзя просто так взять и написать распределенный comet-сервер Нельзя просто
так взять и написать распределенный comet-сервер
Почему Erlang • Феноменальная для веба производительность • Феноменальная для
веба многоядерность • Распределенность из коробки • Асинхронный IO в последовательном виде • Изоляция данных • Горячее обновление кода
DPS - distributed pub/sub https://github.com/doubleyou/dps
Желаемые фичи • In-memory • История сообщений в канале •
Горячий бэкап нод • Zero-conf, no-ops сервер
Хроника событий 1. Реализация pub/sub-механизма 2. Написание тестов 3. Прикручивание
веб-сервера 4. Доработка напильником 5. Бенчмарки 6. ... 7. PROFIT!
• Распределенный • Автоматический failover • Написан за 2.5 часа
• Меньше 300 строк кода • Один race condition • Один баг-опечатка Первый рабочий pub/sub
dps:subscribe("Channel"). dps:publish("Channel", “Message”).
Тесты • Выявили race condition • Очень помогли в дальнейшей
разработке • Отняли несколько часов • Покрыли примерно 80% кода pub/sub-части • По размеру сравнимы с кодом
Comet добавляется за час http://levgem.livejournal.com/409755.html
Прикрутили чатик на JS. Попутно оказалось, что кроссдоменный long-poll не
работает в Safari.
Все круто, все работает.
Спасибо за внимание!
И тут пришли они Бенчмарки
Попытка №0: подозрительно хорошие результаты
Мы просто слали сообщения 300 000 publishes per second
Вывод: бенчмарки должны соответствовать продакшну
Разные профили нагрузки • Whatsapp: 2M online, 12k pps •
Ejabberd: 40k online, 40k pps
Попытка №1 • Amazon EC2 large instances • 1000 клиентских
подключений • 1 rps с каждого клиента
На этот раз, бенчмарк-процессы работают приближенно к живым клиентам
• 20-140% CPU на одной машине • 2000 deliveries per
second Мы посовещались и решили, что Amazon не очень
Структура на одной ноде
Репликация между нодами
• Асинхронная репликация • Messages discarding • Replication dropping Sacrificial
degradation
Асинхронный publish на соседние ноды облегчил ситуацию, но не решил
проблему.
10 000 deliveries per second с асинхронной репликацией, работает
20 000 deliveries per second - через некоторое время обсыпается
с timeout
Интроспекция в Erlang как она есть
Все дело в очередях
Низкое время ответа может быть вредно
Long polling рассчитан на редкие ответы с сервера. У нас
же он превратился в short-polling.
Выходы* • Таймаут на клиенте • Таймаут на сервере •
Пользовательские сессии * лучше - в комбинации
Сессии - почти те же каналы
7500 publishes per second 150 000 deliveries per second
200 000 deliveries per second обсыпается с timeout
• Клиент шлет сообщение в полную очередь • Отваливается с
таймаутом • Перепосылает в ещё более полную очередь • OOM Killer In Da House Замкнутый круг
Вывод: надо тщательно продумывать rate limit control
• Перед публикацией проверяем длину очередей • Если большая, шлем
HTTP 429 • Клиент сам перепошлет завтра позже Power of Erlang
Итого
Сервер написан и протестирован за несколько человеко-дней
Неплохая производительность: WhatsApp - ~11500 pps DPS - ~7500 pps
Функциональность и железо разные, но порядок цифр похожий.
Важные моменты • Не следует хранить всю историю в памяти
• Следите, какие процессы перегружаются • Избегайте избыточных сообщений • Не делайте запросы слишком часто • Используйте пользовательские сессии • Старайтесь не гонять лишние данные
Erlang - не серебряная пуля, но позволяет фокусироваться на более
высокоуровневых задачах
Тесты и бенчмарки с лихвой окупили себя.
Что дальше? • DHT Ring для распределения каналов • Персистентность
• Регулировка consistency/availability
Технические компромиссы могут заметно ускорить работу сервера. • Не хранить
очереди • Терять сообщения • Отказаться от сессий (в некоторых случаях) • Посылать все в /dev/null
Вопросы? Макс Лапшин
[email protected]
Дмитрий Демещук
[email protected]