Как стать автором
Обновить
1057.28
OTUS
Цифровые навыки от ведущих экспертов

Microservice mesh и тестирование под высокой нагрузкой

Время на прочтение6 мин
Количество просмотров3.2K

Сложные серверные приложения могут включать десятки и сотни микросервисов, которые могут как предоставлять точки подключения для клиентов, так и взаимодействовать между собой и своими хранилищами данных. Естественным образом при развертывании таких приложений приходится решать две задачи: как поддерживать сервисы в работоспособном состоянии (здесь может помочь 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 для моделирования ситуацию аномальной нагрузки и определения узкого места в цепочке микросервисов.


Приглашаем всех желающих на открытое занятие, на котором познакомимся с паттернами декомпозиции системы на микросервисы. Также рассмотрим технические и бизнесовые подходы к декомпозиции. Регистрация доступна по ссылке.

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
Всего голосов 8: ↑8 и ↓0+8
Комментарии1

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS