Upload
sasha-soleev
View
85
Download
2
Embed Size (px)
Citation preview
Однажды одна выдуманная команда разработчиков собралась вместе и решила попробовать микросервисы.
Эта выдуманная история расскажет о трудностях, которые встретились у смелых разработчиков на пути и об отваге, с которой эти трудности преодолевались.
Все совпадения случайны, мнение автора может не совпадать с мнением других выдуманных участников истории.
Автор не несет ответственности за возможный сдвиг парадигмы у слушателей и вообще считает его очень полезным для развития.
Сячин Максим
Место работы: Luxoft SPB Заказчик: Почта России
Опыт разработки: 11 лет Java, C++, Kotlin, Scala
twitter: @finnetrolle github: finnetrolle
МикросервисыПервая кровь
70100
19900
План нашей встречи• Проблемы на старте разработки
• Проблемы во время разработки
• Проблемы при тестировании
• А что взамен?
Микросервисы могут быть настолько же эффективны, насколько они обязательно
окажутся сложны.
Начало проектакогда одно решение определяет дальнейшую историю
Монолит Микросервисы
Simplicity Partial deployment
Consistency Availability
Inter-module refactoring Preserve modularity
Multiple platforms
Monolith vs MicroservicesС чего лучше начинать?
Monolith vs MicroservicesС чего лучше начинать?
Monolith vs MicroservicesС чего лучше начинать?
Monolith vs MicroservicesС чего лучше начинать?
Monolith Firstнеоднозначное решение
• Нет влияния на функциональные требования, в следствие чего не выделяются ресурсы на рефакторинг
• Монолит провоцирует высокую связанность, отделять микросервисы тем сложнее, чем старше монолит
Деление на микросервисынесколько сложнее, чем разрезание пиццы
N-layer архитектура
Presentation Layer
Business Layer
Data Access Layer
Web application
Business logic microservice
Data microservice
Однородные команды разработки
UI разработчики
Backend разработчики
DBA
– M. Conway
« Организация которая разрабатывает систему ... вынуждена делать систему по
структуре повторяющую структуру коммуникаций внутри организации»
Гетерогенные команды разработки
Управление финансами
Склад
CRM
Don't repeat yourselfили как избавиться от преимуществ микросервисов
Библиотека common
Ваше первое и основное
приложение
Модуль A
Модуль B
Модуль C
Utils
Utils
Utils
Common
Библиотека common
Приложение А
common
Приложение B Приложение C
A + B B + C
A + C A+B+C
Приложение А новая версия
Приложение B новая версия
Приложение C новая версия
common
Библиотека common, DTO и клиенты
App 5 DTOApp 4DTO
App 2 DTO App 3 DTOApp 1DTO
Один большой и очень умный
common
клиент для App 1клиент для App 2клиент для App 3клиент для App 4клиент для App 5
DTO
клиент для App 5
Общая библиотека common стала
умнееApp 5
App 3App 2App 1
App 4
Библиотека с общим APIКлиентские приложения
Умный балансировщик
Оплата через Капут-банк
Оплата через Банк "Гибкость"
Капут-банк Банк "Гибкость"
REST
REST REST
Оплата common
Библиотека с общим API
DTO оплаты
Общий API
Умный Балансировщик
Оплата через Капут-банк
Оплата через Банк "Гибкость"
Стандартный протокол оплаты Особенность оплаты
через "Гибкость"
DTO оплаты
Общий API
Умный Балансировщик
Оплата через Банк "Гибкость"
Оплата через Капут-банк
Собственный фасад для REST клиента
Jersey client
Собственный REST клиент
client.post(PATH) .withParam("id", id) .withBody(body) .forEntityOf(Resp.class) .orElseThrow(RestError::new)
Клиент к приложению А
Приложение B Приложение C Приложение D
Собственный REST клиент
DTO для приложения А
Собственный REST клиент
client.post(PATH) .withParam("id", id) .withBody(body) .forResponse(Resp.class) .orElseThrow(RestError::new)
Клиент к приложению А
Приложение B Приложение C Приложение D
Собственный фасад для REST клиента
Jersey client
Собственный REST клиент
Клиент к приложению А
Приложение B Приложение C Приложение D
Собственный REST клиент
DTO для приложения А
client.post(PATH) .withParam("id", id) .withBody(body) .forResponse(Resp.class) .orElseThrow(RestError::new)
Собственный REST клиент
Клиент к приложению А
Приложение B
Client v. 1.0.1 Client v. 1.0.0 Client v. 1.0.0
Собственный фасад для REST клиента
Приложение А
Приложение B
Приложение C
Приложение D
Приложение E
Client A v 1.0.1
Client A v 1.0.23
Client A v 1.2.10
Советы по DRY
• Старайтесь обойтись в библиотеках без доменных объектов
• Сильное сцепление и низкая связанность уменьшат потребность в разделяемых библиотеках
• Используйте стабильные библиотеки
ИнтеграцияКошмар поддержки чужих изменений
DTO Hell
Приложение "Каталог двигателей"
engines-dto
Приложение "Страховка"
Приложение "Ремонт авто"
Приложение "Автоподбор для
клиента"
Приложение "Оценка авто"
Приложение "Конструктор"
DTO Hell
Приложение "Каталог двигателей"
engines-dto
Приложение "Страховка"
Приложение "Ремонт авто"
С++ QTПриложение
"Автоподбор для клиента"
Приложение "Оценка авто"
Приложение "Конструктор"
Композитный response{ "id":18, "model":"Rav4", "engines":[ {"name":"4m40", "power":200, "id":101}, {"name":"100kz", "power":250, "id":287} ], "exteriors":[ {"color":"BLACK", "type":"BASIC", "id":334}, {"color":"WHITE", "type":"BASIC", "id":422}, {"color":"WHITE", "type":"DULL", "id":451} ], "transmissions":[ {"type":"AUTO", "gears":5, "id":334}, {"type":"AUTO", "gears":6, "id":335}, {"type":"MANUAL","gears":5, "id":354} ] }
Композитный response{ "id":18, "model":"Rav4", "engines":[ {"name":"4m40", "power":200, "id":101}, {"name":"100kz", "power":250, "id":287} ], "exteriors":[ {"color":"BLACK", "type":"BASIC", "id":334}, {"color":"WHITE", "type":"BASIC", "id":422}, {"color":"WHITE", "type":"DULL", "id":451} ], "transmissions":[ {"type":"AUTO", "gears":5, "id":334}, {"type":"AUTO", "gears":6, "id":335}, {"type":"MANUAL","gears":5, "id":354} ] }
Какие автоматические коробоки передач поставляются с Toyota Rav4?
http://someurl.com/api/vehicle/18
Композитный response
[ {"type":"AUTO", "gears":5, "id":334}, {"type":"AUTO", "gears":6, "id":335} ]
Какие автоматические коробоки передач поставляются с Toyota Rav4?
http://someurl.com/api/vehicle/18/transmissions?type=AUTO
Советы по интеграции
• Паттерн Expand and Contract
• Семантика версий [major.minor.patch]
• Protobuf, Thrift
– Джон Постел
«Будь либерален к тому, что принимаешь, и требователен к тому, что отсылаешь».
Сложности тестированиячто работает само по себе не обязательно заработает
в связке с соседями
Воссоздание окружения для тестирования
Приложение, которое надо протестировать
Какой-нибудь HTTP клиент
(PAW, SoapUI)Локальная СУБД
Это приложение поставляет нам
данныеКстати, ему тоже
нужна СУБД
И еще одно приложение, тоже со своей СУБД
А это приложение стороннего
разработчика и висит в интернете
Проблема асинхронных сервисов
Приложение, которое надо протестировать
Какой-нибудь HTTP клиент
(PAW, SoapUI)
Стороннее приложение, висящее
в интернете и работающее в
асинхронном режиме
Как воссоздаем?
• Dummy внутри микросервиса (активируется настройкой)
• Запуск сервисов с данными
• Отладочные прокси (Fiddler)
• Dummy микросервисы
Собираем логи
Разбираемся с логами
• Elasticsearch + Logstash + Kibana
• Elasticsearch + FluentD + Kibana
• Сторонние сервисы (Loggly, Papertrail)
• Logging to stdout + docker logs
История успехаПозитивные моменты разработки
Проверка и внедрение новых технологий
High maintainability• Быстро входишь в контекст небольшого сервиса даже после длительного перерыва
• Меньше путаного кода
• Изменения в одном сервисе редко задевают другие
• Задачи, затрагивающие несколько сервисов, легко делятся на подзадачи
Высокая надежность
• Stateless сервисы легко масштабируются горизонтально
• Healthcheck + мониторинг + быстрый запуск позволяют не бояться падения приложения
• Пока идет знакомство с микросервисами, разработка сложна, а последствия неверных решений раздражают
• По мере взросления технологии, все больше внимания уделяется задаче, а не бойлерплейту
• Однажды наступает момент, когда в ответ на список новых требований вы просто запускаете новый микросервис
Спасибо за внимание!Настало время вопросов