Путь от монолита на php к микросервисам на scala / Денис...

Post on 06-Jan-2017

1.904 Views

Category:

Engineering

5 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Путь от монолита на PHP кмикросервисам на ScalaИванов Денис

2gis.ru

2GIS WebAPI

Данные

3

Данные

•  8 стран

•  300 городов

•  50 тыс населенных пунктов

4

Данные

•  8 стран

•  300 городов

•  50 тыс населенных пунктов

•  5 млн организаций

5

Данные

•  8 стран

•  300 городов

•  50 тыс населенных пунктов

•  5 млн организаций

•  50 млн гео-объектов

И еще много всего

6

Нагрузка

7

Нагрузка

•  30 млн. пользователей в месяц

8

Нагрузка

•  30 млн. пользователей в месяц

•  2000 RPS

9

Нагрузка

•  30 млн. пользователей в месяц

•  2000 RPS

•  3 датацентра

10

Одна нода•  16 CPU

•  16 GB RAM

•  Минимальная нагрузка - 50%

11

Проблемы

13

Проблемы

•  Долго работают скрипты (95% - 500ms)

14

Проблемы

•  Долго работают скрипты (95% - 500ms)

•  Невозможно параллельно, многопоточно выполнять какие-то задачи

15

Проблемы

•  Долго работают скрипты (95% - 500ms)

•  Невозможно параллельно, многопоточно выполнять какие-то задачи

•  Приложение - один большой кусок, который нужно выкатывать очень

часто и целиком

16

Проблемы

•  Долго работают скрипты (95% - 500ms)

•  Невозможно параллельно, многопоточно выполнять какие-то задачи

•  Приложение - один большой кусок, который нужно выкатывать очень

часто и целиком

•  Кеширование не спасает

17

Проблемы

•  Долго работают скрипты (95% - 500ms)

•  Невозможно параллельно, многопоточно выполнять какие-то задачи

•  Приложение - один большой кусок, который нужно выкатывать очень

часто и целиком

•  Кеширование не спасает

•  Много команд разработчиков, сервисов, интеграций

18

Проблемы

•  Долго работают скрипты (95% - 500ms)

•  Невозможно параллельно, многопоточно выполнять какие-то задачи

•  Приложение - один большой кусок, который нужно выкатывать очень

часто и целиком

•  Кеширование не спасает

•  Много команд разработчиков, сервисов, интеграций

•  Много тестов, которые долго работают

19

Решения

20

Решения

•  Поддерживать существующее и жить дальше

21

Решения

•  Поддерживать существующее и жить дальше

•  Переписать всё нафиг

22

Решения

•  Поддерживать существующее и жить дальше

•  Переписать всё нафиг

•  Подумать и распилить приложение на независимые куски

23

Севисная архитектура (SOA)— модульный подход к разработке программного обеспечения,

основанный на использовании распределённых, слабо связанных

заменяемых компонентов, оснащённых стандартизированными

интерфейсами для взаимодействия по стандартизированным

протоколам

24

Микросервисная архитектура• Малый размер

• Тонкое масштабирование

• Быстрый деплой

• Лёгкость тестирования (Мок)

• Любой язык

25

Микросервисная архитектура• Десятки приложений вместо одного

• Сложность интеграционного тестирования

26

Поехали!

Shipyard

•  https://shipyard-project.com/

•  Котейнеры

•  Образы

•  Реестры

•  Ноды

•  Логи

•  Консоль

38

Consul

•  https://www.consul.io/

•  Дискаверинг

•  Key-value

•  Проверки

•  DNS

39

Consul-template

•  https://github.com/hashicorp/consul-template

41

Consul-template

{{range tree "service/redis@east-aws"}}

{{.Key}} {{.Value}}{{end}}

42

Cadvisor

•  https://github.com/google/cadvisor

43

Схема работы

Router

{

"route": "/api/1.0/some/method",

"chain": [

...

]

}

53

Router chain

{ "key": "ms4",

"method": "/api/0.0.1/ms4",

"data": {},

"timeout": 2000,

"maxRetries": 0,

"isVital": true,

"waitFor": ["ms1", "ms2"] }

54

Базовый образ для контейнера•  Ubuntu ~500мб, deb-пакеты

59

Базовый образ для контейнера•  Ubuntu ~500мб, deb-пакеты

•  BusyBox ~50мб, нет пакетов

60

Java SDK

61

Java SDK•  Gradle

62

Java SDK•  Gradle

•  Jetty

63

Java SDK•  Gradle

•  Jetty

•  BoneCP

64

Java SDK•  Gradle

•  Jetty

•  BoneCP

•  JDBC

65

STOP!

Как распилить?

67

Как распилить?•  Выделить каждую группу методов в отдельный сервис

68

Как распилить?•  Выделить каждую группу методов в отдельный сервис

•  Начать с самого мелкого и несвязного сервиса

69

Как распилить?•  Выделить каждую группу методов в отдельный сервис

•  Начать с самого мелкого и несвязного сервиса

•  Постепенно выделять сервисы, переходя к более крупным

70

Прототип

71

Прототип

•  Тяжелый метод - поисковый запрос, запросы в БД, формирование

2000 маркеров с хешами, куча json-а

72

Прототип

•  Тяжелый метод - поисковый запрос, запросы в БД, формирование

2000 маркеров с хешами, куча json-а

•  PHP, PHP7, Java, Scala

73

Прототип

•  Тяжелый метод - поисковый запрос, запросы в БД, формирование

2000 маркеров с хешами, куча json-а

•  PHP, PHP7, Java, Scala

•  SLA - 95% за 300ms

74

Бенчмарк

75

Бенчмарк

Реализация SLA Смерть

php 30 rps 40 rps

php7 70 rps 80 rps

java 160 rps 180 rps

scala 180 rps 200 rps

76

Scala vs Java

77

Scala vs Java•  Те же библиотеки + свои

78

Scala vs Java•  Те же библиотеки + свои

•  Меньше кода, чем на Java

79

Scala vs Java•  Те же библиотеки + свои

•  Меньше кода, чем на Java

•  Много success-story в микросервисах

80

Scala vs Java•  Те же библиотеки + свои

•  Меньше кода, чем на Java

•  Много success-story в микросервисах

•  Асинхронность и многопоточность намного проще из коробки +

сторонние библиотеки

81

Scala vs Java•  Те же библиотеки + свои

•  Меньше кода, чем на Java

•  Много success-story в микросервисах

•  Асинхронность и многопоточность намного проще из коробки +

сторонние библиотеки

•  В компании есть несколько команд, использующих Scala на

продакшене

82

Интеграция

Библиотечки

87

Библиотечки

•  Spray

88

Библиотечки

•  Spray

•  Spray json

89

Библиотечки

•  Spray

•  Spray json

•  Typesafe config

90

Библиотечки

•  Spray

•  Spray json

•  Typesafe config

•  Akka

91

Библиотечки

•  Spray

•  Spray json

•  Typesafe config

•  Akka

•  HikariCP

92

Библиотечки

•  Spray

•  Spray json

•  Typesafe config

•  Akka

•  HikariCP

•  JDBC

93

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.

94

Spray jsoncase 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.

95

Typesafe configdatabases {

catalog {

host = "127.0.0.1"

port = 5432

timeout = 5s

}

}

01.

02.

03.

04.

05.

06.

07.

96

Инвентарь

97

Инвентарь

•  Scala - основной язык для микросервисов

98

Инвентарь

•  Scala - основной язык для микросервисов

•  TeamCity - сборка и деплой

99

Инвентарь

•  Scala - основной язык для микросервисов

•  TeamCity - сборка и деплой

•  Ansible - деплой

100

Тестирование

101

Тестирование

•  Функциональные и интеграционные тесты на ваш продукт, которые у

вас должны быть

102

Тестирование

•  Функциональные и интеграционные тесты на ваш продукт, которые у

вас должны быть

•  Для нагрузки - yandex tank, gatling

103

Тестирование

•  Функциональные и интеграционные тесты на ваш продукт, которые у

вас должны быть

•  Для нагрузки - yandex tank, gatling

•  Для реверс-инжиниринга - gor

104

Тестирование

•  Функциональные и интеграционные тесты на ваш продукт, которые у

вас должны быть

•  Для нагрузки - yandex tank, gatling

•  Для реверс-инжиниринга - gor

•  Простой скрипт, кидающий запрос на 2 хоста и делающий diff

105

Стало

106

Стало

•  Сборка - 2 минуты

107

Стало

•  Сборка - 2 минуты

•  Тесты (с нагрузкой) - 5-10 минут

108

Стало

•  Сборка - 2 минуты

•  Тесты (с нагрузкой) - 5-10 минут

•  Деплой - 5 минут

109

Стало

•  Сборка - 2 минуты

•  Тесты (с нагрузкой) - 5-10 минут

•  Деплой - 5 минут

•  Серверов - 6 вместо 18 (по 2 в каждом ДЦ)

110

Одна нода•  4 CPU

•  4 GB RAM

•  Средняя нагрузка - 5%

•  Максимальная нагрузка - 30%

111

Грабли

112

Грабли

•  CORS

113

Грабли

•  CORS

•  gzip

114

Что дальше?

115

Что дальше?•  Продолжать распиливать сервисы

116

Что дальше?•  Продолжать распиливать сервисы

•  Двигаться к поставленной цели (к "идеалу")

117

Итоги

118

Итоги

•  Поменьше велосипедов

119

Итоги

•  Поменьше велосипедов

•  Ставьте себе четкие, достижимые цели в короткий срок

120

Итоги

•  Поменьше велосипедов

•  Ставьте себе четкие, достижимые цели в короткий срок

•  Делайте задачи итеративно

121

Итоги

•  Поменьше велосипедов

•  Ставьте себе четкие, достижимые цели в короткий срок

•  Делайте задачи итеративно

•  Решайте проблемы по мере из возникновения

122

Итоги

•  Поменьше велосипедов

•  Ставьте себе четкие, достижимые цели в короткий срок

•  Делайте задачи итеративно

•  Решайте проблемы по мере из возникновения

•  Преждевременная оптимизация - зло

123

Вопросы?

Иванов Денис

dv.ivanov@2gis.ru

124

top related