«Лаппландцы» и HTTP

в 5:52, , рубрики: c++, LAppS, Lua, open source, reactive programming, web-разработка, Разработка под Linux

«Лаппландцы» и HTTP - 1

Это не про настоящих лапландцев (с одной 'п'). Это про сервер приложений для микросервисов LAppS.

Если интересно то прошу под кат.

С момента моей первой публикации на тему LAppS прошло всего 6 дней. За эти 6 дней LAppS обновился до версии 0.6.2 и обзавёлся несколькими полезными функциями.

Основное изменение

Появилась возможность исполнения сервисов независящих от очереди поступающих сообщений WebSockets. Я пока не совсем уверен как эти сервисы называть:
Standalone, Decoupled, Internal? Основной смысл этих сервисов в том, что они являются "ведущими", т.е. они определяют flow приложения. Они самостоятельно устанавливают правила взаимодействия с внешним миром. Сервисы в LAppS и раньше не блокировали ввод-вывод IOWorker-ов, но существовал только один род сервисов, — подчинённых очереди сообщений WebSockets.

Как пример, хочу предложить выполнение кода HTTP сервера под управлением LAppS в подобном сервисе. Для этого будет использован HTTP сервер Xavante проекта Kepler (см. ниже).

Ещё фичи

  • Для конфигурации IOWorker-ов доступны две новые опции

    • max_connections — лимит количества соединений с одним IOWorker-ом. Раньше данная опция была отключена.
    • auto_fragment — автофрагментация исходящих сообщений (сообщения фрагментируются по размеру Upper-Layer-Protocol Payload Ethernet фрейма ~1500 байт включая размер конвертов всего стека протоколов).

  • Для приложений (сервисов) доступна опция ограничения максимальной длинны входящего сообщения (по умолчанию 2^64 или лимит доступной памяти).

  • Добавлен модуль nap для decoupled сервисов. Интерфейс:
    • nap:new() — возвращает userdata объект типа nap
    • nap:usleep(msecs) — метод микросекундного сна. msecs — положительное целое.
    • nap:nsleep(nsecs) — метод наносекундного сна (+-10ns на моей машине). nsecs — положительное целое.
    • nap:sleep(sec) — метод секундного сна. sec — положительное целое.

Запуск Xavante под "лаппландцами"

Предупреждение: сервер xavante это HTTP 1.1 сервер без поддержки SSL (т.е. требует SSL фронтенда в виде nginx или H2O, для балансировки и шифрования трафика). Здесь настройка фронтендов не рассматривается.

Что для этого нужно

  • Установленный из дистрибутивов ОС luarocks.
  • Установленный LAppS-0.6.2. (Варианты установки можно посмотреть на wiki проекта, Например воспользоваться подготовленным deb пакетом или установить с помощью файла Docker )
  • Установленный в соответствии с инструкцией на сайте проекта xavante (2 шага Карл!)

Код сервиса http.lua

Код скопирован из руководства xavante, и вставлен в код сервиса LAppS

local xavante = require "xavante"
local hfile = require "xavante.filehandler"
local hredir = require "xavante.redirecthandler"

http = {}
http.__index = http

http["init"]=function()
  webDir = "/tmp/test/";
end

http["mustStop"]=function()
  return must_stop()
end

http["run"]=function()
  local simplerules = {
    { -- URI remapping example
      match = "^[^%./]*/$",
      with = hredir,
      params = {"index.html"}
    },
    {
      match = ".",
      with = hfile,
      params = {baseDir = webDir}
    }
  }

  xavante.HTTP{
    server = {host = "*", port = 80},

    defaultHost = {
      rules = simplerules
    }
  }

  xavante.start(http.mustStop,1);
end

return http

Перед запуском LAppS

Т.к. мы указали для xavante корень файловой системы для html файлов lua webDir = "/tmp/test/";, то в эту директорию нужно поместить index.html

Давайте совместим полезное с приятным, и поместим туда (переименовав) client.html из примеров вместе с библиотекой cbor.js.

Данный клиент пользуется 3-мя сервисами:

  • echo_lapps — эхо-сервер работающий в соответствии со спецификацией LAppS-протокола.
  • time_broadcast — Односекундный пульс времени
  • broadcast_blob — Броадкаст блоба ~4к размером, для теста авто-фрагментации отправляемых сообщений (с пульсом 5с).

Поэтому создадим файл конфигурации для этих 4-х сервисов (включая xavante):

{
  "directories": {
    "applications": "apps",
    "app_conf_dir": "etc",
    "tmp": "tmp",
    "workdir": "workdir"
  },
  "services": {
    "echo_lapps" : {
       "internal" : false,
       "request_target" : "/echo_lapps",
       "protocol" : "LAppS",
       "instances" : 3,
       "max_inbound_message_size" : 1024
     },
    "http": {
      "internal": true,
      "instances": 1
    },
    "time_broadcast": {
      "internal": true,
      "instances": 1
    },
    "broadcast_blob": {
      "internal": true,
      "instances": 1
    }
  }
}

Конфигурацию (lapps.json) необходимо поместить в /opt/lapps/etc/conf/.

Сами демо приложения, должны быть установлены если Вы ставили LAppS из deb пакета. Если устанавливали из исходников, то просто введите команду маке install-examples.

После этого запускаем "лапландцев": /opt/lapps/bin/lapps

Для запуска в режиме демона можно добавить опцию -d.

Теперь если в браузере запустить http://localhost (если установка шла на localhost) то можно увидеть работу приложения (как на КПДВ): скользящий bar-график echo-rps, нотификация времени, и если открыть инспектор, — то выведенный в консоль блоб.

Интересные (или нет) детали

В коде сервиса http.lua, можно заметить обращение к глобальной функции must_stop(). Эта функция возвращает true, если LAppS желает остановить приложение. Данная функция инжектится во все decoupled-сервисы перед их инициализацией.

Decoupled-сервисы имеют упрощённый интерфейс. Это всё теже модули Lua, однако в них должно быть декларировано всего два метода: init() и run(). Как очевидно из их названий, — первый из них служит для кода инициализации, второй для выполнения сервиса.

У меня в планах:

  • "Прожорливые "лаппландцы"" — исследование потребления памяти и cpu с помощью valgrind и gperftools;
  • "Железнодорожник" — о том почему в LAppS не используются std::thread из STL, но используются std::mutex и std::atomic. Ниже опрос. Нужны-ли на хабре публикации про LAppS.

Также мне нужна помощь в развитии LAppS. Самая простая. Нужны те кто заинтересован в его тестировании, и нужны запросы на функционал.

Планов в принципе много, но возможно кому-то будет полезно что-то ещё, чего я просто не вижу.

Автор: Pavel Kraynyukhov

Источник

* - обязательные к заполнению поля