$30 off During Our Annual Pro Sale. View Details »

Izhevsk PHP Meetup #1. Nginx + Lua vs. Nginx + PHP

Izhevsk PHP Meetup #1. Nginx + Lua vs. Nginx + PHP

Евгений Глазырин, PHP-разработчик, Центр Высоких Технологий
Сравнение решений на основе Lua и PHP в роли API Gateway.

Izhevsk PHP Meetup

December 08, 2016
Tweet

More Decks by Izhevsk PHP Meetup

Other Decks in Technology

Transcript

  1. View Slide

  2. Глазырин Евгений
    Веб-разработчик
    “Центр Высоких Технологий”
    [email protected]
    https://github.com/genhoi

    View Slide

  3. Приложение состоит из
    нескольких сервисов
    У приложения есть API

    View Slide

  4. View Slide

  5. ● 4 запроса для агрегации
    ● Клиентский код сложнее
    ● Как осуществлять контроль доступа?
    ● Как быть с протоколами AMPQ, binary RPC?

    View Slide

  6. View Slide

  7. API Gateway - точка входа в систему
    - Похож на паттерн Фасад в ООП
    - Инкапсулирует внутреннюю
    архитектуру системы
    - Разные обязанности (контроль
    доступа, кэширование,
    балансировка и т.д.)

    View Slide

  8. Варианты реализации
    ● Готовые решения
    ○ Kong (https://getkong.org) написан на Lua
    ○ API Umbrella (https://apiumbrella.io) написан на Lua
    ○ Tyk (https://tyk.io) написан на Go
    ● Своя реализация
    ○ Openresty (nginx + Lua)
    ○ PHP7 (nginx + php-fpm)
    ○ PHP7 (reactphp, kraken-php, Workerman)
    ○ NET Core
    ○ Go
    ○ и т.д.

    View Slide

  9. View Slide

  10. Почему Nginx + Lua?
    Много хороших отзывов о связке Nginx + Lua (2ГИС, Parallels)
    https://github.com/mindreframer/nginx-lua-stuff
    http://techno.2gis.ru/lectures/8
    http://www.slideshare.net/profyclub_ru/openresty-nginx-parallels
    Высокая скорость работы
    Уже давно все используют :)

    View Slide

  11. OpenResty
    Веб платформа интегрирующая Nginx, LuaJIT и различные
    библиотеки на Lua.
    Создан, чтобы помочь в разработке веб-сервисов и динамических
    шлюзов

    View Slide

  12. View Slide

  13. lua-nginx-module
    Встраивает Lua в Nginx
    Event loop у nginx используется для всех асинхронных
    действий, включая HTTP запросы и запросы к БД.

    View Slide

  14. server {
    listen 80;
    lua_code_cache on;
    location / {
    content_by_lua_block {

    ngx.say("hello, world")

    };
    }
    }

    View Slide

  15. View Slide

  16. Lapis http://leafo.net/lapis
    Веб фреймворк, основанный на Openresty.
    local lapis = require "lapis"

    local app = lapis.Application()


    app:match("/", function(self)

    return "Hello world!"

    end)


    return app

    View Slide

  17. View Slide


  18. http {
    include mime.types;
    server {
    listen ${{PORT}};
    lua_code_cache ${{CODE_CACHE}};
    location / {
    resolver ${{DNS_SERVER}};
    content_by_lua_block {
    require("lapis").serve("app")
    }
    }
    }
    nginx.conf

    View Slide

  19. local config = require("lapis.config")
    config({"development", "production"}, {
    port = "80",
    dns_server = "127.0.0.11",
    num_workers = "1",
    email_enabled = false,
    code_cache = "off",
    })
    config("production", {
    email_enabled = true,
    code_cache = "on"
    })
    config.lua

    View Slide

  20. local lapis = require("lapis")
    local http = require("lapis.nginx.http")
    local app = lapis.Application()
    app:match("/", function(self)
    local buf = {};
    buf[1] = http.simple("http://openresty_hello");
    buf[2] = ", ";
    buf[3] = http.simple("http://openresty_world");
    return {
    table.concat(buf), status = 200, headers = {},
    render = false, layout = false
    }
    end)
    return app
    app.lua

    View Slide

  21. $ lapis server

    View Slide

  22. PHP
    Простой API gateway на базе PHP и Lumen
    Ваша реализация :)

    View Slide

  23. require __DIR__ . '/vendor/autoload.php';
    $client = new GuzzleHttp\Client();
    $promises = [
    $client->getAsync('http://openresty_hello'),
    $client->getAsync('http://openresty_world'),
    ];
    /** @var \GuzzleHttp\Psr7\Response[] $results */
    $results = GuzzleHttp\Promise\unwrap($promises);
    $responseContent = $results[0]->getBody() . ', ' . $results[1]->getBody();
    Guzzle 6

    View Slide

  24. Инструменты тестирования
    docker
    Yandex Tank

    View Slide

  25. В течении 5 минут
    нагрузка повышалась
    линейно от 1000 RPS
    до 3000 RPS
    Приложение выводит
    строку “Hello, World” в
    теле ответа
    Test #1

    View Slide

  26. Test #2
    Test #3

    View Slide

  27. Нагрузка
    5 минут - 500 RPS
    Test #2
    Среднее время ответа в мс.

    View Slide

  28. Где NET Core?

    View Slide

  29. Test #3
    Нагрузка
    5 минут - 1000 RPS
    Среднее время ответа в мс.

    View Slide

  30. Исходники сервисов
    https://github.com/genhoi/api-gateway

    View Slide

  31. Вопросы?

    View Slide