Распределенные системы. Паттерны проектирования - страница 19

стр.

redis:

listen: 127.0.0.1:6379

hash: fnv1a_64

distribution: ketama

auto_eject_hosts: true

redis: true

timeout: 400

server_retry_timeout: 2000

server_failure_limit: 1

servers:

- sharded-redis-0.redis:6379:1

- sharded-redis-1.redis:6379:1

- sharded-redis-2.redis:6379:1

Из  конфигурационного  файла  видно,  что  запросы  к  Redis  об-служиваются по адресу  localhost:6379 , так что контейнер прило-жения может получить доступ к контейнеру-послу. Его можно  развернуть  в  «посольскую»  группу  контейнеров,  используя  Kubernetes-объект  ConfigMap ,  который  можно  создать  такой  командой:

kubectl create configmap twem-config --from-file=./nutcracker.yaml Подготовительные  мероприятия  завершены,  и  можно  развер-нуть наш пример реализации паттерна Ambassador. Определяем  группу контейнеров следующим образом:

apiVersion: v1

kind: Pod

metadata:

name: ambassador-example

Глава 3. Паттерн Ambassador 57

spec:

containers:

# Сюда необходимо подставить имя контейнера приложения, например: # - name: nginx

# image: nginx

# Здесь указываем имя контейнера-посла

- name: twemproxy

image: ganomede/twemproxy

command:

- "nutcracker"

- "-c"

- "/etc/config/nutcracker.yaml"

- "-v"

- "7"

- "-s"

- "6222"

volumeMounts:

- name: config-volume

mountPath: /etc/config

volumes:

- name: config-volume

configMap:

name: twem-config

Сначала в группе объявляется контейнер-посол, а конкретный  контейнер приложения может быть внедрен в нее позже. Использование паттерна Ambassador для реализации сервиса-посредника В попытке обеспечить переносимость приложения между раз-ными средами (публичным облаком, физическим центром об-работки  данных  либо  частным  облаком)  основной  проблемой  становится обнаружение и конфигурирование сервисов. Чтобы  понять,  что  это  значит,  представьте  себе  клиентский  модуль,  хранящий  данные  в  базе  данных  MySQL.  В  публичном  об-лаке такая база предоставлялась бы по схеме «ПО как сервис»  (software-as-a-service, SaaS). В частном облаке, однако же, может  58 Часть I. Одноузловые паттерны проектирования

потребоваться  динамически  «поднять»  новую  виртуальную  машину или контейнер с MySQL.

Следовательно,  переносимое  приложение  должно  иметь  воз-можность изучить свое окружение и найти подходящий MySQL-сервер. Такой процесс называется  обнаружением сервисов  (service  discovery), а система, которая выполняет обнаружение и стыковку,  называется  сервисом-посредником  (service broker). Как и в преды-дущих  примерах,  использование  паттерна  Ambassador  позволяет  отделить  логику  контейнера  приложения  от  логики  контейнера-посла  сервиса-посредника.  Приложение  просто  подключается  к  экземпляру  сервиса  (например,  MySQL),  работающему  на  ло-кальном компьютере. Обязанность контейнера-посла сервиса-по-средника заключается в обследовании окружения и опосредова-нии  подключения  к  конкретному  экземпляру  целевого  сервиса.  Данный процесс показан на рис. 3.3.

Рис. 3.3. Контейнер-посол сервиса-посредника создает экземпляр MySQL-сервиса

Глава 3. Паттерн Ambassador 59

Использование пат терна Ambassador для проведения экспериментов и разделения запросов

Последний  пример  приложения  с  использованием  паттерна  Ambassador  —  реализация  экспериментов  и  других  видов  раз-деления  запросов.  В  эксплуатируемых  системах  важно  иметь  возможность разделения запросов, когда некоторая часть запро-сов обрабатывается не основным рабочим сервисом, а его аль-тернативной  реализацией.  Чаще  всего  его  используют,  чтобы  проводить эксперименты с новыми или бета-версиями сервиса  для  определения  степени  надежности  и  производительности  новой версии сервиса по сравнению с существующей. Кроме  того,  разделение  запросов  иногда  используется  для  ду-блирования  или  деления  трафика  таким  образом,  что  он  рас-пределяется  как  на  рабочую  версию  ПО,  так  и  на  новую,  еще  не развернутую.

Ответы рабочей системы возвращаются пользователю, а ответы  новой версии сервиса игнорируются. Чаще всего такое деление  запросов применяется, когда необходимо сымитировать реаль-ную рабочую нагрузку на сервис, не рискуя повлиять на работу  пользователей текущей версии.