SlideShare a Scribd company logo
1 of 35
Сообщения
Одноклассников
Нюансы разработки мобильного мессенджера
Юрий Буянов
“Одноклассники” 2016
Что и зачем
Сложности
Типы медиа
• текст (с нестандартными смайлами, в том числе,
загружаемыми с сервера)
• картинки
• гифки
• видео
• аудиосообщения
• стикеры
• коллажи (текст + картинки + видео)
Оптимизация
Метрики
быстродействия
Оптимизации
• Все тяжёлые операции — в фон
• Работа с БД
• Работа с сетью
• Сериализация/десериализация
• Работа с картинками
• Вёрстка и вычисление размеров текста
Оптимизации
• Бенчмаркинг и выбор быстрых решений
• MessagePack
• Mantle -> YYModel
• lz4 fast compression
Оптимизации
• Оптимизация рендеринга (избавление от offscreen rendering) —
симптоматически
• UIViewContentModeCenter (по возможности)
• Упрощение иерархий UIView
• Кеширование всего
• “Тяжёлые” UIView
• Информация о размерах / вёрстке
• NSAttributedString
• YYTextLayout
• UIImage (нужного размера, decompressed, скруглённые углы)
Протокол
• TCP Socket (+TLS)
• Запрос-ответ
• Server-Side Push
• Транспорт легко поменять:
• Вебсокеты
• Шифрование на уровне пакета
• Фиксированная длина
• Opcode
• Версия протокола
• Длина payload
• Seq index (для связывания
запроса с ответом)
Header Payload
• Переменная длина
• LZ4-compressed
• MessagePack
Протокол
Синхронизация и
кеширование
Синхронизация и
кеширование
Чат 4
Чат 3
Чат 2
Чат 1
Чат 4
Чат 3
Чат 2 *
Чат 1
Чат 5 *
Offline
Синхронизация и
кеширование
Чат 4
Чат 3
Чат 2
Чат 1
Чат 4
Чат 3
Чат 2 *
Чат 1
Чат 5 *
Login
chatSync = 1472735750977
Синхронизация и
кеширование
Login ACK
chats = […]
chatSync = 1472735812543
Чат 4
Чат 3
Чат 2 *
Чат 1
Чат 5 *
Чат 4
Чат 3
Чат 2 *
Чат 1
Чат 5 *
Синхронизация и
кеширование
Online
Чат 4
Чат 3
Чат 2 *
Чат 1
Чат 5 *
Чат 4
Чат 3
Чат 2 *
Чат 1
Чат 5 *
Кеш сообщений
? ?
Last Message
?ChunkInfoChunkInfo
Закешированные сообщения
Кеш сообщений
? ?
Last Message
?ChunkInfoChunkInfo
Закешированные сообщения
? ? ChunkInfoChunkInfo
Кеш сообщений
? ?
Last Message
?ChunkInfoChunkInfo
Закешированные сообщения
? ? ChunkInfoChunkInfo
? ? ChunkInfoChunkInfo
Реализация
YapDatabase
• Key-Value (“на стероидах”)
• NSCoding или кастомная сериализация
• (нам нравится MessagePack)
• Асинхронность и многопоточность
• Объекты не привязаны к контексту
Инициализация БД
Инициализация БД
Транзакции
YapDatabase
• Модель транзакций и данных — проще
• (субъективно)
• Осторожнее с параллельным доступом
• Обновляем объекты только в рамках одной
транзакции
• Очень просто “реактивизировать” работу с БД
Бесконечный скролл
0
new page
contentOffset
0
Бесконечный скролл
0
new page
contentOffset
0
Бесконечный скролл
• Нужно переворачивать ячейки и быть
аккуратнее с жестами
• Нужно переворачивать индексы в массиве
моделей (пока, секции 🙁)
• Вычисления связанные с contentOffset/Inset
немного взрывают мозг
• При скролле вниз проблема возвращается
Обновление списков
• в одну секунду может идти несколько
обновлений чата:
• подгрузка истории вверх
• новое сообщение
• обновление статуса старых сообщений
(прочитано)
Обновление списков
• Если анимация предыдущего обновления не
кончилась, а следующее обновление уже
поменяло данные (массив моделей ячеек) —
случается креш
• Нужно отложить обновление данных до того
момента как анимация закончится
• UIUpdateQueue
UIUpdateQueue
UIUpdateQueue
Спасибо
Юрий Буянов
“Одноклассники” 2016ok.ru/digal
twitter.com/digal

More Related Content

What's hot

High load++2016.highlights (dropbox+clickhouse)
High load++2016.highlights (dropbox+clickhouse)High load++2016.highlights (dropbox+clickhouse)
High load++2016.highlights (dropbox+clickhouse)Pavel Alexeev
 
Как мы строили аналитическую платформу на несколько миллиардов событии в месяц
Как мы строили аналитическую платформу на несколько миллиардов событии в месяцКак мы строили аналитическую платформу на несколько миллиардов событии в месяц
Как мы строили аналитическую платформу на несколько миллиардов событии в месяцMikhail Tabunov
 
эффективный полнотекстовый поиск по базам данных петр зайцев
эффективный полнотекстовый поиск по базам данных   петр зайцевэффективный полнотекстовый поиск по базам данных   петр зайцев
эффективный полнотекстовый поиск по базам данных петр зайцевMedia Gorod
 
MongoDB первые впечатления
MongoDB первые впечатленияMongoDB первые впечатления
MongoDB первые впечатленияfudz1k
 
ClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
ClickHouse как решение для бизнес аналитики. Дмитрий КузьминClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
ClickHouse как решение для бизнес аналитики. Дмитрий КузьминHOWWEDOIT
 
Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.
Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.
Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.rusonyx
 
Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)
Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)
Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)Ontico
 
Использование различных СУБД в высоконагруженных проектах
Использование различных СУБД в высоконагруженных проектахИспользование различных СУБД в высоконагруженных проектах
Использование различных СУБД в высоконагруженных проектахMedia Gorod
 
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)Ontico
 
24 hop sql_in_to_wa_1c _19march_2014_russian
24 hop sql_in_to_wa_1c _19march_2014_russian24 hop sql_in_to_wa_1c _19march_2014_russian
24 hop sql_in_to_wa_1c _19march_2014_russianMaksim Lemeshko
 
кеширование на высоконагруженном Drupal сайте архаров роман (rus)
кеширование на высоконагруженном Drupal сайте архаров роман (rus)кеширование на высоконагруженном Drupal сайте архаров роман (rus)
кеширование на высоконагруженном Drupal сайте архаров роман (rus)drupalconf
 
NoSQL - взрыв возможностей
NoSQL - взрыв возможностейNoSQL - взрыв возможностей
NoSQL - взрыв возможностейAleksey Solntsev
 
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...Badoo Development
 
CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...
CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...
CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...CodeFest
 
Сайфуллин Сравнение почтовых систем
Сайфуллин Сравнение почтовых системСайфуллин Сравнение почтовых систем
Сайфуллин Сравнение почтовых системLiudmila Li
 

What's hot (16)

High load++2016.highlights (dropbox+clickhouse)
High load++2016.highlights (dropbox+clickhouse)High load++2016.highlights (dropbox+clickhouse)
High load++2016.highlights (dropbox+clickhouse)
 
Как мы строили аналитическую платформу на несколько миллиардов событии в месяц
Как мы строили аналитическую платформу на несколько миллиардов событии в месяцКак мы строили аналитическую платформу на несколько миллиардов событии в месяц
Как мы строили аналитическую платформу на несколько миллиардов событии в месяц
 
эффективный полнотекстовый поиск по базам данных петр зайцев
эффективный полнотекстовый поиск по базам данных   петр зайцевэффективный полнотекстовый поиск по базам данных   петр зайцев
эффективный полнотекстовый поиск по базам данных петр зайцев
 
MongoDB первые впечатления
MongoDB первые впечатленияMongoDB первые впечатления
MongoDB первые впечатления
 
ClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
ClickHouse как решение для бизнес аналитики. Дмитрий КузьминClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
ClickHouse как решение для бизнес аналитики. Дмитрий Кузьмин
 
Анализируем данные с Clickhouse
Анализируем данные с  ClickhouseАнализируем данные с  Clickhouse
Анализируем данные с Clickhouse
 
Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.
Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.
Бизнес-завтрак 20131008. Хостинг для веб-проектов. Юрий Устинов, Русоникс.
 
Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)
Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)
Что нужно знать об архитектуре ClickHouse / Алексей Зателепин (Яндекс)
 
Использование различных СУБД в высоконагруженных проектах
Использование различных СУБД в высоконагруженных проектахИспользование различных СУБД в высоконагруженных проектах
Использование различных СУБД в высоконагруженных проектах
 
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
Промышленное ускорение сайтов / Николай Мациевский (Айри.рф)
 
24 hop sql_in_to_wa_1c _19march_2014_russian
24 hop sql_in_to_wa_1c _19march_2014_russian24 hop sql_in_to_wa_1c _19march_2014_russian
24 hop sql_in_to_wa_1c _19march_2014_russian
 
кеширование на высоконагруженном Drupal сайте архаров роман (rus)
кеширование на высоконагруженном Drupal сайте архаров роман (rus)кеширование на высоконагруженном Drupal сайте архаров роман (rus)
кеширование на высоконагруженном Drupal сайте архаров роман (rus)
 
NoSQL - взрыв возможностей
NoSQL - взрыв возможностейNoSQL - взрыв возможностей
NoSQL - взрыв возможностей
 
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
Доклад Сергея Аверина на DevConf 2013. "Распространенные ошибки применения ба...
 
CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...
CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...
CodeFest 2013. Могелашвили Г. — Мобильные сервисы, блобы и Windows 8. Храним ...
 
Сайфуллин Сравнение почтовых систем
Сайфуллин Сравнение почтовых системСайфуллин Сравнение почтовых систем
Сайфуллин Сравнение почтовых систем
 

Viewers also liked

Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...
Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...
Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...RIF-Technology
 
Вячеслав Черников (Binwell) | Xamarin на практике
Вячеслав Черников (Binwell) | Xamarin на практике Вячеслав Черников (Binwell) | Xamarin на практике
Вячеслав Черников (Binwell) | Xamarin на практике RIF-Technology
 
Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...
Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...
Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...RIF-Technology
 
Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...
Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...
Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...RIF-Technology
 
Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...
Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...
Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...RIF-Technology
 
Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...
Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...
Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...RIF-Technology
 

Viewers also liked (6)

Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...
Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...
Ксения Стернина | (Mail.Ru Group)Gamer Experience Research на различных этапа...
 
Вячеслав Черников (Binwell) | Xamarin на практике
Вячеслав Черников (Binwell) | Xamarin на практике Вячеслав Черников (Binwell) | Xamarin на практике
Вячеслав Черников (Binwell) | Xamarin на практике
 
Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...
Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...
Алексей Раменский (Тэглайн) | Обзор рынка российской заказной веб-разработки ...
 
Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...
Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...
Сергей Смирнов (Altair Engineering Inc.) | Организация работы распределенной ...
 
Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...
Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...
Антон Семенченко | (EPAM Systems, DPI.Solutions )Сравнительный анализ инстру...
 
Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...
Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...
Олег Бунин (Онтико) | Менеджмент и бизнес-процессы в разработке highload-прое...
 

Similar to Юрий Буянов | (Одноклассники)Нюансы разработки мобильного мессенджера

Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)Ontico
 
Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...
Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...
Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...Ontico
 
Vizor Interactive: Технологии успеха
Vizor Interactive: Технологии успехаVizor Interactive: Технологии успеха
Vizor Interactive: Технологии успехаDevGAMM Conference
 
TК°Conf. Организация разработки Frontend. Виталий Слободин.
TК°Conf. Организация разработки Frontend. Виталий Слободин.TК°Conf. Организация разработки Frontend. Виталий Слободин.
TК°Conf. Организация разработки Frontend. Виталий Слободин.TKConf
 
SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...
SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...
SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...SECON
 
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Ontico
 
SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...
SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...
SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...SECON
 
Построение системы аналитики
Построение системы аналитикиПостроение системы аналитики
Построение системы аналитикиИлья Середа
 
Унификация взаимодействия
Унификация взаимодействияУнификация взаимодействия
Унификация взаимодействияNikita Efimov
 
Никита Ефимов Lead UX Architect, New Cloud Technologies
Никита Ефимов Lead UX Architect, New Cloud Technologies Никита Ефимов Lead UX Architect, New Cloud Technologies
Никита Ефимов Lead UX Architect, New Cloud Technologies Anton Anokhin
 
Обзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий НасретдиновОбзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий НасретдиновOntico
 
И снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел ТайкалоИ снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел ТайкалоStanfy
 
Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...Ontico
 
Управление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULT
Управление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULTУправление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULT
Управление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULTКРОК
 
Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...
Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...
Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...Positive Hack Days
 
Well-executed architecture decisions for game backend on Unity
Well-executed architecture decisions for game backend on UnityWell-executed architecture decisions for game backend on Unity
Well-executed architecture decisions for game backend on UnityDevGAMM Conference
 
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017Николай Лавлинский
 
Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)
Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)
Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)Ontico
 

Similar to Юрий Буянов | (Одноклассники)Нюансы разработки мобильного мессенджера (20)

Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
Цикл разработки и внедрения функционала в Мамбе (Михаил Буйлов)
 
Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...
Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...
Как мы храним и анализируем большой социальный граф, Максим Бартенев (Норси-т...
 
Vizor Interactive: Технологии успеха
Vizor Interactive: Технологии успехаVizor Interactive: Технологии успеха
Vizor Interactive: Технологии успеха
 
TК°Conf. Организация разработки Frontend. Виталий Слободин.
TК°Conf. Организация разработки Frontend. Виталий Слободин.TК°Conf. Организация разработки Frontend. Виталий Слободин.
TК°Conf. Организация разработки Frontend. Виталий Слободин.
 
SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...
SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...
SECON'2016. Панин Сергей, Лебедев Андрей, Храмушин Дмитрий, IT-инфраструктура...
 
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
Микросервисы: опыт использования в нагруженном проекте / Вадим Мадисон (М-Тех)
 
SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...
SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...
SECON'2016. Парамонов Сергей, Автоматизируй это! Как не погрязнуть в рутине п...
 
Построение системы аналитики
Построение системы аналитикиПостроение системы аналитики
Построение системы аналитики
 
Унификация взаимодействия
Унификация взаимодействияУнификация взаимодействия
Унификация взаимодействия
 
Sivko
SivkoSivko
Sivko
 
Никита Ефимов Lead UX Architect, New Cloud Technologies
Никита Ефимов Lead UX Architect, New Cloud Technologies Никита Ефимов Lead UX Architect, New Cloud Technologies
Никита Ефимов Lead UX Architect, New Cloud Technologies
 
Обзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий НасретдиновОбзор перспективных баз данных для highload / Юрий Насретдинов
Обзор перспективных баз данных для highload / Юрий Насретдинов
 
И снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел ТайкалоИ снова разработка под iOS. Павел Тайкало
И снова разработка под iOS. Павел Тайкало
 
Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...Машинное обучение в электронной коммерции - практика использования и подводны...
Машинное обучение в электронной коммерции - практика использования и подводны...
 
Управление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULT
Управление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULTУправление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULT
Управление данными и защита от сбоев. Решения КРОК на основе продуктов COMMVAULT
 
Stanfy Fireworks Conf
Stanfy Fireworks ConfStanfy Fireworks Conf
Stanfy Fireworks Conf
 
Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...
Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...
Автоматизация нагрузочного тестирования в связке JMeter + TeamСity + Grafana ...
 
Well-executed architecture decisions for game backend on Unity
Well-executed architecture decisions for game backend on UnityWell-executed architecture decisions for game backend on Unity
Well-executed architecture decisions for game backend on Unity
 
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017
Чеклист по клиентской оптимизации - Лавлинский Николай, РИТ++ 2017
 
Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)
Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)
Чеклист по клиентской оптимизации / Николай Лавлинский (Метод Лаб)
 

Юрий Буянов | (Одноклассники)Нюансы разработки мобильного мессенджера

Editor's Notes

  1. Добрый день Меня зовут Юрий Буянов и я делаю мессенджер в компании "Одноклассники". Сегодня я хочу рассказать вам немного о том, как он устроен внутри.
  2. Для начала — пара слов о том, зачем и для кого мы это всё затеяли. Как и любая другая большая соцсеть, мы хотим дать своим пользователям возможность взаимодействовать друг с другом и с контентом, не покидая привычной среды и социального графа. И если людям хочется использовать для общения с близкими современный удобный мессенджер с анимированными стикерами — надо дать им такую возможность. Забегая вперёд, скажу что идея себя оправдала и средний пользователь мессенджера пишет в три раза больше сообщений, чем средний пользователь, переписывающийся через веб или основное мобильное приложение.
  3. Немного об основных сложностях, с которыми мы столкнулись
  4. Не смотря на то, то мессенджер это отдельное приложение, оно должно было существовать на платформе одноклассников и бесшовно работать с имеющейся системой сообщений. В первую очередь это означает что мы с самого начала должны были поддержать все те типы контента, которые есть в сообщениях одноклассников. Помимо текста и картинок это видео (в том числе живые трансляции), аудио, стикеры, гифки, и т.н. коллажи (то есть, сообщения состоящие из текста и нескольких картинок или видео).
  5. Одноклассники безумно популярны на всей территории России и стран СНГ (и не только), в том числе в местах с нерегулярным покрытием мобильной сети (а иногда и полным отутствием стационарного интернета). В некоторых странах СНГ за пределами крупных городов 2G-соединение вообще является фактически единственным окном в интернет.
  6. Кроме того, многие наши пользователи сомневаются в целесообразности покупки каждый год новой модели айфона или ГОРЯЧЕЙ НОВИНКИ от фирмы "Самсунг". По статистике самыми популярными девайсами под iOS у наших пользователей является iPhone 5s, а под Android — недорогие Galaxy выпуска 2014-2015 годов. Поэтому, одним из самых приоритетных направлений в разработке мессенджера для нас с самого начала была оптимизация приложения как с точки зрения быстродействия, так и с точки зрения работы с сетью.
  7. Быстродействие с точки зрения пользователя это, в первую очередь скорость запуска (куда входит и время до отображения нового контента, например при открытии чата с новым сообщением по пуш-уведомлению) и плавность работы (в частности, скролла). В iOS-команде мы стараемся тестировать и замерять быстродействие на iPhone 5 и iPhone 4S. Андроид-команда имеет в распоряжении такие девайсы, как galaxy s3 и "мегафон логин" за 1000 рублей. Приятным следствием из этого является то, что на более мощных девайсах приложение просто летает.
  8. Помимо субъективного тестирования "на плавность" у нас в каждой тестовой сборке можно включить счётчик ФПС, в логи и в систему статистике записывается длительность выполнения операций в "узких местах". Вот здесь, например, виден график из нашей системы статистики, где показано время с момента запуска приложения при открытии по пушу до момента когда пользователь увидит это конкретное сообщение на экране. Заметное падение на графике — это постепенное включение контент-пушей на пользователей.
  9. Как мы оптимизируем? В первую очередь, мы выносим всё что можно из главного треда: работу с БД (об этом будет чуть ниже), работу с сетью, сериализацию/десериализацию данных, процессинг картинок, и даже вычисления, связанные с вёрсткой текста
  10. При выборе сторонних решений и библиотек в узких местах мы тоже старались учитывать быстродействие и компактность. В частности, именно поэтому мы выбрали MessagePack (причём для iOS специально делали бенчмарк разных реализаций), поменяли библиотеку для маппинга данных в объекты с Mantle на YYModel и остановились на lz4 в качестве алгоритма компрессии трафика.
  11. Кроме того, для достижения плавности работы интерфейса мы симптоматически занимаемся оптимизацией рендеринга (избегаем offcreen рендеринга, нагружающего процессор), заранее в фоне ресайзим картинки (вместо использования работающих в главном потоке стандартных UIViewContentMode), делаем наши иерархии UI более "плоскими и простыми", и стараемся кешировать те объекты и данные, создание которых слишком затратно, начиная с высоты ячеек с текстом, заканчивая YYTextLayout (это объект, который хранит информацию об отображении текста в библиотеке YYText), NSAttributedStrings и даже сами UIViews. Во всех списках используется ручная вёрстка, без auto layout (хотя auto layout мы тоже очень любим и используем декларативную вёрстку в коде, там где это целесообразно).
  12. При работе с сетью мы стараемся минимизировать трафик и задержки за счёт выбора быстрого компактного протокола и агрессивного кеширования. В качестве способа общения с сервером мы используем только TCP-сокеты (с TLS-шифрованием). И бинарный протокол. Это позволяет нам как получать обновления с сервера в реальном времени, так и работать в более привычном режиме "запрос-ответ". Сам API, то есть набор команд поверх низкоуровневого протокола, можно в будущем при желании реализовать и на веб-сокетах, так и улучшить, например, добавив шифрование на уровне пакета.
  13. Сами пакеты состоят из заголовка фиксированной длины, несущего служебную информацию, такую как код команды, версию протокола и длину пэйлоада. Также (поскольку ответы на запросы могут приходить в разном порядке и в перемешку с командами сервера) там есть sequence number, позволяющий связать запрос и ответ. В качестве формата для пэйлоада мы решили попробовать messagepack. Он не требует жёсткого задания схемы, очень компактный и имеет довольно шустрые библиотеки сериализации под кучу платформ. Для того, чтобы снизить потребление трафика ещё сильнее мы сжимаем пэйлоад алгоритмом lz4 (который также выбрали за скорость и небольшую нагрузку на CPU и батарейку).
  14. Схема синхронизации данных довольно простая
  15. После коннекта клиент аутентифицируется, одновременно запрашивая критически важные данные: настройки, список контактов и чатов с последними сообщениями. Мы храним таймстемп последнего обновления (получая его от сервера, конечно) и передаём его в запросе, чтобы получить обратно только то, что действительно поменялось. После того как соединение установлено, мы можем получать обновления в реальном времени (например, новые сообщения или изменения данных контактов).
  16. После коннекта клиент аутентифицируется, одновременно запрашивая критически важные данные: настройки, список контактов и чатов с последними сообщениями. Мы храним таймстемп последнего обновления (получая его от сервера, конечно) и передаём его в запросе, чтобы получить обратно только то, что действительно поменялось. После того как соединение установлено, мы можем получать обновления в реальном времени (например, новые сообщения или изменения данных контактов).
  17. После коннекта клиент аутентифицируется, одновременно запрашивая критически важные данные: настройки, список контактов и чатов с последними сообщениями. Мы храним таймстемп последнего обновления (получая его от сервера, конечно) и передаём его в запросе, чтобы получить обратно только то, что действительно поменялось. После того как соединение установлено, мы можем получать обновления в реальном времени (например, новые сообщения или изменения данных контактов).
  18. После коннекта клиент аутентифицируется, одновременно запрашивая критически важные данные: настройки, список контактов и чатов с последними сообщениями. Мы храним таймстемп последнего обновления (получая его от сервера, конечно) и передаём его в запросе, чтобы получить обратно только то, что действительно поменялось. После того как соединение установлено, мы можем получать обновления в реальном времени (например, новые сообщения или изменения данных контактов).
  19. С историей сообщений в чате всё чуть сложнее. Грузить заранее всю историю всех чатов бессмысленно, но то что мы один раз получили — мы кешируем и стараемся больше не запрашивать. В результате, если посмотреть на то, какие участки истории чата закешированы, мы увидим что в истории есть "разрывы". Например, мы видим что в чате новое последнее сообщение (мы получили его с обновлением списка чатов после логина). Кроме того, у нас есть история, закешированная в ходе прошлой сессии. Таких закешированных кусков истории может быть несколько. Кроме того, что очень неудобно, мы не знаем, сколько сообщений есть на сервере между последним сообщением в чате и предыдущим закешированным сообщением.
  20. Поэтому кроме самих сообщений, мы храним метаданные о непрерывных кусках истории (чанках), которые мы закешировали. При скролле чата мы используем эту информацию, для того чтобы знать, грузить следующую страницу из кеша, или необходимо сделать запрос на сервер (или и то и другое).
  21. При этом чанки меняют размер и сливаются друг с другом. Поскольку приложение под iOS не может постоянно работать в фоне, нам очень помогают контент-пуши: чаше всего, когда пользователь открывает пуш, сообщения в чате уже загружены мы можем их сразу показать пользователю (даже при плохом или отсутсивующем соединении).
  22. При проектировании мы используем подход MVVM, но я не буду делать ещё один 152 доклад про введение в MVVM, расскажу про те вещи, которые оказались новыми именно для нас
  23. В iOS-приложении для кеширования мы используем библиотеку YapDatabase. (Спросить кто знаком) YapDatabase это по сути Key-Value хранилище поверх SQLite с очень большим набором возможностей. Лично мне кажется что она гораздо проще в использовании и гибче, чем CoreData. В частности, можно выбрать механизм сериализации объектов в базе (по умолчанию используется NSCoding, а мы используем тот же MessagePack). YapDatabase не требует наследования объектов от базового класса или реализации какого-то протокола, и не привязывает объекты к контексту. Чтение и запись производятся с помощью синхронных или асинхронных транзакций. При этом доступны все те же возможности, что и в "настоящей" БД, такие как прозвольные SQL-запросы и индексирование нескольких полей, полнотекстовый поиск, подписка на изменения (как в NSFetchedResultsController), etc.
  24. Немного покажу как выглядит работа с YapDatabase. Инициализация соединения, то есть, объекта, который позволяет непосредственно работать с транзакциями занимает буквально две строки.
  25. При необходимости, здесь же можно определить механизм сериализации. (в этом примере испульзуется NSKeyedArchiver, а мы у себя используем MessagePack)
  26. Транзакции делаются при помощи блоков, при этом сделать асинхронную транзакцию в фоне не сложнее чем синхронную. Лично мне YapDatabase очень нравится и повышает продуктивность и понятность кода, но у меня есть несколько коллег, которые её не очень любят. В принципе, их можно понять, поскольку после длительной работы с CoreData для работы с YapDatabase нужно действительно несколько вывернуть мозг.
  27. Кроме того, при асинхронной работе с базой через несколько соединений нужно хорошо понимать как база обрабатывает параллельные запросы на чтение и запись через одно или разные соединения (эта информация есть в вики). А также, помнить что объекты обновляются в БД целиком. Для обновления объекта в БД надо не просто сохранить тот экземпляр, который вы прочитали какое-то время назад и модифицировали, прочитать объект из базы, изменить его так, как вам нужно, и записать обратно в рамках одной транзакции. В противном случае можно случайно записать в БД устаревшие данные. Кроме того, работа с базой очень удобно встраивается в наш реактивный стиль написания кода. Асинхронные шаблоны транзакций (чтение/запись/модификация отдельного объекта) очень просто завернуть, например, в сигналы ReactiveCocoa, и встраивать работу с базой в одну цепочку с обработкой сетевых запросов.
  28. Немного расскажу о паре приёмов, которые мы использовали в iOS-приложении, для того чтобы обойти ограничения системы, которые мешали нам сделать дружелюбный и плавный интерфейс. Одной из проблем стал безконечный скролл в чате, то есть, незаметная для пользователя подгрузка истории при прокрутке чата вверх. В 99% случаев пользователь находится именно внизу чата и хочет проскроллить его вверх для того, чтобы прочитать старые сообщения. Мы не дожидаемся пока пользователь доскроллит до самого верха и увидит там "крутилку", а стараемся заранее запрашивать предыдущие страницы истории ещё во время скролла (как из локального кеша, так и с сервера). Проблема заключается в том, что когда мы вставляем такую страницу в начало списка сообщений, contentOffset того участка, который уже был загружен — сдвигается и скролл скачет. Естественно, мы можем посчитать размер вставляемой страницы и изменить contentOffset обратно, но это (мы же помним, что это происходит во время скролла) приводит к резкой остановке анимации скролла, а это некрасиво.
  29. Чтобы решить эту проблему мы (и не только мы, насколько я знаю, похожее решение используют ещё несколько мессенджеров) применили очень странный "костыль": мы переворачиваем список вверх ногами (с помощью .transform), а затем переворачиваем каждую ячейку в обратном направлении. Пользователь ничего не замечает, но теперь contentOffset отсчитывается снизу и подгрузка старых сообщений никак на него не влияет.
  30. Это решение хорошо работает, но у него есть ряд подводных камней. Во первых, необходимо конвертировать перевёрнутые индексы ячеек в индексы в вашей модели данных (и обратно). В случае, если у вас больше одной секции, вычисления будут очень сложными, так что лучше ограничиться одной. Кроме того, плавающие заголовки работают не очень хорошо (но их можно имитировать). Во вторых, могут возникнуть проблемы с вычислением координат внутри ячеек, наприимер при работе с жестами, но это происходит не очень часто. В третьих — при подгрузке данных вниз проблема возвращается, но поскольку подгрузка при скролле вниз происходит сильно реже, то для нас это не очень большая проблема (хотя хотелось бы решить и её, конечно).
  31. Вторая проблема — это анимированные (и вообще асинхронные) обновления списков. Если несколько независимых обновлений происходят почти одновременно (например, подгружается страница истории вверху чата и приходит новое сообщение внизу), то данные, используемые делегатом tableView могут измениться в момент, когда не закончилась анимация предыдущего обновления. Это может привести к тому, что UITableView отрендерит неправильную ячейку или вообще упадёт (особенно, если вы используете предыдущий хак). Можно, конечно использовать метод reloadData, который является синхронным в UITableView, однако это приводит к морганиям, остановке скролла, и прочим раздражающим пользователя вещам
  32. Специально для таких случаев мы сделали специальную очередь для последовательной обработки таких обновлений. Все изменения модели и отображение их на UI производятся внутри блоков, которые ставятся в очередь. При этом блок может залочить очередь при старте анимации (или какой-то другой асинхронной операции) и разлочить её при завершении. Таким образом, вся работа с таблицей производится последовательно и данные не меняются, пока не завершится предыдущая анимация.