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

Шрифт
Интервал

server experiment;

}

server {

listen localhost:80;

location / {

proxy_pass http://backend;

}

}

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

так, вы добавляете еще один сервис, который нужно поддерживать, масштабировать, мониторить и т. д. Если есть вероятность, что экспериментирование укоренится в вашей архитектуре, в таком решении может быть смысл. Если оно применяется скорее время от времени, то более осмысленным будет использование контейнера-посла на Обратите  внимание,  что  в  данной  конфигурации  я  использую  хеширование IP. Оно необходимо для того, чтобы пользователь  не задействовал попеременно то основную, то тестовую версию  сервиса.  Благодаря  этому  пользователи  будут  взаимодейство-

вать с приложением единообразно.

Весовой коэффициент используется, чтобы 90 % трафика при-ходилось на основное приложение, а 10 % — на тестовую версию. Как и в других примерах, мы будем разворачивать данную кон-фигурацию как объект  ConfigMap  в Kubernetes. kubectl create configmaps --from-file=nginx.conf Она исходит из того, что сервисы web и experiment уже опре-делены.  Если  это  не  так,  то  вам  необходимо  их  создать  до  создания  контейнера-посла,  поскольку  nginx  не  запустится  корректно,  если  не  сможет  найти  сервисы,  которым  он  про-ксирует запросы.

Вот несколько примеров конфигурации:

# Сервис 'experiment'

apiVersion: v1

kind: Service

metadata:

name: experiment

62 Часть I. Одноузловые паттерны проектирования

labels:

app: experiment

spec:

ports:

- port: 80

name: web

selector:

# Установите значение данного селектора в соответствии # с метками вашего приложения

app: experiment

---

# Сервис 'prod'

apiVersion: v1

kind: Service

metadata:

name: web

labels:

app: web

spec:

ports:

- port: 80

name: web

selector:

# Установите значение этого селектора в соответствии # с метками вашего приложения

app: web

Затем разворачиваем nginx в роли посла в рамках контейнера: apiVersion: v1

kind: Pod

metadata:

name: experiment-example

spec:

containers:

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

# - name: some-name

# image: some-image

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

- name: nginx

image: nginx

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

volumeMounts:

- name: config-volume

mountPath: /etc/nginx

volumes:

- name: config-volume

configMap:

name: experiment-config

Чтобы  воспользоваться  контейнером-послом  в  полной  мере,  в группу можно добавить еще один или несколько контейнеров. 4> Адаптеры

В предыдущих главах мы рассмотрели, как с помощью паттерна  Sidecar  расширять  и  дополнять  существующие  контейнеры  приложений. Мы также разобрали, как контейнеры-послы мо-гут опосредовать и даже изменять способ взаимодействия кон-тейнера с внешним миром. В этой главе описывается последний  одноузловой паттерн —  Adapter . В его рамках  контейнер-адап-тер  модифицирует программный интерфейс  контейнера прило-жения  таким образом, чтобы он соответствовал некоему заранее  определенному  интерфейсу,  реализация  которого  ожидается  от  всех  контейнеров  приложений.  К  примеру,  адаптер  может  обеспечивать реализацию унифицированного интерфейса мони-торинга. Или же он может обеспечивать то, что файлы журнала  всегда выводятся в stdout, а также требовать соблюдения любых  других соглашений.

Разработка реальных приложений — тренировка по построению  гетерогенных,  гибридных  систем.  Одни  части  вашего  прило-жения  могут  быть  написаны  вашей  командой  с  нуля,  другие  Глава 4. Адаптеры 65

получены  от  поставщиков,  третьи  —  вообще  быть  готовыми  проприетарными  решениями  или  решениями  с  открытым  ко-дом,  используемыми  в  виде  двоичных  исполняемых  файлов.  Совокупный  эффект  такой  гетерогенности  состоит  в  том,  что  любое реальное приложение, которое вам приходилось или при-дется развертывать, написано на множестве языков и с учетом  разных  соглашений  относительно  ведения  файлов  журнала,  мониторинга и других подобных общих задач. Но для того, чтобы эффективно следить за работой приложения  и управлять им, нужны общие интерфейсы. Когда каждое при-ложение  выводит  показатели  в  разных  форматах  посредством  разных  интерфейсов,  очень  тяжело  собирать  их  для  визуали-зации и уведомления о нештатных ситуациях. Именно в такой  ситуации и уместен паттерн Adapter. Как и другие одноузловые  паттерны, паттерн Adapter состоит из модульных контейнеров.  Разные  контейнеры  приложений  могут  предоставлять  разные  интерфейсы для мониторинга, а контейнер-адаптер подстраива-ется под гетерогенность среды с целью унификации интерфейса.  Это позволяет разворачивать единственный инструмент, зато-ченный под этот конкретный интерфейс. Рисунок 4.1 обобщен-но иллюстрирует данный паттерн.

Рис. 4.1. Обобщенный паттерн Adapter

Далее в главе мы рассмотрим несколько приложений паттерна  Adapter.

66 Часть I. Одноузловые паттерны проектирования

Мониторинг

Хотелось  бы  иметь  унифицированное решение,  позволяющее  автоматически обнаруживать любые приложения, развернутые  в  некоторой  среде,  и  наблюдать за  их  состоянием. Чтобы  это  стало возможным, каждое приложение должно реализовывать  один и тот же интерфейс мониторинга.