Apache时间问题

时间:2013-07-30 21:08:10

标签: python django apache

我目前有一个使用cookie会话的django网站。我注意到会话随机被注销。在调试时我发现这是由于我的代码中的逻辑看着会话的年龄。 然而,我注意到在没有问题的时期,Apache时间戳中显示正确的时间。但是那时tiemstamp又恢复了5个小时,然后导致我的Django程序认为会话已经过期并将其注销。

下面给出一个例子,

[Wed Jul 31 16:12:45 2013] [error] DEBUG ok elapsed time 7
[Wed Jul 31 16:12:45 2013] [error] DEBUG ok elapsed time 1
[Wed Jul 31 10:12:46 2013] [error] DEBUG : request.user.is_authenticated()
[Wed Jul 31 10:12:46 2013] [error] DEBUG ok elapsed time 64809
[Wed Jul 31 10:12:46 2013] [error] DEBUG  since begin . elapsedTime.seconds 64809
[Wed Jul 31 10:12:46 2013] [error] DEBUG request.session\\['deginRequest'\\]
[Wed Jul 31 10:12:46 2013] [error] DEBUG ok elapsed time 64801
[Wed Jul 31 10:12:46 2013] [error] DEBUG  since last req . elapsedTime.seconds 64801
[Wed Jul 31 10:12:46 2013] [error] DEBUG request.session\\['lastRequest'\\]
[Wed Jul 31 10:12:47 2013] [error] DEBUG : shouldLogout

这个问题也随机发生。有什么想法吗?

此外,我使用的中间件(生成这些日志),

class timeOutMiddleware(object):

    def process_request(self, request):

        shouldLogout = False

        if request.user.is_authenticated():
            print "DEBUG :request.user.is_authenticated()"
            if 'beginSession' in request.session:
                elapsedTime = datetime.datetime.now() - \
                              request.session['beginSession']
                print "DEBUG ok elapsed time",elapsedTime.seconds
                if elapsedTime.seconds > 12*3600:
                    print "DEBUG  since begin . elapsedTime.seconds",elapsedTime.seconds
                    del request.session['beginSession']
                    print "DEBUG  request.session\[\'deginRequest\'\]"

                    shouldLogout = True
            else:
                request.session['beginSession'] = datetime.datetime.now()

            if 'lastRequest' in request.session:
                elapsedTime = datetime.datetime.now() - \
                              request.session['lastRequest']
                print "DEBUG ok elapsed time",elapsedTime.seconds
                if elapsedTime.seconds > 2*3600:
                    print "DEBUG   since last req . elapsedTime.seconds",elapsedTime.seconds
                    del request.session['lastRequest']
                    shouldLogout = True

            request.session['lastRequest'] = datetime.datetime.now()


            username = request.user
            if ####.objects.get(username=username).token:
                print "DEBUG : ####.objects.get(username=username).token"

                try:
                    token = ####.objects.get(username=username).token
                    url = 'https://############/%s' % (token)
                    response = requests.get(url)
                    answer = json.loads(response.text)
                    #print "DEBUG answer",answer
                    if not answer["valid"]:
                        shouldLogout = True
                        print "DEBUG",datetime.now(),"not answer[\"valid\"]"
                except:
                    shouldLogout = True
                    print "DEBUG except"
            else:
                shouldLogout = True
                print "DEBUG else"

            if shouldLogout:
                print "DEBUG : ",datetime.datetime.now(),"shouldLogout"
                logout(request)

        else:
            if 'beginSession' in request.session:
                del request.session['beginSession']
            if 'lastRequest' in request.session:
                del request.session['lastRequest']

        return None

4 个答案:

答案 0 :(得分:2)

这似乎是OS / HW配置错误。

我怀疑有时您的网络出现故障且操作系统(操作系统)需要从硬件时钟获取数据但是ntp。

您应确保 BIOS时钟UTC配置与/etc/default/rcS参数匹配

# assume that the BIOS clock is set to UTC time (recommended)
UTC=no

另外,请确保您的时区配置正确:

root@egg-v3:/etc# cat /etc/timezone 
Europe/Barcelona

一些简单的测试:

  • 启动没有ntp的机器。如果系统数据不正确,请尝试更改UTC参数。
  • 使用hwclock命令进行游戏:

样品:

root@egg-v3:/etc# hwclock 
Fri 02 Aug 2013 04:30:54 PM CEST  -0.609670 seconds
root@egg-v3:/etc# date
Fri Aug  2 14:30:55 CEST 2013

答案 1 :(得分:2)

Apache日志表明一个非常离散的时间步长为5小时,因此这不太可能是通过保留守护进程(如ntp)进行的基础系统时间调整。我猜这几乎肯定与时区设置有关。

如果您使用mod_wsgi以非守护进程模式为您的应用程序提供服务,则可能存在来自环境的进程之间的共享状态。特别是,您应该注意以下链接中的信息:https://code.google.com/p/modwsgi/wiki/ApplicationIssues#Timezone_and_Locale_Settings

正如其他答案中所建议的那样,始终以UTC格式存储时间并仅转换为特定时区的演示文稿是个好主意。

考虑在wsgi守护程序模式下运行您的应用程序。来自mod_wsgi docs

  

虽然嵌入式模式在技术上可以更好地执行守护进程模式   通常是最安全的选择。

守护进程模式确保您有一个独立的进程处理您的应用程序,不会受到其他wsgi进程的环境污染。例如TZ环境变量变化。

答案 2 :(得分:1)

这可能无法解决您的问题,但值得建议。把它放在评论中看起来不合适。


使用时区感知日期时间对象而不是天真的对象(datetime.datetime.now()为您提供。)

在处理日期/时间时使用datetime.datetime.utcnow()而不是.now()

所以来自django timezones

import datetime
from django.utils.timezone import utc

now = datetime.datetime.utcnow().replace(tzinfo=utc)

当将request.session['beginSession']中存储的时间从天真地转换为时区感知对象时,django可能会应用时区。

答案 3 :(得分:0)

日志文件中时间戳的差异通常是因为您的系统时区与Django配置使用的时区不同。如果使用Apache / mod_wsgi的嵌入式模式,您也可能遇到同样在同一台Apache服务器上托管PHP应用程序而PHP使用不同时区的问题。