Хранение вложенных таблиц в разделяемой памяти nginx - PullRequest
1 голос
/ 08 июня 2019

Я работаю с open-resty и lua, чтобы создать сервер для перенаправления запросов.Перенаправления выполняются на основе некоторых данных из структуры дерева данных lua (вложенные таблицы)

Я ищу способ заполнить эти данные один раз при запуске и после этого делиться данными между работниками.

ngx.ctx может сохранять произвольные данные, но работает только во время запроса.Общий dict длится до конца, но может сохранить только список примитивов.

Я читал, что есть возможность обмениваться данными между модулями lua.Потому что модули запускаются только один раз при запуске.Код выглядит примерно так:

local _M = {}

local data = {
    dog = {"value1", "value4"},
    cat = {"value2", "value5"},
    pig = {"value3", "value6"}
}


function _M.get_age(name)
    return data[name]
end

return _M

, а затем в nginx.conf

location /lua {
    content_by_lua_block {
        local mydata = require "mydata"
        ngx.say(mydata.get_age("dog"))
    }
}

Является ли эта третья возможность безопасной для потока?Есть ли что-то еще, что может достичь этого?

Существует не так много документации по этому вопросу, поэтому разместил это здесь.Любая информация поможет, спасибо

1 Ответ

1 голос
/ 08 июня 2019

Вы можете заполнить свои данные в init_by_lua и получить к ним доступ позже. В вашем случае инициализация модуля mydata может быть достигнута:

init_by_lua_block {
     require "mydata"
}

init_by_lua запускается один раз при запуске nginx, а затем процесс, который он запускает, разветвляется на рабочих, поэтому каждый из них содержит независимую копию этих данных.

Рабочие являются однопоточными, поэтому вы можете безопасно получить доступ к вашим данным.


Теперь, если вы хотите изменить свою конфигурацию во время выполнения, не перезагружая nginx, тогда это немного усложняется. Каждый работник независим, но мы можем использовать ngx.shared.DICT для распространения изменений. В зависимости от ваших требований вы можете использовать два решения:

  1. После каждого изменения помещайте свою конфигурацию в общий словарь. Создайте таймер, который периодически перезагружает конфигурацию работника из этого общего кэша.
  2. После каждого изменения помещайте свою конфигурацию в общий словарь вместе с текущей меткой времени или номером версии. При каждом запросе работника проверяйте, совпадает ли эта временная метка / версия с той, которая кэшируется локально - если она затем десериализует эту конфигурацию и кэширует ее локально.

Если у вас есть API, который должен использоваться, вы можете использовать lua-resty-lock для создания критических секций между сотрудниками, которые синхронизируют изменения.

...