Путь от монолита на PHP к
микросервисам на Scala
Иванов Денис
2gis.ru
2GIS WebAPI
Данные
•  8 стран
•  300 городов
•  50 тыс населенных пунктов
•  5 млн организаций
•  50 млн гео-объектов
И еще много всего
3
Нагрузка
•  30 млн. пользователей в месяц
•  2000 RPS
•  3 датацентра
4
Одна нода
•  16 CPU
•  16 GB RAM
•  Минимальная нагрузка - 50%
5
Проблемы
•  Долго работают скрипты (95% - 500ms)
•  Невозможно параллельно, многопоточно выполнять какие-то задачи
•  Приложение - один большой кусок, который нужно выкатывать очень
часто и целиком
•  Кеширование не спасает
•  Много команд разработчиков, сервисов, интеграций
•  Много тестов, которые долго работают
7
Решения
•  Поддерживать существующее и жить дальше
•  Переписать всё нафиг
•  Подумать и распилить приложение на независимые куски
8
Севисная архитектура (SOA)
— модульный подход к разработке программного обеспечения,
основанный на использовании распределённых, слабо связанных
заменяемых компонентов, оснащённых стандартизированными
интерфейсами для взаимодействия по стандартизированным
протоколам
9
Микросервисная архитектура
•   Малый размер
•   Тонкое масштабирование
•   Быстрый деплой
•   Лёгкость тестирования (Мок)
•   Любой язык
10
Микросервисная архитектура
•   Десятки приложений вместо одного
•   Сложность интеграционного тестирования
11
Поехали!
Shipyard
•  https://shipyard-project.com/
23
Consul
•  https://www.consul.io/
29
Consul-template
•  https://github.com/hashicorp/consul-template
31
Consul-template
{{range tree "service/redis@east-aws"}}
{{.Key}} {{.Value}}{{end}}
32
Cadvisor
•  https://github.com/google/cadvisor
33
Router
{
"route": "/api/1.0/some/method",
"chain": [
...
]
}
42
Router chain
{ "key": "ms4",
"method": "/api/0.0.1/ms4",
"data": {},
"timeout": 2000,
"maxRetries": 0,
"isVital": true,
"waitFor": ["ms1", "ms2"] }
43
Базовый образ для контейнера
•  Ubuntu ~500мб, deb-пакеты
•  BusyBox ~50мб, нет пакетов
48
Java SDK
•  Gradle
•  Jetty
•  BoneCP
•  JDBC
49
STOP!
Как распилить?
•  Выделить каждую группу методов в отдельный сервис
•  Начать с самого мелкого и несвязного сервиса
•  Постепенно выделять сервисы, переходя к более крупным
51
Прототип
•  Тяжелый метод - поисковый запрос, запросы в БД, формирование
2000 маркеров с хешами, куча json-а
•  PHP, PHP7, Java, Scala
•  SLA - 95% за 300ms
52
Бенчмарк
Реализация SLA Смерть
php 30 rps 40 rps
php7 70 rps 80 rps
java 160 rps 180 rps
scala 180 rps 200 rps
53
Scala vs Java
•  Те же библиотеки + свои
•  Меньше кода, чем на Java
•  Много success-story в микросервисах
•  Асинхронность и многопоточность намного проще из коробки +
сторонние библиотеки
•  В компании есть несколько команд, использующих Scala на
продакшене
54
Интеграция
Библиотечки
•  Spray
•  Spray json
•  Typesafe config
•  Akka
•  HikariCP
•  JDBC
59
Spray
path("api" / "1.0" / "some" / "method") {
parameters('id.as[String]) { id =>
val response = DoSomeWork(id)
onSuccess(response) { content =>
complete(content)
}
}
}
01.
02.
03.
04.
05.
06.
07.
08.
60
Spray json
case class User(name: String, isOk: Boolean)
implicit val UserFormatter = jsonFormat2(User)
val json = """{"name": "Denis", "isOk": true}"""
val user = json.parseJson.convertTo[User]
01.
02.
03.
04.
05.
06.
07.
61
Typesafe config
databases {
catalog {
host = "127.0.0.1"
port = 5432
timeout = 5s
}
}
01.
02.
03.
04.
05.
06.
07.
62
Инвентарь
•  Scala - основной язык для микросервисов
•  TeamCity - сборка и деплой
•  Ansible - деплой
63
Тестирование
•  Функциональные и интеграционные тесты на ваш продукт, которые у
вас должны быть
•  Для нагрузки - yandex tank, gatling
•  Для реверс-инжиниринга - gor
•  Простой скрипт, кидающий запрос на 2 хоста и делающий diff
64
Стало
•  Сборка - 2 минуты
•  Тесты (с нагрузкой) - 5-10 минут
•  Деплой - 5 минут
•  Серверов - 6 вместо 18 (по 2 в каждом ДЦ)
65
Грабли
•  CORS
•  gzip
66
Что дальше?
•  Продолжать распиливать сервисы
•  Двигаться к поставленной цели (к "идеалу")
67
Итоги
•  Поменьше велосипедов
•  Ставьте себе четкие, достижимые цели в короткий срок
•  Делайте задачи итеративно
•  Решайте проблемы по мере из возникновения
•  Преждевременная оптимизация - зло
68
Вопросы?
Иванов Денис
dv.ivanov@2gis.ru
69

«Путь от монолита на PHP к микросервисам на Scala» – Денис Иванов, 2ГИС