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

стр.

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

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

Такое разделение ответственности позволяет четко ограничить  функциональность  и  размер  кода  приложений,  содержащихся  в контейнерах. Разделение приложения на модули дает возмож-ность использовать контейнер с делителем запросов во многих  разных приложениях и с различными настройками. Практикум. Реализация 10%-ных экспериментов

Для эксперимента с разделением запросов воспользуемся веб-сервером nginx. Nginx — мощный, многофункциональный веб-сервер с открытым исходным кодом. Чтобы сконфигурировать  nginx для применения в контейнере-после, воспользуемся сле-дующей конфигурацией (обратите внимание, что она рассчита-на на HTTP, но ее легко адаптировать под HTTPS): worker_processes 5;

error_log error.log;

pid nginx.pid;

worker_rlimit_nofile 8192;

events {

worker_connections 1024;

}

http {

upstream backend {

ip_hash;

server web weight=9;

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, а также требовать соблюдения любых  других соглашений.