Nginx.pm
 use nginx or die;



                     Андрей Гейн, УрФУ
…
                    /about
          /search
/images
…
                    /about
          /search
/images
Nginx
Nginx
• Высокая нагрузка
Nginx
• Высокая нагрузка
• Кроссплатформенность
Nginx
• Высокая нагрузка
• Кроссплатформенность
• Обратный прокси-сервер
Nginx
•   Высокая нагрузка
•   Кроссплатформенность
•   Обратный прокси-сервер
•   Балансировщик нагрузки
Nginx
•   Высокая нагрузка
•   Кроссплатформенность
•   Обратный прокси-сервер
•   Балансировщик нагрузки
•   Безопасность
Nginx
•   Высокая нагрузка
•   Кроссплатформенность
•   Обратный прокси-сервер
•   Балансировщик нагрузки
•   Безопасность
•   Модульность
Nginx
•   Высокая нагрузка
•   Кроссплатформенность
•   Обратный прокси-сервер
•   Балансировщик нагрузки
•   Безопасность
•   Модульность
•   Плюшки
Конфигурация
Конфигурация
server {
  listen         80;
  server_name    urfu.ru ustu.ru usu.ru;
  root           /data/www;
} location / {
     index       index.html index.pl
  }
Конфигурация
server {
  listen            80;
  server_name       urfu.ru ustu.ru usu.ru;
     perl_handler
  root               My::App::handler;
                    /data/www;
  location / {
     index          index.html index.pl
  }
}
Конфигурация
location / {
  index          index.html index.pl
  perl_handler   My::App::handler;
  perl_access    My::App::access_handler;
  perl_app       /path/to/app.pl;
}
Общие настройки
Общие настройки
perl_inc   /path/to/lib;
Общие настройки
perl_inc     /path/to/lib;
perl_require My/App.pm;
Общие настройки
perl_inc     /path/to/lib;
perl_require My/App.pm;
perl_eval    '$My::App::CONF{foo} = "bar"';
HTTP API
HTTP API
sub handler {
  my $r = shift;
  my $buf = "Hello world!n";




}
HTTP API
sub handler {
  my $r = shift;
  my $buf = "Hello world!n";

    $r->header_out('Content-Length', length($buf));
    $r->send_http_header('text/html; charset=UTF-8');



}
HTTP API
sub handler {
  my $r = shift;
  my $buf = "Hello world!n";

    $r->header_out('Content-Length', length($buf));
    $r->send_http_header('text/html; charset=UTF-8');

    $r->print($buf);
    return NGX_OK;
}
HTTP API
sub access_handler {
 my $r = shift;



    return NGX_OK;
}
HTTP API
sub access_handler {
  my $r = shift;
  if ($r->uri eq '/private') {
    return 403;
  }
  return NGX_OK;
}
Изнутри
Изнутри
$r->send_http_header($content_type)
Изнутри
$r->send_http_header($content_type)
$r->header_only
Изнутри
$r->send_http_header($content_type)
$r->header_only
$r->status($error_code);
Изнутри
$r->send_http_header($content_type)
$r->header_only
$r->status($error_code);
$r->header_in("User-Agent")
Изнутри
$r->send_http_header($content_type)
$r->header_only
$r->status($error_code);
$r->header_in("User-Agent")
$r->headers_in
     { content-type   => ['text/html'],
       content-length => [1234] }
Изнутри
$r->uri
$r->send_http_header($content_type)
$r->header_only
$r->status($error_code);
$r->header_in("User-Agent")
$r->headers_in
$r->header_out($name, $value)
Изнутри
$r->uri
$r->args
Изнутри
$r->uri
$r->args
$r->request_method
Изнутри
$r->uri
$r->args
$r->request_method
$r->remote_addr
Изнутри
$r->uri
$r->args
$r->request_method
$r->remote_addr
$r->location_name
Изнутри
$r->uri
$r->args
$r->request_method
$r->remote_addr
$r->location_name
$r->root
Изнутри
$r->print($data, ...)
$r->uri
$r->args
$r->request_method
$r->remote_addr
$r->location_name
$r->root
$r->request_body
Изнутри
$r->print($data, ...)
$r->unescape($data)
Изнутри
$r->print($data, ...)
$r->unescape($data)
$r->sendfile($filename, $offset, $length)
Асинхронно?
Асинхронно?
ngx_timer $after, $repeat, sub { }

     my $repeat = 5;
     ngx_timer $repeat, $repeat, sub {
        $repeat--;
     };
Асинхронно?
ngx_timer $after, $repeat, sub { }
ngx_resolver $name, $timeout, sub { }
Асинхронно?
ngx_timer $after, $repeat, sub { }
ngx_resolver $name, $timeout, sub { }
ngx_http "$ip:$port:key=value;key=value...",
                           $request, sub { }
Nginx::Test
Nginx::Test
$nginx = find_nginx_perl
Nginx::Test
$nginx = find_nginx_perl
$port = get_unused_port
Nginx::Test
$nginx = find_nginx_perl
$port = get_unused_port
$text = cat_nginx_logs $dir
Nginx::Test
$nginx = find_nginx_perl
$port = get_unused_port
$text = cat_nginx_logs $dir
prepare_nginx_dir_die $dir, $conf, $package1,
                            $package2, ...
Nginx::Test
$nginx = find_nginx_perl
$port = get_unused_port
$text = cat_nginx_logs $dir
prepare_nginx_dir_die $dir, $conf, $package1,
                            $package2, ...
$child = fork_nginx_die $nginx, $dir
Nginx::Redis
Nginx::Redis
ngx_redis "$ip:$port:$auth:$timeout",
          ['GET', 'mykey'], sub { };
Тесты
Тесты
nginx-perl
Node.js
Тесты
                /        /single     /multi
nginx-perl
Node.js

10 потоков, 10 000 запросов, 3 запуска
Тесты
               /      /single   /multi
nginx-perl   3 (22)   5 (27)    7 (31)
Node.js      5 (40)   6 (30)    14 (45)
Nginx::Questions

Nginx.pm