Ответ 1
nginx использует основанную на событиях архитектуру, а это означает, что он использует один поток 1 с циклом события, который обрабатывает сокеты, когда они становятся готовыми для чтения или записи. Это означает, что запросы не обрабатываются одновременно, но несколько запросов могут быть быстро обработаны один за другим, хотя могут возникнуть задержки в обработке отдельных запросов, если есть задержки сокета/ввода-вывода.
Если я делаю 10 одновременных вызовов в /incr, а позже я вызываю/подсчитываю, могу ли я быть уверен, что результат будет 10 (я предполагаю, что нет, но почему)?
Да. Пока /count
вызывается после завершения всех запросов /incr
, результат будет равен 10. Представьте, что 9 запросов были завершены, но 10-й запрос был по какой-то причине задержан отправителем, а если /count
был обработанный до того, как 10-й запрос был обработан nginx, в результате вы должны получить 9.
Если я делаю 10 одновременных вызовов в /incr, и в то же время я делаю еще 10 до /decr, могу ли я быть уверен, что /count вернет 0?
Да, но порядок, в котором эти запросы будут обрабатываться, не гарантируется. Обратите внимание: в этом случае вам не нужно блокировать свое состояние или использовать глобальные семафоры или что-то в этом роде. Вы можете столкнуться с проблемами, если у вас есть некоторые вызовы ввода/вывода между состоянием чтения и записью его (поскольку в то же время можно обрабатывать другой запрос), но это не то, что делает ваш пример.
Как влияет количество рабочих на результаты?
Экземпляры Lua разделяются между запросами, обрабатываемыми одним и тем же рабочим процессом, поэтому несколько сотрудников не собираются давать вам тот же результат. Все ваши запросы /incr
могут обращаться к одному рабочему, но ваш запрос /count
может обратиться к другому сотруднику с другим экземпляром Lua, который (все еще) имеет count
, установленный в 0. Если вам нужно обмениваться данными между экземплярами, вам, вероятно, нужно использовать что-то вроде lua_shared_dict. См. Также раздел обмена данными для других параметров.
Как влияет на результат фазу, в которой происходит код (т.е. init_by_lua вместо content_by_lua)?
init_by_lua
выполняется только тогда, когда главный процесс загружает файл конфигурации.
1 Я упрощаю, так как он может вызывать несколько экземпляров для обработки многоядерных систем и некоторых других случаев, насколько я помню.