У меня есть сервер с некоторыми форумами на PHP (Ваниль 1.1.5a) на нем, и недавно я заметил, что сообщения на них выходят из строя. Некоторое копание показало, что Apache, похоже, меняет текущий часовой пояс с +0000 до -0500 по запросу без видимого шаблона, который можно увидеть в таких записях журнала:
38.104.58.202 - - [15/Jun/2009:22:40:05 +0000] "GET /extensions/MembersList/library/paginate.js HTTP/1.1" 200 22880 "http://mysite.com/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b99) Gecko/20090605 Firefox/3.5b99"
38.104.58.202 - - [15/Jun/2009:17:40:05 -0500] "GET /extensions/JQuery/jquery-1.2.6.min.js HTTP/1.1" 200 55804 "http://mysite.com/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b99) Gecko/20090605 Firefox/3.5b99"
Хотя время, скорректированное с учетом разницы часовых поясов, такое же, похоже, это заставляет функцию даты PHP возвращать локальное, нескорректированное время (с последующим хаосом искажения времени, происходящим в данных форума).
Я также запускаю приложение mod_python на основе Django на том же VirtualHost. Конфигурация выглядит так:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
<Directory "/usr/lib/cgi-bin">
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
</Directory>
ErrorLog /var/log/apache2/error.log
# Possible values include: debug, info, notice, warn, error, crit,
# alert, emerg.
LogLevel warn
CustomLog /var/log/apache2/access.log combined
Alias /doc/ "/usr/share/doc/"
<Directory "/usr/share/doc/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Deny from all
Allow from 127.0.0.0/255.0.0.0 ::1/128
</Directory>
Alias /media/ "/usr/share/python-support/python-django/django/contrib/admin/media/"
<Directory /usr/share/python-support/python-django/django/contrib/admin/media/>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
RedirectMatch ^/raid-scheduler$ "/raid-scheduler/"
<Location "/raid-scheduler/">
SetHandler python-program
PythonHandler django.core.handlers.modpython
SetEnv DJANGO_SETTINGS_MODULE raid_scheduler.settings
PythonOption django.root /raid-scheduler
PythonDebug On
PythonPath "['/opt', '/opt/raid_scheduler'] + sys.path"
</Location>
</VirtualHost>
Есть идеи относительно того, что может быть причиной этого?
В Unix / Linux каждый процесс может работать в разном часовом поясе. Это связано с тем, что в зависимости от содержимого переменной $ TZ, которая может присутствовать в среде процесса, системные функции, связанные со временем, изменяют свои возвращаемые значения (это не зависит от PHP или Apache). Вероятно, $ TZ модифицируется внутри одного или нескольких ваших процессов Apache. И mod_php, и mod_python являются частью процесса Apache, поэтому они могут свободно изменять $ TZ.
Можно ли вывести getenv ('TZ') в журнал вместе с идентификатором процесса Apache через posix_getpid (), чтобы его можно было использовать для сопоставления с различными запросами пользователей?
Может быть, какой-то другой запрос устанавливает TZ, а он валяется? Запись getenv('TZ')
в начале каждого запроса проверял бы это, и putenv
можно использовать, чтобы обойти это.
Я думаю, что это больше связано с вашими настройками php. Взгляните на переменную окружения mod_php "TZ".
Переменная среды TZ, как и различные переменные среды, связанные с настройками языка и локали, являются глобальными процессами. Таким образом, запуск нескольких экземпляров приложения в одном процессе, будь то Python или PHP, которые хотят установить его по-разному, вызовет проблемы. Эта проблема также влияет на mod_wsgi и обсуждается в:
http://code.google.com/p/modwsgi/wiki/ApplicationIssues#Timezone_and_Locale_Settings
Обратите внимание, что попытка проверить что-либо, глядя на os.environ изнутри веб-приложения Python, может не помочь, поскольку os.environ является копией переменных среды процесса во время создания экземпляра интерпретатора Python (под). Таким образом, любое изменение TZ или других переменных среды не будет отражено в словаре Python os.environ. Синхронизация определенных значений происходит только тогда, когда значение в os.environ обновляется, и в этом случае Python также вызывает функцию putenv () уровня C.