Skip to content

Commit d3a05a6

Browse files
author
eugene.kalashnikov
committed
Рефакторинг ООП, добавил инфу про микросервисы и картинки
1 parent 2b5718c commit d3a05a6

File tree

10 files changed

+109
-0
lines changed

10 files changed

+109
-0
lines changed

img/OOP10.png

140 KB
Loading

img/OOP11.png

194 KB
Loading

img/OOP12.png

284 KB
Loading

img/OOP13.png

162 KB
Loading

img/OOP14.png

431 KB
Loading

img/OOP8.png

184 KB
Loading

img/OOP9.png

94.9 KB
Loading

img/Test1.png

79.2 KB
Loading

oop.md

+99
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,13 @@ __Принцип инверсии зависимостей (DIP)__<br>
236236
+ Повышенные требования к Continuous Integration/Continuous Delivery (деплою)
237237

238238
Непрерывная интеграция (CI) — процесс автоматического принятия изменений. Первичный процесс обновления ПО, в рамках которого все изменения на уровне кода вносятся в единый центральный репозиторий. Такое внесение принято называть слиянием. После каждого слияния (которое проходит по несколько раз в день) в изменяемой системе происходит автоматическая сборка (часто приложение упаковывается в Docker) и тестирование (проверка конкретных модулей кода, UI, производительности, надёжности API). Таким образом разработчики страхуются от слишком поздних обнаружений проблем в обновлениях.
239+
+ Возможность локальной сборки проекта
240+
+ На каждый коммит в кдаленный репо запускаем сборки проекта в системе (Jenkins, TravisCI)
241+
+ Сломанная сборка запрещает слияние
242+
239243
Непрерывная доставка (CD) — CI + CD. Автоматизированый процесс доставки изменений до продакшена. Теперь новая версия не только создаётся и тестируется при каждом изменении кода, регистрируемом в репозитории, но и может быть оперативно запущена по одному нажатию кнопки развёртывания. Однако запуск развёртывания всё ещё происходит вручную — ту самую кнопку всё же надо кому-то нажать. Этот метод позволяет выпускать изменения небольшими партиями, которые легко изменить или устранить в случае необходимости.
244+
+ Поддерживаем артефакты стабильными
245+
+ Развертываем по кнопке
240246

241247
Сложности проектирования Микросервисов
242248
+ Сложно разделить предметную область на части
@@ -350,7 +356,100 @@ __Способы взаимодействия__
350356
На основе polling: Kafka
351357
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP7.png)
352358

359+
Микросервисы могут работать одновеременно с разными диалектами БД. При этом есть __сильная согласованность__, когда изменения сразу видны всем, с момента их применения и __конечная согласованность__ когда изменения будут видно, но не сразу, а доставляются асинхронно
360+
361+
__Сильная согласованность__ - всегда актуальные данные, но высокие задержки при получении
362+
363+
В таких случаях используются __Распределенные транзакции__. Но это сложно, дорого и есть не везде. Можно эмулировать распределенную транзакцию с помощью вложенных локальных транзакций
364+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP8.png)
365+
366+
При этом возврат ошибки не гарантирует, что запись не была вставленна в БД. А откат первой транзакции не приводит к откату второй.
367+
368+
Saga паттерн: Для решения нужно разбивать одну большую распределенную транзакцию на последовательность локальных транзакций и предоставить возможность отката всех локальных транзакций.
369+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP9.png)
370+
371+
Особенности: нужно уметь восстанавливаться после сбоев любого участка и повторять сагу с определенного шага + отличать финальные ошибки от нефинальных
372+
Хореография
373+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP10.png)
374+
375+
+ Нет единой точки отказа
376+
+ Легко менять кусочек процесса
377+
+ Сложно понять процесс целиком и отслеживать ошибки
378+
379+
Оркестрация
380+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP11.png)
381+
382+
+ Есть единая точка отказа
383+
+ Сложнее вносить изменения в места
384+
+ Легко понять процесс и отслеживать ошибки
385+
386+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP12.png)
387+
388+
__Конечная согласованность__ - могут быть неактуальные данные, зато низкие задержки
389+
390+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP13.png)
391+
392+
__Взаимоисключения__
393+
394+
Иногда требуется выполнять какой-то процесс эксклюзивно. Например используя распределенный консенсус - алгоритмы, которые сложно и медленно работают. etcd, Consul, Zookeeper. Зато отказоустойчивы
395+
396+
Альтернатива - red lock, когда БД используется в качестве хранилища блокировок. Блокировка не захватывается, а арендуется на время. Чтобы в случае блокировки и отказа системы блокировка не осталась навсегда Добавляем версию блокировки для контроля ее корректности
397+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/OOP14.png)
398+
399+
[к оглавлению](#ООП)
400+
401+
## OpenAPI
402+
OpenAPI - спецификация для описания REST API.
403+
404+
https://habr.com/ru/post/541592/
405+
406+
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+
Для Саги: Исходный запрос теряется при обработке асинхронных процессов - В задачу на продолжение саги кладем исходный идентификатор операции (в БД) - При возобновлении саги используем этот идентификатор
353450

451+
Визуализация трасс помогает построить схему взаимодействия между сервисами. Можно это делать атоматически и динамически. Zipkin, Jaeger
452+
354453
[к оглавлению](#ООП)
355454

356455
# Источники

test.md

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Тестирование
44
+ [Что такое _«модульное тестирование»_?](#Что-такое-модульное-тестирование)
5+
+ [Что такое _«компонентное тестирование»_?](#Что-такое-компонентное-тестирование)
56
+ [Что такое _«интеграционное тестирование»_?](#Что-такое-интеграционное-тестирование)
67
+ [Чем интеграционное тестирование отличается от модульного?](#Чем-интеграционное-тестирование-отличается-от-модульного)
78
+ [Какие существуют виды тестовых объектов?](#Какие-существуют-виды-тестовых-объектов)
@@ -10,6 +11,8 @@
1011
+ [Какие аннотации фикстур существуют в JUnit?](#Какие-аннотации-фикстур-существуют-в-junit)
1112
+ [Для чего в JUnit используется аннотация `@Ignore`?](#Для-чего-в-junit-используется-аннотация-ignore)
1213

14+
![Image alt](https://github.com/Shell26/Java-Developer/raw/master/img/Test1.png)
15+
1316
## Что такое _«модульное тестирование»_?
1417
__Модульное/компонентное тестирование (unit testing)__ - процесс в программировании, позволяющий проверить на корректность отдельные модули исходного кода программы. Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже оттестированных местах программы, а также облегчает обнаружение и устранение таких ошибок.
1518

@@ -21,6 +24,13 @@ __Модульное/компонентное тестирование (unit tes
2124

2225
[к оглавлению](#Тестирование)
2326

27+
## Что такое _«компонентное тестирование»_?
28+
Проверяет функциональность и ищет дефекты в частях приложения, которые доступны и могут быть протестированы по-отдельности (модули программ, объекты, классы, функции и т.д.). Обычно проводится вызывая код, который необходимо проверить и при поддержке сред разработки, таких как фреймворки (frameworks - каркасы) для модульного тестирования или инструменты для отладки.
29+
30+
По-существу компонентные и модульные тестирования представляют одно и тоже, разница лишь в том, что в компонентном тестировании в качестве параметров функций используют реальные объекты и драйверы, а в модульном тестировании - конкретные значения.
31+
32+
[к оглавлению](#Тестирование)
33+
2434
## Что такое _«интеграционное тестирование»_?
2535
__Интеграционное тестирование (integration testing)__ — это тестирование, проверяющие работоспособность двух или более модулей системы в совокупности — то есть нескольких объектов как единого блока. В тестах взаимодействия же тестируется конкретный, определенный объект и то, как именно он взаимодействует с внешними зависимостями.
2636

0 commit comments

Comments
 (0)