在我的Django + postgresql网站上,我需要在某个时间点公开显示所有内容都是在线的(这是一个社交网站)。我该怎么做?例如,是否有一种方法可以枚举在前10分钟内访问我的nginx webserver的所有登录用户?像这样的东西会管用的。我是一个初学者,目前正在寻找可行的解决方案。
目前,为了实现这一点,我将会话存储到数据库中,使用外部库使会话可枚举。这使我可以在一段时间内询问有多少唯一的用户在线。
但是该方案产生了大量不必要的DB通信量。因此,日志记录和剪枝日志变得无效。此外,pgFouine向我展示了与会话相关的DB调用是我的网站目前面临的最大性能瓶颈。
有一个建议的解决方案这里,但它使用数据库。
发布于 2016-11-29 15:55:27
目前,我正在尝试另一种方法。我编写了一个中间件,在每个请求中,用户的user_id是全局排序集中的已存储。只有在他们被认证的情况下,我才会这样做,并且我使用redis键值存储来确保一切都非常快。
解决方案还没有实现。我将在这里报告更多,并给出一个完整的答案,一旦我完成。在标记正确的解决方案之前,我还将考虑这里给出的其他答案。
发布于 2016-11-27 19:52:36
使用django的缓存框架将db查询的结果保存到内存中。这样,您就不需要为每个页面呈现执行昂贵的数据库查询。
from django.core.cache import cache
def count_current_users():
users = cache.get('users')
if users is None:
# last count has timed out
users = do_expensive_db_query()
cache.set('users', users, timeout=500)
return usershttps://docs.djangoproject.com/en/1.10/topics/cache/#basic-usage
您还可以使用模板片段缓存并编写一个只在缓存陈旧时运行db查询的自定义模板标记。这将缓存结果500秒。
{% cache 500 logged_in_users %}
{% expensive_query_db_for_logged_in_users %}
{% endcache %}如果您希望您的用户计数更实时,您可能必须绕过django的缓存框架,直接与Redis通信。将每个登录用户存储为一个键,并有固定的生存期。从Redis获取当前活动键的列表将比sql数据库的等效查询便宜得多。它也可以用几行python代码来实现。
发布于 2016-11-27 18:40:36
如果您使用django-用户会话,则会话模型有一个last_activity字段。
你也许可以做这样的事情:
from user_sessions import Session
from datetime import datetime, timedelta
time_threshold = datetime.now() - timedelta(minutes=10)
qs = Session.objects.filter(last_activity__gt=time_threshold)尽管如此,django-user-sessions在该字段上没有数据库索引,这意味着如果您有大量的用户/会话,那么查询可能会很困难,需要很长时间。一个更复杂的答案可能包括创建一个物化视图(如果您正在使用postgres),该视图通过cron作业刷新。
https://stackoverflow.com/questions/40827564
复制相似问题