Распределенные системы. Паттерны проектирования - [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. Одноузловые паттерны проектирования
Мониторинг
Хотелось бы иметь унифицированное решение, позволяющее автоматически обнаруживать любые приложения, развернутые в некоторой среде, и наблюдать за их состоянием. Чтобы это стало возможным, каждое приложение должно реализовывать один и тот же интерфейс мониторинга.