
Сложные серверные приложения могут включать десятки и сотни микросервисов, которые могут как предоставлять точки подключения для клиентов, так и взаимодействовать между собой и своими хранилищами данных. Естественным образом при развертывании таких приложений приходится решать две задачи: как поддерживать сервисы в работоспособном состоянии (здесь может помочь Kubernetes или любая другая система оркестрации) и как их регистрировать и связывать с префиксами или адресами публикации для внешних клиентов? Также весьма остро встает вопрос мониторинга взаимодействия микросервисов и организации нагрузочных тестов как на отдельные сервисы, так и на целые группы.
В этой статье мы обсудим использование оператора Istio для координации микросервисов и инструмента для нагрузочного тестирования Fortio, который может использоваться также и для тестирования произвольных сервисов под высокой нагрузкой.
Прежде всего, дадим определение Service Mesh — это подход к организации взаимодействия группы микросервисов, когда между ними создается посредник, который решает вопросы наблюдения за трафиком, аутентификации и аудита, отслеживания доступности, балансировки нагрузки и мониторинга системы. Одним из решений для Kubernetes, которое реализует Service Mash является Istio. Кроме непосредственно регистрации сервисов и присоединения их к точкам публикации для внешних клиентов и взаимодействия микросервисов (здесь используется Ingress-контроллер Envoy), Istio обеспечивает отслеживание запросов (Tracing) и замеры времени обработки запроса (и отслеживания всей цепочки вызовов, которые связаны с запросом клиента), контроль доступа между микросервисами и управление трафиком (с использованием расширяемой системы для определения политик доступа).
Первым делом установим инструмент управления Istio (istioctl) и настроим тестовое приложение:
curl -L https://istio.io/downloadIstio | sh - mv istio*/ /usr/local/lib/istio/ export PATH=/usr/local/lib/istio:$PATH istioctl install --set profile=demo -y kubectl label namespace default istio-injection=enabled kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.15/samples/bookinfo/platform/kube/bookinfo.yaml kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.15/samples/bookinfo/networking/bookinfo-gateway.yaml kubectl get svc istio-ingressgateway -n istio-system https://raw.githubusercontent.com/istio/istio/release-1.15/samples/addons/prometheus.yaml https://raw.githubusercontent.com/istio/istio/release-1.15/samples/addons/grafana.yaml https://raw.githubusercontent.com/istio/istio/release-1.15/samples/addons/jaeger.yaml https://raw.githubusercontent.com/istio/istio/release-1.15/samples/addons/kiali.yaml istioctl dashboard kiali
После установки будут развернуты несколько микросервисов (в пространство имен default) и зарегистрированы соответствующие сервисы и правила доступа из внешней сети (через Ingress), адрес которого нам будет необходим для выполнения нагрузочного тестирования. В завершение будут установлены дополнения для мониторинга трафика и системы и запущена веб-панель с возможностью наблюдения за взаимосвязью микросервисов и прохождением трафика. Для нас будут наиболее важны метрики нагрузки на микросервисы (Workloads — Traces, Workloads — Inbound metrics), а также информация о количестве запросов к отдельным микросервисам (Graph — Inbound).
Для проверки нагрузки мы будем использовать внешнюю точку подключения /productpage. Рассмотрим теперь возможности инструмента нагрузочного тестирования fortio. Одной из важных особенностей fortio является возможность удаленного управления процессом, создающим нагрузку, что позволяет запускать имитацию высокой нагрузки непосредственно в облаке или использовать ферму с несколькими процессами для создания распределенной нагрузки. Fortio может также работать внутри других приложений на Go, поскольку может быть собран как библиотека и выполняться в составе кода интеграционного тестирования. Также вариант сборки сервера (docker-контейнер fortio/fortio) предоставляет минималистичный веб-интерфейс для запуска тестов и исследования их результатов, а также для управления очередью тестов через REST API.
Процесс Fortio может быть запущен в одном из следующих режимов:
-
server— предоставляет веб-интерфейс (на порт 8080) и API (порт 8079) для удаленного запуска тестов -
report— сервер с отчетами о тестировании (без возможности запуска новых тестов) -
load— запустить нагрузочное тестирование на указанный адрес
При запуске теста можно дополнительно передать заголовки (-H), изменить количество параллельных потоков выполнения (-c) и количество запросов в секунду (-qps), общее количество запросов (-n) или время выполнения теста (-t). Результатом тестирования будет построение гистограмм и определение статистических замеров (min, max, 50, 75, 90, 99 и 99.9 перцентиль), также результаты могут быть сохранены в json (-a), при этом важно примонтировать к контейнеру внешний каталог на путь, указанный в -data-dir. Дополнительно можно указать идентификатор запуска (например может совпадать с номером сборки при автоматическом запуске в сборочном конвейере) через -runid, она будет добавлен к названию файла json. Также можно тестировать не только http, но и tcp, udp и socket-подключения, а также gRPC-сервисы (-grpc). Кроме оценки количества успешных запросов (которые можно скоррелировать с информацией от kiali) также можно собирать профили использовать процессора и памяти (наиболее актуально при локальном тестировании или встраивании теста непосредственно в тестовые сценарии).
Особое внимание уделяется возможности проксирования запросов на несколько точек, например это может быть важно при распределенной системе и необходимости проверки разных внешних адресов в одном тесте (-M определяет http-прокси-сервер, -P используется для tcp/udp-прокси, они могут использоваться как цель тестирования и будет пересылать запросы на указанные endpoint) и смещению запросов между параллельно запущенными подключениями (-jitter делает случайное отклонение, -uniform — применяет нормальное распределение для группы клиентов). Также можно добавлять дополнительный данные для запроса (—payload или —payload-file).
Для автоматического запуска теста можно использовать REST API (на сервере /fortio/rest/run с передачей json, при этом могут одновременно выполняться несколько сценариев нагрузочного тестирования). Остановить выполнение теста можно через /fortio/rest/stop, посмотреть текущее состояние выполнения через /fortio/rest/status. Например, для тестирования развернутого сервиса (в предположении, что в GATEWAY_URL будет записан адрес и порт публикации Ingress) можно использовать следующий запрос:
curl -v -d '{"metadata": {"url":"$GATEWAY_URL/", "c":"4", "qps":"10000", "t": 10, "async":"on", "save":"on"}}' \ "localhost:8080/fortio/rest/run?jsonPath=.metadata"
Посмотреть статус выполнения можно с помощью запроса:
curl -v "localhost:8080/fortio/rest/status"
В отчете по результатам нагрузочного тестирование будет информация о времени выполнения запроса (минимальное, максимальное, среднее), запрошенном и реальном количестве обработанных запросов («RequestedQPS», «ActualQPS»).
Также библиотека может использоваться в коде проектов на Go через импорт fortio.org/fortio. Так, для тестирования http-сервисов, можно импортировать fortio.org/fortio/fhttp и запустить тест с передачей необходимых опций для runner:
ro := periodic.RunnerOptions{ QPS: qps, Duration: *durationFlag, NumThreads: *numThreadsFlag, Percentiles: percList, Resolution: *resolutionFlag, Out: out, Labels: labels, Exactly: *exactlyFlag, Jitter: *jitterFlag, Uniform: *uniformFlag, RunID: *bincommon.RunIDFlag, Offset: *offsetFlag, NoCatchUp: *nocatchupFlag, } httpOpts := bincommon.SharedHTTPOptions() o := fhttp.HTTPRunnerOptions{ HTTPOptions: *httpOpts, RunnerOptions: ro, Profiler: *profileFlag, AllowInitialErrors: *allowInitialErrorsFlag, AbortOn: *abortOnFlag, } res, err = fhttp.RunHTTPTest(&o)
Таким образом, тесты функционирования системы под высокой нагрузкой могут быть интегрированы в сценарии тестирования при сборке (через использовании библиотеки), запущены на тестовых серверах в облаке (через REST-запросы), а также объединены с информацией из панели Istio для моделирования ситуацию аномальной нагрузки и определения узкого места в цепочке микросервисов.
Приглашаем всех желающих на открытое занятие, на котором познакомимся с паттернами декомпозиции системы на микросервисы. Также рассмотрим технические и бизнесовые подходы к декомпозиции. Регистрация доступна по ссылке.
ссылка на оригинал статьи https://habr.com/ru/company/otus/blog/686924/
Добавить комментарий