Консультация № 178622
25.05.2010, 00:35
45.00 руб.
0 15 1
Уважемые эксперты!
Есть довольно интересный вопрос.

Есть скрипт: http://moshoster.net/test.txt
Он просто получает текущую дату.

А вот результат его работы:
http://moshoster.net/test.cgi
Вроде всё верно. Но попробуйте обновить страницу раз 5-10, увидите, что происходит.

Сталкивался ли кто-нибудь из вас с такой интересной вещью?

Обсуждение

давно
Академик
20764
1861
25.05.2010, 08:13
общий
Там и с одного раза получается, что сервер находится где-то в Америке :-)
А теперь - в Москве.
Неизвестный
25.05.2010, 11:27
общий
Как и ожидалось, на локальном компе никаких сбоев не происходит, т.е. проблема именно серверная.
Может вместо localtime использовать gmtime и самому приводить время к Москве? Или нужно именно локальное время пользователя?
давно
Академик
20764
1861
25.05.2010, 11:40
общий
Выведете $ENV{'TZ'} и что-нибудь про /etc/localtime (длина, mtime,..)
давно
Руководитель
2
547
25.05.2010, 11:59
общий
Хватов Сергей:
Вывод $ENV{'TZ'} организовал: http://moshoster.net/test.cgi
По поводу /etc/localtime. Этот файл является ссылкой на /usr/share/zoneinfo/Europe/Moscow
Если нужно что-то ещё - выложу.
давно
Руководитель
2
547
25.05.2010, 12:01
общий
_Ayl_:
Да, проблема серверная. Скорее даже ОС. Т.к. точно на такой же версии Перл под Windows подобной проблемы нет.
gmtime можно использовать, но вот заменять все вызовы localtime на gmtime на большом кол-ве сайтов вряд ли получится. Плюс ко всему, что интересно, подобная проблема со временем наблюдается и на PHP при вызове подобных localtime функций.
давно
Академик
20764
1861
25.05.2010, 12:17
общий
TZ=America/Chicago иногда. Уж не знаю, кто и когда его поставил, но кто-то браузере помнит "вчерашний день". Попробуйте удалить эту переменную из среды в начале скрипта. Или записать туда путь к файлу описания зоны /etc/localtime' Правда возможно, что после этого надо явно вызывать tzset(), только его в perl по-моему нет.
давно
Руководитель
2
547
25.05.2010, 12:20
общий
Хватов Сергей:
Сергей, так это похоже всё-таки на глюк ядра системы или Перла?
давно
Академик
20764
1861
25.05.2010, 12:22
общий
Посмотрел в Интернете. Проблема известная, tzset вызывать надо и он есть в модуле POSIX
давно
Академик
20764
1861
25.05.2010, 12:29
общий
Цитата: Алексей Гладенюк
это похоже всё-таки на глюк ядра системы или Перла

Это точно не глюк ядра - ядро с временными зонами не работает Это особенность localtime() из libc. Но если для libc сюрпризы этой функции внятно описаны (а стало быть они уже не ошибки, а особенности), то в perl это всё скрыто.
Откуда в apache берётся "чужое" окружение не знаю, но в его архитектуре, где один подпроцесс может обслуживать несколько различных запросов, это в принципе возможно.
давно
Руководитель
2
547
25.05.2010, 12:57
общий
Хватов Сергей:
В принципе, вызывать эту функцию не проблема, если на сервере один-два сайта.
В данном случае - сайтов более 100, причём их кол-во постоянно пополняется. Получается, что нужно будет в каждый сайт (если в его коде есть вызов localtime) прописывать вывод этой функции.
В Преле - это полбеды. Проблема в том, что и в PHP время также прыгает.
Насколько я понимаю, это, скорее всего, реальный глюк, обойти который можно только обновлением системы...
давно
Академик
20764
1861
25.05.2010, 13:44
общий
Калашников О.А.:
Цитата: Алексей Гладенюк
реальный глюк, обойти который можно только обновлением системы...

Это - ОПИСАННОЕ и исторически сложившееся поведение функции из libc, и его никто не изменит.
Глюк здесь только в том, что при исполнении запроса то ли содержимое TZ в environment неопределеное, то ли остаётся сынициализированный tzdata с предыдущих запросов. Это вероятно проблемы apache Или встроенных в него интерпретаторов: mod_perl и mod_php (наверное и mod_python тоже), да и то сомнительные: никто не гарантировал чего-либо в environment помимо того, что предусмотрено реализацией cgi. Скорее - нестыковка.
P.S. Хорошо бы найти того, кто заполняет TZ. Очень вероятно, что это один из скриптов.
P.P.S. Вопрос - зачем клиенту знать локальное время сервера - тоже интересный.
давно
Академик
20764
1861
25.05.2010, 16:11
общий
Калашников О.А.:
Провёл эксперименты (правда, на python) с установкой TZ и повторил у себя эту ошибку. Apache при этом ещё и неверную дату в log пишет. Так что это - его бага. Можете писать bug report.
Кстати, про даты в логах apache кто-то уже спрашивал, только не помню где.
давно
Руководитель
2
547
25.05.2010, 20:21
общий
Хватов Сергей:
Сергей, благодарю за расширенный ответ!
Я тут сделал простую вещь: http://moshoster.net/info.php
Как оказалось часть переменных из раздела "Environment" иногда неопределены (если пару раз обновить эту страницу, то это будет видно). Очень похоже на то, что действительно глюк Апача.
Попробую его обновить.
Перевёл 100 руб. за помощь в решении проблемы. Успехов!
давно
Руководитель
2
547
25.05.2010, 20:25
общий
Хватов Сергей:
Можете сформировать ответ из Ваших последних двух сообщений в мини-форуме, чтобы вопрос и ответ ушли в рассылку. Возможно, кому-то это тоже поможет.
давно
Академик
20764
1861
25.05.2010, 21:34
общий
это ответ
Здравствуйте, Калашников О.А..
Формулирую ответ по результатам совместных экспериментов.

Это прежде всего ошибка в сервере Apache, связанная с особенностями его архитектуры: при его работе запускаются несколько подпроцессов, каждый из которых обслуживает по несколько разных запросов. Кроме того, интерпретаторы perl, php и python в нём встроенные. В результате если какой-то из скриптов сделает изменения в environment, эти изменения попадут и в некоторые другие запросы. В этом бы не было особой ошибки, если бы environment неявно не использовалась в ряде библиотечных функций. localtime() использует TZ, и изменение каким-то скриптом TZ и вызвало тот эффект, который вы наблюдали - неожиданное изменение временной зоны в скрипте. Дже в логи записывается дата с изменённой зоной.
В Интернете также упоминаются эффекты от изменения LANG и LC_*
Чтобы этого избежать, придётся перед использованием localtime() явно удалять $ENV{'TZ'}. Возможно, что также придётся для корректировки уже заполненных статических данных вызвать POSIX::tzset (мне в python не понадобилось)


Форма ответа