[C] Nginx - модули: можно или нет использовать потоки ?
Воспользуйся crontab для выполнения регулярных действий.
предполагаю, что там есть какие-то данные, отдающиеся модулем нгинкса, и эти данные он хочет периодически обновлять
Ну, и аналогичную задачу я именно так и решал: регулярно (crontab) отдельный скрипт парсил базу и клал данные в memcache, откуда уже забирал php-скрипт, запускаемый апачем.
У nginx есть собственные таймеры (см ngx_add_timer, ngx_del_timer чем они не устраивают?
У nginx есть собственные таймеры (см ngx_add_timer, ngx_del_timer чем они не устраивают?Спасибо. Изучу сегодня этот вопрос.
> Я решил добавить потоки.
> Но насколько это правильно?
Совсем неправильно. Nginx основан на event-loop, твое решение идет точно поперек его архитектуры. Используй его таймеры, как тебе сказали выше.
Ну, и аналогичную задачу я именно так и решал: регулярно (crontab) отдельный скрипт парсил базу и клал данные в memcache, откуда уже забирал php-скрипт, запускаемый апачем.@
Вот я, если честно, тоже к такой архитектуре пришёл.
@__
Если делать обновление через ngx_add_timer и ngx_del_timer, то поток по обработке запросов будет тормозить все то время, что обновляются данные.
Или я не прав?
Или ещё файл в память замапить не поможет?
Если делать обновление через ngx_add_timer и ngx_del_timer, то поток по обработке запросов будет тормозить все то время, что обновляются данные.Да, именно так.
[кэп]
Если файл большой, а вычислений мало - можно посмотреть в сторону aio. Если требуется много CPU time - то да, либо потоки, либо обработка сторонним процессом с последующей подгрузкой уже обработанных данных из него.
[/кэп]
А почему таймеры, а не inotify какое-нибудь?@
Архитектура nginx такова, что есть процесс master и процессы workers.
Вызов обновления внутри worker'a через таймеры или inotify будет тормозить поток worker'a.
Вместо обработки запросов он будет заниматься обновлением данных.
@__ и @
P.S. Я вот главного не пойму.
Добавить новый поток в worker - это плохо.
А схема crontab - memcached - util process - вроде как хорошо.
Вызов обновления внутри worker'a через таймеры или inotify будет тормозить поток worker'a.А если обновление длительное по времени, то зачем пытаться это дело вкорчевать в nginx? Не проще ли его бекэндом запустить тогда?
А если обновление длительное по времени, то зачем пытаться это дело вкорчевать в nginx? Не проще ли его бекэндом запустить тогда?@
Вместо одной сущности (модуля nginx я должен буду завести 3 сущности (модуль, утилиту и общее хранилище всё это синхронизовать, правильно сконфигурировать и так далее.
Спасибо.
Я вот так и не понял зачем тебе модуль?
Добавить новый поток в worker - это плохо.Потоки плохи тем, что
А схема crontab - memcached - util process - вроде как хорошо.
а) усложняется решение (блокировки, экспоненциальный рост состояний и т.п
б) если падает поток, падает весь процесс,
в) оскверняется event-loop nginx-а,
г) если воркеров у nginx несколько, то каждому воркеру придется перечитывать файл (немного некрасиво)
Если ты готов с этим жить, не вижу причин, почему бы не использовать потоки.
(была еще идея перечитывать файл мастер-процессом по reload-у, и релоадить nginx по обновлению файла, но раз в 30 секунд это делать не вариант)
Я вот так и не понял зачем тебе модуль?@
Это упрощенный прототип, на котором я тренируюсь.
на диске лежит файл data.json и я хочу раз в 30 секунд перечитывать его содержимое в память.Более крутой модуль мне нужен, чтобы работать с Cookies на nginx сервере.
При этом обработчик запросов будет отдавать клиенту данные из памяти.
Вся проблема в том, что информация, которая пишется в Cookies, обновляется каждые N секунд c диска / из БД.
Логика формирования Cookies не совсем простая. В двух словах не расскажешь.
Своего рода метрика посещения страниц сайта для рекомендательного сервиса и в БД лежит словарь.
Подробно @: в БД хранятся идентификаторы страниц сайта и идентификаторы мета-тегов для страницы сайта. Обновление этой БД довольно регулярное: раз в 2 минуты. В куку я пишу идентификаторы и мне требуется их список регулярно пополнять, читая из БД.
@__ Пункт г можно обойти организовав общий семафор.
Выполнять reload на высоконагруженных серверах раз в n секунд - это совсем плохо.
Ладно, пока буду думать в направлении предложенным товарищем ым.
Раз уж другого способа не предлагается.
Всем тогда спасибо.
в случае с мемкешом - чтение из него тоже надо будет либо встраивать в main-loop (что вряд ли просто либо читать синхронно - тогда точно так же worker может залипнуть
ЗЫ а кроме "надругания" над чистотой архитектуры нгинкса есть какие-нибудь причины не создавать тред?
Модуль мне нужен, чтобы работать с Cookies на nginx сервере.
Вся проблема в том, что информация, которая пишется в Cookies, обновляется каждые N секунд c диска / из БД.
может, ты более детально напишешь, чего хочешь достичь?
Я вот так и не понял зачем тебе модуль?+1
на мой взгляд аккуратно написанный тредик типа
sleep
load_data
swap_data
ничего не усложнит и ничего не сломает
блин, не делай так больше - не добавляй ответы на вопросы в ранее созданные посты@
Извини. Не буду так больше делать.
Я привел пример в первом сообщении треда и обозначил проблему.
А меня завалили вопросами "зачем тебе это?". Чтобы не отвечать каждому, я все объединил в один пост.
Примите, как дано, что мне это надо. И мне нужен nginx, потому что есть другая бизнес-логика на нем.
на мой взгляд аккуратно написанный тредик типа sleep load_data swap_data ничего не усложнит и ничего не сломаетЗдесь я согласен, но выше приведены аргументы, что
1) Мы должны будем организовать работу так, чтобы 10 worker'ов 10 раз не делали одну и ту же работу по обновлению данных в памяти (скорее всего через команду flock это можно обойти).
2) В nginx нет механизма работы с потоками. Их запретили в версии 0.7.4. И любая попытка это обойти - по сути хак.
Остается только один вариант. Делать отдельный процесс, вызов которого осуществлять по cron или через те же ngx_add_timer / ngx_del_timer.
А потом можно будет поиграться и переписать через потоки и посмотреть, как изменится производительность.
1) Мы должны будем организовать работу так, чтобы 10 worker'ов 10 раз не делали одну и ту же работу по обновлению данных в памяти (скорее всего через команду flock это можно обойти).1) не факт, что это нужно. Если там операция не супер ресурсоёмкая (именно ресурсо-, а не времени- то можно и 10 раз считать
2) В nginx нет механизма работы с потоками. Их запретили в версии 0.7.4. И любая попытка это обойти - по сути хак.
2) в нгинск нет мехнаизмов для работы много с чем - это не повод ограничивать себя. Потоки они "запретили" наверняка для того, чтобы 1) никто не пересекался с mainloop-ом; 2) никто не заблокировал основной поток исполнения непродуманным mutex-ом али еще чем;
P.S. Я вот главного не пойму.Ты не с той стороны на это смотришь.
Добавить новый поток в worker - это плохо.
А схема crontab - memcached - util process - вроде как хорошо.
Добавить новый поток для обработки асинхронных событий - это плохо, поскольку события обрабатываются в nginx через event-loop.
Вынести тяжеловестные и независимые от вебсервера вычисления в отдельный процесс - это хорошо, и вебсервер разгружается, и независимая сущность выделяется в отдельную компоненту.
1. Подготавливаешь бинарный файл с данными ровно в том виде, в котором будешь работать в nginx'е (boost/serialization или что-то подобное в помощь).
2. Далее читаешь файл в холостую один раз, чтобы он закэшировался в ОС
3. Посылаешь уведомление в nginx о том, что готова новая версия данных (сигнал?).
При получении уведомления в nginx'е:
1. mmap(PROT_READ, MAP_SHARED) + mlock на указанный файл. Так как файл уже закэшировался, то это быстро отработает даже для многогигового файла.
2. используешь полученный кусок памяти по назначению
Я планировал примерно то же самое через shared memory сделать.
Но за рекомендацию с файлами тоже большое спасибо.
2. Далее читаешь файл в холостую один раз, чтобы он закэшировался в ОС
1. mmap(PROT_READ, MAP_SHARED) + mlock на указанный файл. Так как файл уже закэшировался, то это быстро отработает даже для многогигового файла.1) полагаться на то, что файл закешируется - фэйл
2) любой вид лока на внешний ресурс - потенциальный блок основного воркера (тут как с ружьем на стене)
3) насколько я понял, предполагается держать лок все время обработки запроса, т.е., если запросов много, то лок держится почти всегда и тогда, когда придет время отдельной утилите писать в файл, она заберет лок и фэйл из пункта 2) точно случится
Я планировал примерно то же самое через shared memory сделать.
с шаредмемори те же проблемы с локами
+ шаред мемори легко еще может остаться жить и засирать оперативку, если процесс упадет не освободив ее (и тут вообще непонятно, кто должен ее освобождать)
1) полагаться на то, что файл закешируется - фэйлМне кажется, ты пишешь о каких-то совсем других локах.
2) любой вид лока на внешний ресурс - потенциальный блок основного воркера (тут как с ружьем на стене)
3) насколько я понял, предполагается держать лок все время обработки запроса, т.е., если запросов много, то лок держится почти всегда и тогда, когда придет время отдельной утилите писать в файл, она заберет лок и фэйл из пункта 2) точно случится
mlock(2) - Linux man page
+ шаред мемори легко еще может остаться жить и засирать оперативку, если процесс упадет не освободив ее (и тут вообще непонятно, кто должен ее освобождать)@
Ну а что тут можно предложить?
Да. Есть такая проблема. Память освободит и лок с флага снимет наша же утилита, запущенная через 30 секунд прямо при старте. (flock для подстраховки).
Фактически я хочу сделать 2 буфера в общей памяти. Один для чтения, один для записи.
И менять их местами после окончания обновления через какой-то общий флаг.
Вариант, который предложил , по моим прикидкам скушает столько же памяти, только внутри самого nginx.
Хотя он может и проще с точки зрения реализации.
я потому и написал "насколько я понял" ) - с ммапами я дела давно не имел. но все равно мне кажется, что основная проблема в том, что у тебя все закладывается на то, что файл попадет в дисковый кеш - я сомневаюсь (точнее, не знаю что это можно гарантировать. А если нельзя то чтение его сдиска опять таки заблокирует воркера
Хотя он может и проще с точки зрения реализации.ну, если тебе отдельный процесс и синхронизация его с воркером (сигналами или как-то еще) проще, чем отдельный тред - то, конечно, делай так
только имей еще в виду, что тебе придется заморочиться с сериализацией данных в "сырой" кусок памяти и с тем, чтобы ты одновременно не писал/читал один и тот же кусок - просто "указателем" на тот кусок, который сейчас "актуален" тут не отделаешься
отдельный процесс и синхронизация его с воркером (сигналами или как-то еще) проще, чем отдельный тред@
Вы на самом деле очень клевые советы даете. Я бы до них сам точно не догадался.
придется заморочиться с сериализацией данных в "сырой" кусок памяти и с тем, чтобы ты одновременно не писал/читал один и тот же кусокНу для этого в утилите можно предусмотреть какой-нибудь отладочный режим с сериализацией данных.
Понятно, что хорошо бы checksum проверять и прочие вкусности.
@ Спасибо, что предложил вполне работающее решение. Но мне пока мой вариант нравится больше.
Пишу утилиту с shared_memory, весь код собираю в библиотеку.
Конфигурацию всего этого хозяйства отдаю модулю nginx.
Никаких сигналов, только проверка лока на каком-то флаге внутри обработчика запросов.
Дальше уже можно полностью перенести всё внутрь nginx (тот же pthread поток создать).
И если тесты покажут, что производительность не упала, то в таком виде и оставить.
А если нет, так придется cron или ngx_add_timer использовать.
Мыши плакали, кололись, но продолжали кушать кактус.
я бы на твоем месте начал с реализации через поток (т.к. на мой взгляд она гораздо проще за счет простоты синхронизации потоков по сравнению с процессами) и сравнил ее производительность с производительностью просто nginx-а с константными данными (т.е. без перезагрузки данных)
Зы: скорее всего задачу решает вообще файловая система, а не нгинкс.
я сомневаюсь (точнее, не знаю что это можно гарантировать. А если нельзя то чтение его сдиска опять таки заблокирует воркератеоретически, в любой момент что угодно может заблокировать воркера (даже mlockall не панацея)
на практике, файл будет в кеше после первого прочтения, если памяти хватает
если рассуждать как ты, то даже index.html нельзя отдавать как есть - а вдруг воркер заблокируется при чтении файла, и пипец
А чо будет если указать нгинксу отдавать файл с диска, а файл поменять? Не решает ли он самостоятельно ту же задачу?Если менять именно тот же файл без локов, то все взорвется.
Зы: скорее всего задачу решает вообще файловая система, а не нгинкс.
Если делать в отдельном файле новую версию и потом атомарно его перемещать, то будет ок, но ТС же вроде нужна какая-то логика обработки файла, а не просто отдача.
а) усложняется решение (блокировки, экспоненциальный рост состояний и т.пС правильно расставленными мемори барьерами ничего этого не надо.
Проблема Я решил добавить потоки.Я сорсы nginx не щупал, но быстрое гугление --with-threads говорит, что это просто переключает внутреннюю имплементацию воркеров нгинкса на треды вместо процессов, что давно не поддерживается и не работает.
Выяснилось, что начиная с версии 0.7.4 опция --with-threads запрещена в конфигурации.
Использовать кроссплатформенные обертки для работы с потоками в nginx я не могу.
Конечно, я тут могу быть не прав, но мне кажется довольно странным, что отключение подобного флага мешает в своем модуле использовать свои треды для себя.
Впрочем, shm lock-free - вполне нормальное решение, которое имеет смысл даже если треды в нгинксе таки можно плодить.
если рассуждать как ты, то даже index.html нельзя отдавать как есть - а вдруг воркер заблокируется при чтении файла, и пипецНу да. А зачем еще придумали DMA, AIO и sendfile?
Впрочем, "на практике, файл будет в кеше после первого прочтения, если памяти хватает" - согласен. Но надо понимать, что читать из памяти процесса vs читать с диска надеясь на кеш - одно лишнее копирование памяти во втором случае. Что, впрочем, может быть пренебрежимо.
А зачем еще придумали DMA, AIO и sendfile?sendfile как раз и предназначен, чтоб отдать файл из кеша в сеть
а если файл нужно прочитать с диска, то sendfile диск крутиться быстрее не заставит
AIO в теории как раз ничего не гарантирует
ну подождал ты пока блоки подгрузятся с диска и что? думаешь с ними уже можно работать теперь не блокируясь? нифига, диспетчер памяти мог сбросить любые страницы процесса, пока он ждал
ещё есть tmpfs если не хочется трогать диск совсем
sendfile как раз и предназначен, чтоб отдать файл из кеша в сетьsendfile - это такой AIO + zero copy. Из кеша там или не из кеша - пофиг, в обоих случаях все плюсы aio и zero copy сохраняются.
а если файл нужно прочитать с диска, то sendfile диск крутиться быстрее не заставит
AIO в теории как раз ничего не гарантируетДа, AIO дает тебе только возможность, пока диск крутится, заниматься своими делами.
ну подождал ты пока блоки подгрузятся с диска и что? думаешь с ними уже можно работать теперь не блокируясь? нифига, диспетчер памяти мог сбросить любые страницы процесса, пока он ждал
От своппинга можно защититься очень просто - отключив его.
К сожалению, это не вся картина, и остается хотя бы куча всяких прерываний, которые тоже могут "заблокировать" твой воркер. К счастью, речи о втыкании ядерного реактора в USB у нас вроде не идет, на риалтаймовую отдачу index.html мы не претендуем, так что проблемы от этих эффектов порядка микросов я не вижу. Эффекты порядка миллисов должны быть устранимы.
ещё есть tmpfs если не хочется трогать диск совсемСогласен. Это + sendfile - довольно простой, быстрый и надежный вариант.
Да, AIO дает тебе только возможность, пока диск крутится, заниматься своими делами.на практике да, а в теории этого никто не гарантирует
От своппинга можно защититься очень просто - отключив его.просто страничка с кодом может быть сброшена например и ты получишь page fault как только решишь что-то сделать с прочитанными даннными
от этого можно защититься через mlockall, но гарантия не полная: как только захочется выделить память, могут заставить подождать, причём выделить память может захотеть сисколл, та же запись в сокет например
хотя да, я понял про что ты говоришь: в nginx лучше использовать асинхронное чтение (если оно доступно оттуда) или же tmpfs
Атомарно перемещать = копировать новый файл вместо старого, так? Т.е. ничонеделать особенного.
топикстартеру же не надо файл отдавать, а надо какие-то структурированные данные персчитывать откуда-то; вроде из базы вообще изначально - т.е. зачем тут файл вообще не очень понятно
я, боюсь, потерял нить вашего диалога и не понимаю, что и куда вы собираетесь посылать sendfile-омЕсли я правильно понял, то они развивают идею c файлами.
топикстартеру же не надо файл отдавать, а надо какие-то структурированные данные персчитывать откуда-то; вроде из базы вообще изначально - т.е. зачем тут файл вообще не очень понятно
Только файл теперь на tmpfs.
P.S. Я совершенно не против, потому что идею с shared_memory или на простых потоках уже обсудили.
Что взорвется и как?Если приводить аналогию из бд, у тебя случится read uncommitted.
Атомарно перемещать = копировать новый файл вместо старого, так?Атомарно перемещать = например, делать posix rename.
Нажимание f5 или f6 в твоем любимом файлменеджере - это не то.
Если я правильно понял, то они развивают идею c файлами.
да, только они обсуждают, как послать файл куда-то, что тебе, насколько я понимаю, не нужно (я так понял, что тебе нужно считать данные и использовать их для "внутренней кухни", а не посылать просто куски отттуда клиенту)
Атомарно перемещать = например, делать posix rename.
UPD почитал ман - удалять не надо )
я, наверное, опять повторюсь, но я не понимаю, зачем тут вообще промежуточный файл (данные же вроде из БД)? и решение с потоком прекрасно решит задачу и не наплодит ненужных сущностей. Единственное "но" - чье-то чувство прекрасного может пострадать по каким-то сугубо субъективным причинам
Зы read uncommited случается во всех файловых системах?
я, наверное, опять повторюсь, но я не понимаю, зачем тут вообще промежуточный файл (данные же вроде из БД)? и решение с потоком прекрасно решит задачу и не наплодит ненужных сущностей. Единственное "но" - чье-то чувство прекрасного может пострадать по каким-то сугубо субъективным причинамс файлом проще (так как библиотек полно, которые могут прочитать из файла любые структуры в одну строчку) - быстрее будет работающий прототип
однако в продакшене будет сложнее - отдельный демон (или задача крона это нужно отдельно мониторить, и сильнее зависимость от системных настроек (та же tmpfs)
Оптимальное по пефомансу решение задачи топикстартера, на мой взгляд, уже написано выше - shm\threads + memory barriers.
Пусть и корректный swap_data в общем случае нетривиален (но вполне выполним). Ибо перед тем, как делать load_data, надо убедиться, что все воркеры увидели предыдущий swap_data и не читают из места, куда собираемся load'ить.
Но при допущении, что релоадим редко, и за время между релоадами все воркеры успевают увидеть swap_data (что вполне разумно при фиксированном времени между релоадами порядка секунды) задача становится достаточно тривиальной.
с файлом проще (так как библиотек полно, которые могут прочитать из файла любые структуры в одну строчку) - быстрее будет работающий прототип
так в случае с потоком вообще серилиазовать не надо - у тебя все считывается из базы и сразу складывается в структурированную форму, а воркеру просто передается указатель на "корень"
Решение получается некроссплатформенным.
На чем все это писать? На C++/Boost? Заворачивать в библиотеку, обернув extern C, и отдавать обертку в nginx?
PS Нужны примеры реализаций хотя бы одного из подходов.
А их нет, что забавно. Открываем Америку все дружно.
ну у топикстартера же один воркер на один поток будет и данные в одном адресном пространстве (безо всяких там shared memory) - воркер может просто лочить мутекс на время работы с общим ресурсом, а отдельный поток брать тот же мутекс только для swap-а. и никакой магии с барьерами и т.п.
так в случае с потоком вообще серилиазовать не надо - у тебя все считывается из базы и сразу складывается в структурированную форму, а воркеру просто передается указатель на "корень"ну там пока ты разберёшься с таймерами и блокировками - можно 20 сериализаций зафигачить за это время
там в потоке ровно один sleep (ну да, время сна можно подгонять, чтобы интервалы были честнее, но это и в отдельном процессе так же будет?) и один mutex_lock на "быструю" операцию
Не обижайся, я же любя. Даже про "этих несведущих программистов на питоне" не стал ничего язвить
> Прям никак из командной строки posix rename не вызывается?
Не знаю.
Вероятно, "mv -f" в рамках одной фс в большинстве случаев делает то, что нужно. Но гарантий оно, судя по man'у, никаких не дает.
а там у воркеров общее адресное пространство с мастер-процессом?
а на практике есть проверенные способы
но если данных много и в каждом воркере их держать накладно - то да, придется извращаться )
Этот же вариант допиливается и до случая с shm - просто делается по мьютексу на каждый воркер. Мьютексы шарятся с релоадящим процессом, и при data_swap лочатся все по очереди.
Немножко хуже, но при ограниченном количестве воркеров все еще терпимо.
ненене, я предлагал в каждом воркере наспаунить по треду ) ( в предположении, что операция считывания данных - в данном случае из БД - не жрет проца - тогда не страшно, что одни и те же данные по несколько раз будут читаться)а, ну это ещё грубее, чем крон+файл
а эти процессы будут завершаться корректно? своих воркеров-то nginx прибьёт
rename старается: "If newpath already exists, it will be atomically replaced".
Да. Так как в фс в принципе нет понятия commit на этом уровне, то read uncommitted - единственный способ прочитать в файле то, что записали другие.
Я за то чтоб не программировать, если можно не программировать. А тут по-моему можно и все должно работать, городить велосипеды незачем.
Понял, спасибо.
Городить что-то придется в любом случае, ибо задача автора не просто сервить изредка обновляющийся файл, на что тебе уже указали.
Чем плохо зашиваться на неспецифицированные детали имплементации того же mv, я, думаю, объяснять не надо, хотя это уже больше 'у комментарий.
Чем плохо зашиваться на неспецифицированные детали имплементации того же mv, я, думаю, объяснять не надо, хотя это уже больше 'у комментарий.ну тогда на всяких питонах вообще нельзя писать
Решение получается некроссплатформенным.Оу. Ммм. Ну скопипасть к себе ту кроссплатформенную обертку, которая использовалась в самом нгинксе. Нгинкс же это как-то делал?
PS Нужны примеры реализаций хотя бы одного из подходов.Навскидку (сам не юзал, просто нагуглил): что-нить типа такого не пойдет? Написать на нем вообще всю твою логику и все?
А их нет, что забавно. Открываем Америку все дружно.
можно.
PS Спор ради спора. Я уже забыл, как это бывает. Всем хорошего дня!
Судя по всему, вот уже пару лет, как PS Спор ради спора. Я уже забыл, как это бывает. Всем хорошего дня!
Где?
"..., но ТС же вроде нужна какая-то логика обработки файла, а не просто отдача."
Написать на нем вообще всю твою логику и все?@
Спасибо. Но веб сервер OpenResty не подходит. Нужен nginx.
Выше я уже объяснял почему (куча бизнес-логики, которую переносить не хочется).
Чтобы отдавать файл статикой, ничего программировать не требуется. Nginx это сам умеет.
Мне надо загрузить файл для некоторых нестандартных действий (например, формирование куки на его основе).
PS. У меня уже мозг взрывается от разных предложений. А задачка-то вроде проще не придумаешь.
PS Нужны примеры реализаций хотя бы одного из подходов.
пример с отдельным тредом довольно простая штука и вряд ли кто-то снанет такое выкладывать (зачем?)
или ты хочешь, чтобы тебе тут кто-то написал код?)
PS Нужны примеры реализаций хотя бы одного из подходов.@
ты опять отредактировал пост
Нет. Просто все погрузились в спор и проигнорировали мое сообщение.
пример с отдельным тредом довольно простая штука и вряд ли кто-то снанет такое выкладывать (зачем?)Дело тут не в простоте. Код некроссплатформенный убог и никому не интересен.
или ты хочешь, чтобы тебе тут кто-то написал код?)Нет, зачем. Я, кстати, если реализацию через shared_memory допишу, обязательно куда-нибудь выложу.
PS. Беру таймаут на пару дней. С вами интересно, но надо работать.
Код некроссплатформенный убог и никому не интересен.
хз, мне вот виндакод, например, совсем неинтересен
ЗЫ хотя, если ты рассматриваешь возможность написания на С++, то в С++11 есть все необходимое, вроде бы
Нет, зачем. Я, кстати, если реализацию через shared_memory допишу, обязательно куда-нибудь выложу.Вот еще вдогонку: http://github.com/openresty/lua-resty-lock.
Но тут уже надо мерять, что лучше. Очень может быть, что обычный мьютекс - лучше.
А если нужен пример, как красиво рожать тред в нгинксе, то чем код самого нгинкса под with-threads не устроит, я так и не понял.
клац: "..., но ТС же вроде нужна какая-то логика обработки файла, а не просто отдача."Это примерно то же самое что ты сказал - вроде как ему что-то другое нужно, а где он это написал - хз.
В моем понимании это "что-то" можно записывать в файл, файл подменять. Что еще нужно ТС так ни разу и не ответил.
Нет, зачем. Я, кстати, если реализацию через shared_memory допишу, обязательно куда-нибудь выложу.Назови ее varnish, пожалуйста
Мне надо загрузить файл для некоторых нестандартных действий (например, формирование куки на его основе).
А если нужен пример, как красиво рожать тред в нгинксе, то чем код самого нгинкса под with-threads не устроит, я так и не понял.@
Расскажи, пожалуйста, как это сделать. --with-threads опция удалена.
Предлагаешь определять NGX_THREADS макрос прямо в коде?
P.S. Пропатчить nginx до OpenResty не предлагать.
@
Посмотри модуль GeoIP. Сможешь сделать, чтобы база обновлялась сама раз в сутки без перезапуска сервера?
PS Хорош троллить.
И я про то же.
все, что тебе нужно сделать - создать тред при инициализации (или кофигурации - не знаю, насколько они там разнесены) модуля и сделать join на созданный тред в shutdown-е модуля (это, возможно, необязательно - в крайнем случае главный процесс наверняка просто убьет воркера)
@Попробуй внятно объяснять чего делать хочешь, а то приходится телепатически догадываться что за проблемы.
Посмотри модуль GeoIP. Сможешь сделать, чтобы база обновлялась сама раз в сутки без перезапуска сервера?
PS Хорош троллить.
Файл что ли большой?
тебе почти наверняка не надо рожать тред "как в нгинксе", т.к. там наверняка куча всяких дополнительных действий, которые тебе совершенно не нужны.@
Согласен. Причем сам выше написал, что нашел в интернете, что код этот написан для старой архитектуры nginx.
Он может содержать ошибки, небезопасен. А кроме того, там нет нужных нам shm_lock и прочих вкусностей.
shm_lockа что ты тут подразумеваешь?
shm_lockЯ имел ввиду, что нет оберток функций mlock, semget и других вкусностей для работы с общей памятью.
Да и нафиг он вообще нужен, если есть boost и c++.
Оставить комментарий
Yulka-MOl
Всем привет.При написании модуля к веб-серверу nginx потребовалось создать фоновый поток для регулярного обновления данных.
Идея в общем такая.
Внутри функции модуля, которая парсит конфиг, создается поток. Раз в n секунд функция потока просыпается и обновляет данные с диска из базы.
Например, сейчас на диске лежит файл data.json и я хочу раз в 30 секунд перечитывать его содержимое в память.
При этом обработчик запросов будет отдавать клиенту данные из памяти.
Детали.
Я посмотрел небезызвестную статью Evan Miller'а про его модуль Circle GIF, рисующий GIF-изображение в виде круга в браузере.
Дополнительно посмотрел модуль GeoIP, использующий файл соответствий IP-адреса и геобазы.
Вроде бы получилось их скрестить. Потоки я не использовал. Файл читается один раз с диска.
Проблема Я решил добавить потоки.
Выяснилось, что начиная с версии 0.7.4 опция --with-threads запрещена в конфигурации.
Использовать кроссплатформенные обертки для работы с потоками в nginx я не могу.
PS Код будет исполняться на CentOS и я могу использовать pthreads библиотеку, заточенную под UNIX.
Но насколько это правильно? Делал ли кто-нибудь что-нибудь подобное?
Буду признателен любой помощи.