Статьи

Автоматизация настройки обратного прокси-сервера Nginx

proxyautomation

Очень хорошо, если вы можете отделить свой внешний API от деталей разделения и развертывания приложений.

В предыдущем посте я объяснил некоторые преимущества использования обратного прокси . В моем текущем проекте мы создаем распределенную сервис-ориентированную архитектуру, которая также предоставляет HTTP API, и мы используем обратный прокси-сервер для маршрутизации запросов, адресованных нашему API, отдельным компонентам. Мы выбрали отличный веб-сервер Nginx в качестве нашего обратного прокси-сервера; это быстро, надежно и легко настраивается. Мы используем его для объединения нескольких сервисов, предоставляющих API-интерфейсы HTTP, в одно пространство URL. Так, например, когда вы печатаете:

http://api.example.com/product/pinstripe_suit

Он направляется на:

http://10.0.1.101:8001/product/pinstripe_suit

Но когда вы идете в:

http://api.example.com/customer/103474783

Он направляется в

http://10.0.1.104:8003/customer/103474783

Потребителю API кажется, что он исследует единое пространство URL ( http://api.example.com/blah/blah ), но за кулисами разные сегменты верхнего уровня URL-адреса маршрутизируют на разные внутренние серверы , / product /… направляется к 10.0.1.101:8001, но / customer /… направляется к 10.0.1.104:8003.

Мы также хотим, чтобы это было самостоятельной настройкой. Итак, скажем, я хочу создать новый компонент системы, который регистрирует уровни запасов. Вместо того, чтобы расширять существующий компонент, я хочу иметь возможность написать автономный исполняемый файл или службу, которая предоставляет конечную точку HTTP, автоматически развернуть ее на одном из хостов в моей облачной инфраструктуре и автоматически направлять запросы Nginx по адресу http. : //api.example.com/stock/ что бы то ни было для моего нового компонента.

Мы также хотим сбалансировать нагрузку этих сервисов. Возможно, мы захотим развернуть несколько экземпляров нашего нового API, и Nginx автоматически циклически перебирает между ними.

Мы называем каждый сегмент верхнего уровня (/ акции, / продукт, / клиент) претензией. Компонент публикует сообщение AddApiClaim через RabbitMQ, когда он появляется в сети. Это сообщение имеет 3 поля: «Заявка», «ipAddress» и «Номер_порта». У нас есть специальный компонент, ProxyAutomation, который подписывается на эти сообщения и переписывает конфигурацию Nginx по мере необходимости. Он использует SSH и SCP для входа на сервер Nginx, передачи различных файлов конфигурации и дает Nginx команду перезагрузить свою конфигурацию. Мы используем отличную библиотеку SSH.NET, чтобы автоматизировать это.

Отличная вещь в конфигурации Nginx — это подстановочные знаки. Взгляните на наш файл конфигурации верхнего уровня:

...

  

 http {

     include       /etc/nginx/mime.types;

     default_type  application/octet-stream;

  

     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

                       '$status $body_bytes_sent "$http_referer" '

                       '"$http_user_agent" "$http_x_forwarded_for"';

  

     access_log  /var/log/nginx/access.log  main;

  

     sendfile        on;

     keepalive_timeout  65;

  
     include /etc/nginx/conf.d/*.conf;

 }

В строке 16 написано: возьмите любой файл * .conf в каталоге conf.d и добавьте его сюда.

Внутри conf.d находится один файл для всех запросов api.example.com:

include     /etc/nginx/conf.d/api.example.com.conf.d/upstream.*.conf;

  

 server {

     listen          80;

     server_name     api.example.com;

  

     include         /etc/nginx/conf.d/api.example.com.conf.d/location.*.conf;

  

     location / {

         root    /usr/share/nginx/api.example.com;

         index   index.html index.htm;

     }

 }

Это в основном говорит, что прослушивает порт 80 для любых запросов с заголовком узла «api.example.com».

Это включает в себя два включает. Первый в строке 1, я расскажу позже. В строке 7 написано «взять любой файл с именем location. *. Conf в подкаталоге« api.example.com.conf.d »и добавить его в конфигурацию. Наш прокси-компонент автоматизации добавляет новые компоненты (заявления AKA API), удаляя новые файлы location. *. Conf в этом каталоге. Например, для нашего компонента stock он может создать файл location.stock.conf, например:

location /stock/ {

     proxy_pass http://stock;

 }

Это просто говорит Nginx о необходимости проксировать все запросы, адресованные api.example.com/stock/…, к вышестоящим серверам, определенным в ‘stock’. Вот где упоминается другое упомянутое выше «upstream. *. Conf». Компонент автоматизации прокси также помещает файл с именем upstream.stock.conf, который выглядит примерно так:

 upstream stock {

     server 10.0.0.23:8001;

     server 10.0.0.23:8002;

 }

Это говорит Nginx о необходимости округлять все запросы к api.example.com/stock/ для указанных сокетов. В этом примере это два компонента на одном компьютере (10.0.0.23), один на порту 8001, а другой на порту 8002.

По мере развертывания экземпляров фондового компонента новые записи добавляются в upstream.stock.conf. Точно так же, когда компоненты удаляются, запись удаляется. Когда последняя запись удаляется, весь файл также удаляется.

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