Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django本地内存缓存在heroku上不工作_Python_Django_Heroku_Caching_Django Rest Framework - Fatal编程技术网

Python Django本地内存缓存在heroku上不工作

Python Django本地内存缓存在heroku上不工作,python,django,heroku,caching,django-rest-framework,Python,Django,Heroku,Caching,Django Rest Framework,我需要使用基于SMS的OTP对django rest框架应用程序中的用户进行身份验证。为此,我创建了以下API端点 GET \otp - generate and send OTP and store it in cache POST \otp - validate OTP based on value store in cache 这是我的密码- from django.core.cache import cache # It is used just for debugging &

我需要使用基于SMS的OTP对django rest框架应用程序中的用户进行身份验证。为此,我创建了以下API端点

GET \otp - generate and send OTP and store it in cache
POST \otp - validate OTP based on value store in cache
这是我的密码-

from django.core.cache import cache

# It is used just for debugging & logging purpose
local_cache = {}

class OTPView(APIView):
    def get(self, request):
        serializer = ContactSerializer(data=request.query_params)
        num = serializer.validated_data.get('contact_number')
        otp = generate_otp()
        cache.set(num, otp, 300)
        local_cache[num] = otp
        print('GET Cache is : ', local_cache)
        return Response('OTP Sent')

    def post(self, request):
        serializer = OTPSerializer(data=request.data)
        num = serializer.validated_data.get('contact_number')
        otp = serializer.validated_data.get('otp')
        print('POST Cache is : ', local_cache)
        otp_in_cache = cache.get(num)
        if otp_in_cache is None:
            return Response('No OTP or prev expired')
        elif otp == otp_in_cache:
            return Response('Success')
        else:
            return Response('Incorrect OTP')
要在内存缓存中使用的两个请求之间持久化OTP。它在我的本地机器上按预期工作,但在部署到Heroku上时却无法正常工作。以下是heroku的日志供参考-

2020-09-02T17:17:22.556785+00:00 app[web.1]: Number is 6666660008 and otp is 541609
2020-09-02T17:17:22.556798+00:00 app[web.1]: GET Cache is :  {'6666660008': '541609'}
2020-09-02T17:17:22.558975+00:00 app[web.1]: 10.69.31.173 - - [02/Sep/2020:22:47:22 +0530] "GET /account/api/otp/?contact_number=6666660008 HTTP/1.1" 200 36 "https://direct-fresh-chicken.netlify.app/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/77.0.3865.90 Chrome/77.0.3865.90 Safari/537.36"
2020-09-02T17:17:32.897997+00:00 app[web.1]: POST Cache is :  {}
2020-09-02T17:17:32.898035+00:00 app[web.1]: Error 400: No OTP or prev expired.
2020-09-02T17:17:32.900342+00:00 app[web.1]: 10.69.31.173 - - [02/Sep/2020:22:47:32 +0530] "POST /account/api/otp/ HTTP/1.1" 400 66 "https://direct-fresh-chicken.netlify.app/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/77.0.3865.90 Chrome/77.0.3865.90 Safari/537.36"
我知道本地内存缓存不适合生产,最终我计划使用更好的替代方案,如memcached

我想知道-

  • 为什么本地内存缓存不能在heroku上运行
  • 为什么
    local\u cache
    dictionary对象在post方法中有空值(请参阅日志)
  • 我可以在heroku上使用吗?如果是,我应该使用什么配置
  • 除了使用缓存,还有其他可能的方法来验证OTP吗
关于Heroku上的本地内存缓存 一般来说,本地内存缓存在Heroku上运行良好。但是有一个限制:本地缓存dict和Django
locmem
缓存后端都是进程和dyno的本地缓存

因此,例如,如果您使用的是
gunicorn
,则默认情况下,它将使用子进程来处理请求。每个子进程都有自己的
locmem
缓存。这个

现在关于一般设置问题: 一般来说,本地缓存对于生产使用来说是完全好的(而且速度非常快),前提是进程/动态限制对您来说很好,并且您无法在不重新启动所有动态对象的情况下清除整个缓存

文件系统缓存也可以工作,但也只是dyno的本地缓存,这意味着只有通过重新启动所有dyno才能进行清理

在一个应用程序有多个服务器/容器的环境中,实际上最好有一个单独的缓存,比如redis、memcached等等。。。所有的迪诺人都能进入

缓存和OTP 通常,您可以使用此处的缓存来存储令牌。这里的风险在于,具体取决于实际的缓存后端:如果缓存已满,它将删除数据。对于真正的缓存来说,这通常是很好的,但对于OTP来说,这将是一个问题

在您的情况下,您可以,它足够大,可以容纳所有当前有效的令牌