You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
+ Повышенные требования к Continuous Integration/Continuous Delivery (деплою)
237
237
238
238
Непрерывная интеграция (CI) — процесс автоматического принятия изменений. Первичный процесс обновления ПО, в рамках которого все изменения на уровне кода вносятся в единый центральный репозиторий. Такое внесение принято называть слиянием. После каждого слияния (которое проходит по несколько раз в день) в изменяемой системе происходит автоматическая сборка (часто приложение упаковывается в Docker) и тестирование (проверка конкретных модулей кода, UI, производительности, надёжности API). Таким образом разработчики страхуются от слишком поздних обнаружений проблем в обновлениях.
239
+
+ Возможность локальной сборки проекта
240
+
+ На каждый коммит в кдаленный репо запускаем сборки проекта в системе (Jenkins, TravisCI)
241
+
+ Сломанная сборка запрещает слияние
242
+
239
243
Непрерывная доставка (CD) — CI + CD. Автоматизированый процесс доставки изменений до продакшена. Теперь новая версия не только создаётся и тестируется при каждом изменении кода, регистрируемом в репозитории, но и может быть оперативно запущена по одному нажатию кнопки развёртывания. Однако запуск развёртывания всё ещё происходит вручную — ту самую кнопку всё же надо кому-то нажать. Этот метод позволяет выпускать изменения небольшими партиями, которые легко изменить или устранить в случае необходимости.
Микросервисы могут работать одновеременно с разными диалектами БД. При этом есть __сильная согласованность__, когда изменения сразу видны всем, с момента их применения и __конечная согласованность__ когда изменения будут видно, но не сразу, а доставляются асинхронно
360
+
361
+
__Сильная согласованность__ - всегда актуальные данные, но высокие задержки при получении
362
+
363
+
В таких случаях используются __Распределенные транзакции__. Но это сложно, дорого и есть не везде. Можно эмулировать распределенную транзакцию с помощью вложенных локальных транзакций
При этом возврат ошибки не гарантирует, что запись не была вставленна в БД. А откат первой транзакции не приводит к откату второй.
367
+
368
+
Saga паттерн: Для решения нужно разбивать одну большую распределенную транзакцию на последовательность локальных транзакций и предоставить возможность отката всех локальных транзакций.
Иногда требуется выполнять какой-то процесс эксклюзивно. Например используя распределенный консенсус - алгоритмы, которые сложно и медленно работают. etcd, Consul, Zookeeper. Зато отказоустойчивы
395
+
396
+
Альтернатива - red lock, когда БД используется в качестве хранилища блокировок. Блокировка не захватывается, а арендуется на время. Чтобы в случае блокировки и отказа системы блокировка не осталась навсегда Добавляем версию блокировки для контроля ее корректности
Swagger - это фреймворк для спецификации RESTful API, цель которого - поддерживать документацию в актуальном виде. Его прелесть заключается в том, что он дает возможность не только интерактивно просматривать спецификацию, но и отправлять запросы – так называемый Swagger UI.
407
+
408
+
+ Code first - сначала пишем код, потом генерируем спецификацию
409
+
+ Schema first - сперва спецификация, затем генерируем по ней код
410
+
+ Публикуем спецификацию (отделный артефак или Swagger)
411
+
+ Строго следовать этой спецификации
412
+
413
+
Документирование БД
414
+
Database Schema as a Code - текущая схема должна быть представлена последовательностью патчей, хранимых как код
415
+
416
+
+ Возможность восстановить БД на любом окружении
417
+
+ Аудит, контроль, валидация
418
+
+ Flyway, Liquibase
419
+
420
+
[к оглавлению](#ООП)
421
+
422
+
## Тестирование микросервисов
423
+
+ Компонентные для тестирования логики приложения
424
+
+ Модульные для тестирования вычислений
425
+
+ Компонентных должно быть больше, чем модульных, т.к. изменяемая среда, много зависимочти между классами
426
+
427
+
Тесты должны быть независимыми и уметь работать параллельно. Тесты не должны очищать БД или буффер брокера сообщений перед/после своего запуска/завершения
428
+
429
+
Для тестирования API лучше делать реальные HTTP вызовы, валидировать ответ согласно схеме (JSON). RESTAssured как пример инструмента.
430
+
431
+
При тестирование взаимодействия с БД на каждый запуск тестов локально поднимается БД. Embedded или TestContainers
432
+
433
+
При тестировании взаимодействия микросервисов на каждый запуск тестов локально HTTP-сервер, создаем моки операций сервисов, выполняем, моки валидируем. WireMock, MockServer
434
+
435
+
При тестировании аинхронных процессов стараемся приблизить тестовый сценарий к реальному, запускаем операцию и ждем завершения выполнения. Awaitility
436
+
437
+
Для автоматизации развиваем Continuous Integration/Continuous Delivery - помогает быстрее развивать сервисы и доставлять их на production. Но дорого.
438
+
439
+
[к оглавлению](#ООП)
440
+
441
+
## Распределенная трассировка
442
+
При межсервисном взаимодействии сложно отследить весь путь запроса по системе
443
+
+ К каждому внешнему запрсос прикрепляем "идентификатор операции"
444
+
+ Пробрасываем его по всей системе
445
+
+ Добавляем его в логовые сообщения для отслеживания. Elastic APM, OpenTracing
446
+
447
+
Для HTTP: Прикрепляем HTTP-заголовок с этим идентификатором - Используем его при обработке запроса - Поллинг делаем с тем же индентификаторо - Обраный вызов с ним же - В брокер сообщений также отправляем этот индентификатор
448
+
449
+
Для Саги: Исходный запрос теряется при обработке асинхронных процессов - В задачу на продолжение саги кладем исходный идентификатор операции (в БД) - При возобновлении саги используем этот идентификатор
353
450
451
+
Визуализация трасс помогает построить схему взаимодействия между сервисами. Можно это делать атоматически и динамически. Zipkin, Jaeger
__Модульное/компонентное тестирование (unit testing)__ - процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы. Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже оттестированных местах программы, а также облегчает обнаружение и устранение таких ошибок.
Проверяет функциональность и ищет дефекты в частях приложения, которые доступны и могут быть протестированы по-отдельности (модули программ, объекты, классы, функции и т.д.). Обычно проводится вызывая код, который необходимо проверить и при поддержке сред разработки, таких как фреймворки (frameworks - каркасы) для модульного тестирования или инструменты для отладки.
29
+
30
+
По-существу компонентные и модульные тестирования представляют одно и тоже, разница лишь в том, что в компонентном тестировании в качестве параметров функций используют реальные объекты и драйверы, а в модульном тестировании - конкретные значения.
31
+
32
+
[к оглавлению](#Тестирование)
33
+
24
34
## Что такое _«интеграционное тестирование»_?
25
35
__Интеграционное тестирование (integration testing)__ — это тестирование, проверяющие работоспособность двух или более модулей системы в совокупности — то есть нескольких объектов как единого блока. В тестах взаимодействия же тестируется конкретный, определенный объект и то, как именно он взаимодействует с внешними зависимостями.
0 commit comments