如何防止运行时错误("Unable to create a new session key.")?



客户端的Django应用程序间歇性地(大约每天两次)抛出RuntimeError("Unable to create a new session key."):

    Traceback (most recent call last):
  File "/usr/local/lib/python2.6/dist-packages/django/core/handlers/base.py", line 111, in get_response
    response = callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/views/decorators.py", line 17, in _checklogin
    if request.user.is_active and request.user.is_staff:
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/auth/middleware.py", line 9, in __get__
    request._cached_user = get_user(request)
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/auth/__init__.py", line 107, in get_user
    user_id = request.session[SESSION_KEY]
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py", line 47, in __getitem__
    return self._session[key]
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/base.py", line 195, in _get_session
    self._session_cache = self.load()
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/cache.py", line 16, in load
    self.create()
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/sessions/backends/cache.py", line 33, in create
    raise RuntimeError("Unable to create a new session key.")
RuntimeError: Unable to create a new session key.

从回溯中可以看到,当使用缓存会话后端和memcached缓存后端时,这种情况发生在django.contrib.sessions的深处。

Django跟踪票证(https://code.djangoproject.com/ticket/14093)建议将会话密钥哈希值从MD5更改为uid4,但这没有帮助——问题是网络。我观察到(使用tcpdump),当从应用服务器到memcache服务器的TCP连接由于数据包丢失而超时时,可能会发生此异常。

我们有两个应用服务器和一个memcached(1.4.2)服务器,都运行在Amazon EC2上。在高需求期间,我观察到一个应用程序服务器与memcache服务器每秒交换75,000个数据包。在这段高需求期间,我观察到一个新的memcache连接的SYN包丢失了,导致python-memcache连接超时(在内核甚至有机会重新传输之前)和RuntimeError

我不知道如何解决这个问题。我希望将Linux的TCP重传计时器调优到3秒以下,但这是不可调的。如果做不到这一点,我想让python-memcache在放弃之前重试连接几次,但它不会。我看到pylibmc有可配置的连接和重试行为,但我还没能找到一个组合的选项,工作围绕丢包。

想法?


更新:

对于看到"无法创建新的会话键"的用户;一直以来,这只是意味着您的memcache没有正确设置。下面的一些答案讨论了要检查的事情(软件包安装了吗?

我们遇到的问题是间歇性—几千个请求中只有一个会失败。我使用tcpdump来显示,当TCP三次握手中的三个数据包中的一个丢失时(由于网络拥塞),会发生这种情况,导致python-memcache超时并引发异常,导致"无法创建新的会话密钥";RuntimeError .

在云提供商网络中丢包可能是不可避免的。理想情况下,Linux内核会使TCP初始重传计时器可配置,但在我研究这个问题时,情况似乎并非如此。这意味着python-memcache库本身需要具有某种超时-重试逻辑,而它(当时)没有。

看起来Django缓存后端的新版本增加了一个重试循环,这应该可以避免这种间歇性的失败,但代价是请求偶尔会多花几秒钟的时间。

刚刚解决了apt-get install memcached的相同问题。也许这也是你的情况。

哦,对不起,这不是你的案子。我只是更仔细地读了题目。但我会留下我的答案,因为这是关于运行时错误的。

查看launchpad上的python-memcached代码,您应该能够调整dead_retryretry_timeout。另一种选择可能是在一个或两个应用服务器上运行低内存、低连接的memcached实例,作为主memcached服务器不可达时的后备。

https://github.com/django/django/blob/master/django/contrib/sessions/backends/cache.py

def create(self):
    # Because a cache can fail silently (e.g. memcache), we don't know if
    # we are failing to create a new session because of a key collision or
    # because the cache is missing. So we try for a (large) number of times
    # and then raise an exception. That's the risk you shoulder if using
    # cache backing.
    for i in xrange(10000):
        self._session_key = self._get_new_session_key()
        try:
            self.save(must_create=True)
        except CreateError:
            continue
        self.modified = True
        return
    raise RuntimeError("Unable to create a new session key.")
  • 你可以用猴子补丁django.contrib.sessions.backends.base.SessionBase._get_new_session_key来做time.sleep(0.001)
  • 你也可以检查你的熵:

命令如下:

cat /proc/sys/kernel/random/entropy_avail

我得到这个错误运行本地,开发版本的Django项目,因为它是定期有问题连接到非本地缓存。我意识到我可以将会话后端改为基于文件的会话来解决这个问题。

在Django本地开发版本的设置文件中,我简单地设置了以下值:

SESSION_ENGINE = 'django.contrib.sessions.backends.file'

这不是我在生产环境中使用的解决方案,也不是我建议原始海报的解决方案,但我花了几分钟才弄清楚问题是什么,这是我在谷歌搜索时出现的唯一结果之一,所以我想我可能会在这里发帖帮助其他人解决类似的问题。

在memcache配置文件中(例如:/etc/sysconfig/memcached/etc/memcached.conf),您可能需要更改:

-l 127.0.0.1

-l 0.0.0.0

允许web服务器连接到memcache服务器(如果它们在不同的主机上)。

我遇到过同样的问题,检查django和memcached中配置的端口。可能两者都不一样

你可以改变memcached端口vim/etc/memcached.conf找到'Default connection port is'根据你的需要重新启动memcached服务

这就是CPU短缺。当请求完成时,监视/var/log/apache/error.log可能是监视的最佳位置。当您使用web控制台时,还可以使用htop tp监控您的CPU。你应该增加CPU核数

相关内容

最新更新