FastCGI

Материал из Национальной библиотеки им. Н. Э. Баумана
Последнее изменение этой страницы: 21:10, 10 декабря 2016.

Интерфейс FastCGI — клиент-серверный протокол взаимодействия веб-сервера и приложения, дальнейшее развитие технологии CGI. По сравнению с CGI является более производительным и безопасным[1].

FastCGI снимает множество ограничений CGI-программ. Недостаток CGI-программ в том, что они должны быть перезапущены веб-сервером при каждом запросе, что приводит к понижению производительности. FastCGI, вместо того чтобы создавать новые процессы для каждого нового запроса, использует постоянно запущенные процессы для обработки множества запросов. Это позволяет экономить время.

Flow fastcgi.png

В то время как CGI-программы взаимодействуют с сервером через STDIN и STDOUT запущенного CGI-процесса, FastCGI-процессы используют Unix Domain Sockets или TCP/IP для связи с сервером. Это даёт следующее преимущество над обычными CGI-программами: FastCGI-программы могут быть запущены не только на этом же сервере, но и где угодно в сети. Также возможна обработка запросов несколькими FastCGI-процессами, работающими параллельно[2].

lighttpd включает в себя внутренний распределитель нагрузки FastCGI, который может использоваться для распределения сразу на несколько FastCGI-серверов. В отличие от иных решений, в кластере должен находиться только FastCGI-процесс, а не целый веб-сервер. Это позволяет использовать FastCGI-процессу больше ресурсов, по сравнению, например, с load-balancer+apache+mod_php.

При сравнении php-FastCGI с apache+mod_php необходимо обращать внимание на то, что FastCGI обеспечивает дополнительную безопасность, такую как, например, запуск FastCGI-процесса под учётной записью пользователя, отличного от пользователя веб-сервера, а также может находиться в chroot'е, отличном от chroot'а веб-сервера.

При сравнении perl-FastCGI с apache+mod_perl(1,2), кроме вышеуказанного, заметно, что для разделяемого использования памяти между процессами, реализуемого в mod_perl через startup.pl, необходим FastCGI-менеджер процессов, реализованный на Perl. Это реализуется модулем FCGI::ProcManager и его надстройкой FCGI::Spawn.

Принцип работы FastCGi

FastCGI программа работает следующим образом: скрипт единожды загружается в память в качестве демона (независимо от HTTP-сервера), а затем входит в цикл обработки запросов от HTTP-сервера. Один и тот же процесс-скрипт обрабатывает несколько различных запросов один за другим, что отличается от работы в CGI-режиме, когда на каждый запрос создается отдельный процесс, "умирающий" после окончания обработки.

Опции

Поддержка FastCGI в lighttod предоставляется через модуль fastcgi (mod_fastcgi) который имеет 2 опции в конфигурационном файле: fastcgi.debug Значение от 0 до 65535 для выставления уровня отладки в FastCGI модуле. На данный момент используются только 0 или 1. Выставите 1 чтобы включить отладку, и 0 чтобы выключить. fastcgi.server сообщает модулю куда надо отправлять FastCGI вызовы. каждое расширение файла может отправлять своему собственному FastCGI серверу. Балансировка нагрузки реализуется указанием нескольких FastCGI сервером для одного расширения.

структура fastcgi.server секции:

 ( <extension> => 
  ( <handle> => 
    ( "host" => <string> ,
      "port" => <integer> ,
      "socket" => <string>,       # socket
                                  # или пара host+port
      "bin-path" => <string>,     # ОПЦИОНАЛЬНО 
      "bin-environment" => <array>, # ОПЦИОНАЛЬНО 
      "bin-copy-environment" => <array>, # ОПЦИОНАЛЬНО 
      "mode" => <string>,         # ОПЦИОНАЛЬНО
      "docroot" => <string> ,     # ОПЦИОНАЛЬНО если "mode" 
                                  # не "authorizer"
      "check-local" => <string>,  # ОПЦИОНАЛЬНО
      "min-procs" => <integer>,   # ОПЦИОНАЛЬНО
      "max-procs" => <integer>,   # ОПЦИОНАЛЬНО
      "max-load-per-proc" => <integer>, # ОПЦИОНАЛЬНО
      "idle-timeout" => <integer> # ОПЦИОНАЛЬНО
    )
  ), 
  ( <handle> => ... 
  )
 )

<extension>: расширение файла или префикс (если начинается с "/")
<handle>: уникальное имя для этого handle
"host" : имя хоста/ip данного FastCGI процесса
"port" : tcp-порт на "host" используемый FastCGI процессом
"bin-path" : путь к локальному исполняемому файлу FastCGI который должен быть запущен если не используется отдельный FastCGI процесс
"socket" : путь к unix-domain socket
"mode" : режим FastCGI протокола. По умолчанию это "responder", также есть режим "authorizer" .
"docroot" : это опционально, и это docroot (корневая директория для документов) на удалённом хосте для режима "responder" mode. Для режима "authorizer" это ОБЯЗАТЕЛЬНО и указывает на docroot для авторизованных запросов. По причинам безопастности рекомендуется держать этот docroot вне дерева каталога server.document-root.
"check-local" : опционально и может быть включено "enable" (по умолчанию) или "disable". Если включено то сервер сначала проверяет файл в локальном server.document-root каталоге и возвращает 404 (Not Found) если такого файла нет. Если выключено, то сервер перенаправляет запрос к FastCGI интерфейсу без этой проверки.
Если указана bin-path:

"min-procs" : выставляет минимальное количество процессов стартующих при запуске
"max-procs" : верхний лимит запущенных процессов
"max-load-per-proc" : максимальное количество ожидающих процессов до того как запуститься новый процесс
"idle-timeout" : количество секунд после прошествия которых неиспользуемый процесс будет уничтожен
"bin-environment" : помещает переменную окружения для запускаемого процесса
"bin-copy-environement" : очищает переменные окружения и копирует только указанные переменные в новое окружение создаваемого процесса

Распределение нагрузки

FastCGI plugin предоставляет автоматическое распределение нагрузки между несколькими FastCGI серверами.

  fastcgi.server = ( ".php" => 
                   ( "server1" => 
                     ( "host" => "10.0.0.3",
                       "port" => 1030 ),
                     "server2" =>
                     ( "host" => "10.0.0.3",
                       "port" => 1030 )
                   )
                 )

Чтобы понять как работает распределение нагрузки вы можете включить опцию fastcgi.debug и получить вывод подобный этому:

  proc: 127.0.0.1 1031  1 1 1 31454
  proc: 127.0.0.1 1028  1 1 1 31442
  proc: 127.0.0.1 1030  1 1 1 31449
  proc: 127.0.0.1 1029  1 1 2 31447
  proc: 127.0.0.1 1026  1 1 2 31438
  got proc: 34 31454
  release proc: 40 31438
  proc: 127.0.0.1 1026  1 1 1 31438
  proc: 127.0.0.1 1028  1 1 1 31442
  proc: 127.0.0.1 1030  1 1 1 31449
  proc: 127.0.0.1 1031  1 1 2 31454
  proc: 127.0.0.1 1029  1 1 2 31447

Данный вывод показывает множество порождений FastCGI на локальной машине. Следующее объяснение верно также и для удалённых соединений.

Вывод показывает:

IP, порт, unix-socket (в данном случае пусто) is-local, показатель (0 - не выставлено, 1 - запущено, ... ) активные соединения (загрузка) PID Как вы можете видеть список всё время упорядочен по полю загрузки

При запросе нового соединения, выбирается первый указатель на FastCGI процесс (один с наименьшей нагрузкой), значение загрузки увеличивается на 1 (got proc: ...) и список сортируется вновь.

Если FastCGI запрос заканчивается или соединение обрывается, загрузка FastCGI proc уменьшается на 1 и список опять сортируется (release proc: ...)

Такое поведение занимает мало кода, весьма эффективно, и позволяет использовать fastcgi-сервера равнозагруженно, даже если они имеют разные CPU[3].

Веб-серверы, поддерживающие FastCGI

  • Abyss Web Server
  • Apache HTTP-сервер (частично)
  • Используются сторонние модули mod_fastcgi или mod_fcgid
  • Мультиплексирование запросов через одно соединение невозможно в данной архитектуре веб-сервера Apache[1]
  • aXesW3
  • Cherokee HTTP Server
  • Hiawatha webserver
  • Поддержка изолированного FastCGI-сервера
  • Lighttpd
  • LiteSpeed Web Server
  • Microsoft IIS[2]
  • MyServer
  • nginx
  • Поддержка группы серверов
  • Open Market Web Server
  • Roxen webserver
  • Sun Java System Web Server (и предшественники)
  • WebSTAR
  • Yaws
  • Zeus
  • Kitura

Привязки FastCGI API в языках программирования

FastCGI может быть использован в любом языке, поддерживающем сокеты. Существующие API:

  • Borland Delphi/FreePascal
  • C / C++
  • Chicken Scheme
  • Common Lisp: CLISP and CMUCL
  • D (язык программирования)
  • Go
  • Erlang
  • Guile Scheme
  • Goanna Eiffel
  • Haskell
  • HP BASIC for OpenVMS
  • Java
  • Lua
  • Mono XSP
  • Ocaml
  • Perl
  • PHP
  • Python
  • Roadsend PHP
  • Ruby
  • SmallEiffel
  • Smalltalk: FasTalk и Dolphin Smalltalk
  • Tcl

Примечания

  1. FastCGI Specification [Электронный ресурс] : Материал из http://www.mit.edu: — Режим доступа: http://www.mit.edu/~yandros/doc/specs/fcgi-spec.html
  2. Коротко о CGI, FastCGI, PHP-FPM и mod_php [Электронный ресурс] : Материал из http://xandeadx.ru/: — Режим доступа: http://xandeadx.ru/blog/php/866
  3. FastCGI [Электронный ресурс] : Материал из Википедии — свободной энциклопедии: — Режим доступа: https://ru.wikipedia.org/wiki/FastCGI