Slide 1

Slide 1 text

Один кликстрим на все бэкенды Внедрение инструментария для отправки аналитических событий в php, go, python Дмитрий Хасанов, Avito

Slide 2

Slide 2 text

Сервисная архитектура Avito облако CI/CD сервис демонок крончик 2

Slide 3

Slide 3 text

Общие задачи логи загрузка файлов метрики сервис демонок крончик 3

Slide 4

Slide 4 text

Кликстрим ● клик ● просмотр ● оплата ● сообщение в мессенджере ● поисковый запрос ● рекламный аукцион 4

Slide 5

Slide 5 text

Готовые решения ● Google Analytics ● Яндекс Метрика 5

Slide 6

Slide 6 text

Кликстрим Событие Хранилище Отчёт 6

Slide 7

Slide 7 text

Кликстрим Событие Хранилище Отчёт 7

Slide 8

Slide 8 text

Кликстрим Событие Хранилище Отчёт “clickstream_event”: { “event_id”: 100, “user”: { “id”: 413, “email”: “user@example.com” }, “geo”: { “latitude”: 20.220, “longitude”: -10.110 }, “user_agent”: “fluffy_browser”, “time”: “2018-04-11 22:37:05” } 8

Slide 9

Slide 9 text

Кликстрим Событие Хранилище Отчёт DWH 9

Slide 10

Slide 10 text

Простая реализация Проект A event = { ‘field_one’: ‘val_1’, ‘field_two’: ‘val_2’, ‘time’: unixtime() } transport.send(event) 10 Проект Б event = { ‘fieldOne’: ‘val_1’, ‘field.TWO’: ‘val_2’, ‘time’: date() } customTransport.send(event)

Slide 11

Slide 11 text

Простая реализация Плюсы: ● быстро получаем отчёт ● легко реализовать Минусы: ● бардак ● затраты ресурсов ● трудно переиспользовать код 11

Slide 12

Slide 12 text

Источники событий Бэкенды: ● монолит: php ● сервисы: go, python, php ● кроны, демоны: go, python, php, shell 12

Slide 13

Slide 13 text

Источники событий Бэкенды: ● монолит: php ● сервисы: go, python, php ● кроны, демоны: go, python, php, shell Фронтенды: js 13

Slide 14

Slide 14 text

Источники событий Бэкенды: ● монолит: php ● сервисы: go, python, php ● кроны, демоны: go, python, php, shell Фронтенды: js Мобильные приложения: swift, java 14

Slide 15

Slide 15 text

Источники событий Бэкенды: ● монолит: php ● сервисы: go, python, php ● кроны, демоны: go, python, php, shell Фронтенды: js Мобильные приложения: swift, java Внешние проекты: c#, java 15

Slide 16

Slide 16 text

Путь события сервис демонок крончик DWH транспорт 16

Slide 17

Slide 17 text

Путь события фронтенд сайта внешний проект мобильное приложение DWH транспорт прокси 17

Slide 18

Slide 18 text

Реестр событий ● окружения ● события ● поля ● метаинформация 18

Slide 19

Slide 19 text

Кодогенерация ● лангпак php, go, python ● отправщик событий в DWH ● автодокументация 19

Slide 20

Slide 20 text

Лангпак ● геттеры, сеттеры ● общая логика 20 class EventOne: def setFieldOne(string value): self.fields[“one”] = value def getFieldOne() -> string: return self.fields[“one”] def getTime() -> Timestamp: return time.now() def getData() -> EventData: return self.fields

Slide 21

Slide 21 text

Отправщик событий 21 сервис демонок крончик DWH транспорт

Slide 22

Slide 22 text

Пример лангпака package someproject type SomeEventV0 struct { *event } func NewSomeEventV0() *SomeEventV0 { e := &SomeEventV0{ event: new( 420, `user@example.org`, `lindows`, ), } e.required["user_id"] = struct{}{} e.required["email"] = struct{}{} e.required["os"] = struct{}{} return e } 22

Slide 23

Slide 23 text

Версионирование событий ● нельзя ломать код на бою ● нельзя удалять ● новая версия события на каждое изменение 23

Slide 24

Slide 24 text

Версионирование лангпаков ● нельзя ломать код на бою ● новая версия на каждое изменение кода лангпака 24

Slide 25

Slide 25 text

Получение лангпака ● php composer install reestr/langpack ● go, python curl \ -d '{"environment":"bo"}' \ -H "Content-Type: application/json" \ http://reestr/langpack/go/0/ | tar x 25

Slide 26

Slide 26 text

Отправка событий ● php $clickstreamSender->send($event); ● go err := clickstreamSender.Send(event) ● python clickstream_sender.send(event) 26

Slide 27

Slide 27 text

Протохитрости 27 фронтенд сайта внешний проект мобильное приложение DWH транспорт прокси

Slide 28

Slide 28 text

Протохитрости Мобильные приложения message MobileAppEvent { int32 eventId = 1; int32 version = 2; int32 timestamp = 3; map params = 4; } 28 Сторонние проекты message ExternalProjectEvent { int32 someIntField = 1; string someStringField = 2; bool someBoolFied = 3; }

Slide 29

Slide 29 text

Объекты event = { ‘scalar_field’: ‘some_string’, ‘object_field’: { ‘inner_scalar’: 3.14, ‘inner_object’: { … } } } 29 Плюсы: ● наборы объектов Комплексность: ● лангпаки ● админка реестра ● валидация

Slide 30

Slide 30 text

Административности ● идентификация владельцев событий ● отслеживание девиаций: технических, логических ● вывод из эксплуатации неиспользуемых событий ● интеграция в работающие проекты 30

Slide 31

Slide 31 text

Настоящее ● десятки источников ● более тысячи версий событий ● логируется около двух миллиардов событий в сутки 31

Slide 32

Slide 32 text

Будущее ● ускорение создания событий ● нативные пакеты с лангпаками для python и go ● статус отправки события ● доменная модель компонентов 32

Slide 33

Slide 33 text

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