Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.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
Django 在Google云任务上执行失败的每个任务_Django_Google App Engine_Google Cloud Tasks - Fatal编程技术网

Django 在Google云任务上执行失败的每个任务

Django 在Google云任务上执行失败的每个任务,django,google-app-engine,google-cloud-tasks,Django,Google App Engine,Google Cloud Tasks,我需要在Django应用程序中运行一些异步任务,我开始研究Google云任务。我想我已经遵循了所有的指示——以及我能想到的每一种可能的变化,但迄今为止都没有成功 问题是所有创建的任务都进入队列,但无法执行。控制台和日志仅报告http代码301(永久重定向)。为了简单起见,我将相同的代码部署到appengine(标准)的两个服务中,并将任务请求仅路由到其中一个 看起来代码本身运行良好。当我转到“”时,例程执行得很好,并且根据DevTools/Network没有重定向。当云任务尝试调用“/api/v

我需要在Django应用程序中运行一些异步任务,我开始研究Google云任务。我想我已经遵循了所有的指示——以及我能想到的每一种可能的变化,但迄今为止都没有成功

问题是所有创建的任务都进入队列,但无法执行。控制台和日志仅报告http代码301(永久重定向)。为了简单起见,我将相同的代码部署到appengine(标准)的两个服务中,并将任务请求仅路由到其中一个

看起来代码本身运行良好。当我转到“”时,例程执行得很好,并且根据DevTools/Network没有重定向。当云任务尝试调用“/api/v1/Tasks”时,每次都会失败

如果有人能看一下下面的代码,并指出是什么导致了这个失败,我将非常感激

多谢各位

#--------------------------------
# [proj]/.../urls.py
#--------------------------------
from [proj].api import tasks

urlpatterns += [
    # tasks api
    path('api/v1/tasks', tasks, name='tasks'),
]
更新:

以下是执行的日志:

{
 insertId: "1lfs38fa9"  
 jsonPayload: {
  @type: "type.googleapis.com/google.cloud.tasks.logging.v1.TaskActivityLog"   
  attemptResponseLog: {
   attemptDuration: "0.008005s"    
   dispatchCount: "5"    
   maxAttempts: 0    
   responseCount: "5"    
   retryTime: "2020-03-09T21:50:33.557783Z"    
   scheduleTime: "2020-03-09T21:50:23.548409Z"    
   status: "UNAVAILABLE"    
   targetAddress: "POST /api/v1/tasks"    
   targetType: "APP_ENGINE_HTTP"    
  }
  task: "projects/[proj]/locations/us-central1/queues/tectaq/tasks/09687434589619534431"   
 }
 logName: "projects/[proj]/logs/cloudtasks.googleapis.com%2Ftask_operations_log"  
 receiveTimestamp: "2020-03-09T21:50:24.375681687Z"  
 resource: {
  labels: {
   project_id: "[proj]"    
   queue_id: "tectaq"    
   target_type: "APP_ENGINE_HTTP"    
  }
  type: "cloud_tasks_queue"   
 }
 severity: "ERROR"  
 timestamp: "2020-03-09T21:50:23.557842532Z"  
}
问题是所有创建的任务都进入队列,但无法执行。控制台和日志仅报告http代码301(永久重定向)

任务端点的请求处理程序可能需要一个尾随斜杠

尝试更改此选项:

class ManutView(View):
    template_name = '[proj]/manut.html'

    def post(self, request, *args, **kwargs):
        relative_url = '/api/v1/tasks'
        ...
为此:

class ManutView(View):
    template_name = '[proj]/manut.html'

    def post(self, request, *args, **kwargs):
        relative_url = '/api/v1/tasks/'
        ...

另外,您也可以自己点击任务url,看看是否可以从
curl

运行任务。最后,我可以让云任务工作,但只能使用http_请求类型(带有绝对url)。当任务被定义为app_engine_http_request(相对url)时,我无法让它们运行

我已经用POST尝试了http_请求类型,但那是在我免除api函数之前,我没有检查csrf令牌,这导致了一个错误
禁止(Referer checking failed-no Referer.):/api/v1/tasks
,我无法连接到csrf

如果有人在将来偶然发现这个问题,并找到一种方法让app_engine_http_请求在Django的云任务上工作,我仍然非常想知道解决方案

如果有人在将来偶然发现这个问题,并找到一种方法 为了让app_engine_http_请求在Django的云任务上工作,我需要 还是很想知道解决办法

@JCampos我设法让它在我的Django应用程序上工作(我使用了另外的DRF,但我不认为它会造成很大的差异)

然后我使用这样一个视图:

class CloudTaskView(views.APIView):
    authentication_classes = []

    def post(self, request, *args, **kwargs):
        # Do your stuff
        return Response()
最后,我使用
csrf\u-empton(CloudTaskView.as\u-view())


起初我有403错误,但多亏了您和您对csrf_emption的评论,它现在可以工作了。

问题是应用程序引擎任务处理程序不遵循重定向,因此您必须找出请求被重定向的原因,并对应用程序引擎请求破例。在我的例子中,我将http重定向到https,并不得不做出如下例外:(Node Express)


云任务似乎使用HTTP url调用应用引擎(这没关系,因为它们可能在同一个网络中),但如果您使用HTTPs,Django应该重定向(HTTP->HTTPs)正在接收的任何请求,包括处理程序端点

要解决这个问题,您应该告诉Django不要重定向处理程序。
你可以用它

例如:

SECURE\u REDIRECT\u emption=[r“^api/v1/tasks/$”]

views/manut.py文件
views/manut.py
似乎没有包含在任何地方,我不确定该文件的用途。默认情况下,云任务队列已禁用日志记录功能,因此请尝试为正在分派任务的队列启用日志记录功能,可能会在那里显示一些信息:
gcloud beta Tasks Queues update--log sampling ratio=1.0
感谢您提供日志记录提示,@yedpodtrzitko。我启用了它,但情况并没有变得更好,因为错误“不可用”对我来说毫无意义。您能否从
dispatch.yaml
中删除规则
*appspot.com/*
,以确保它不会引起任何问题?默认情况下,所有内容都被路由到
default
服务,因此这在那里应该是不必要的…您可以添加一个简化的示例来复制吗?我从dispatch.yaml中删除了
*appspot.com/*
,但没有任何更改。我将尝试制作一个非常简单的worker,这样问题就可以重现,谢谢。是的,我甚至包括了两个url模式(带和不带尾随斜杠),所以没有一个会被重定向。这两个云上任务的错误相同,从curl或浏览器调用时都成功。我还尝试了GET(没有有效负载/主体)而不是POST,并且一切都保持不变。
#--------------------------------
# [proj]/app.yaml & tasks.yaml:
#--------------------------------
runtime: python37

instance_class: F1

automatic_scaling:
  max_instances: 2

service: default

#handlers:
#- url: .*
#  secure: always
#  redirect_http_response_code: 301
#  script: auto

entrypoint: gunicorn -b :$PORT --chdir src server.wsgi

env_variables:
...
{
 insertId: "1lfs38fa9"  
 jsonPayload: {
  @type: "type.googleapis.com/google.cloud.tasks.logging.v1.TaskActivityLog"   
  attemptResponseLog: {
   attemptDuration: "0.008005s"    
   dispatchCount: "5"    
   maxAttempts: 0    
   responseCount: "5"    
   retryTime: "2020-03-09T21:50:33.557783Z"    
   scheduleTime: "2020-03-09T21:50:23.548409Z"    
   status: "UNAVAILABLE"    
   targetAddress: "POST /api/v1/tasks"    
   targetType: "APP_ENGINE_HTTP"    
  }
  task: "projects/[proj]/locations/us-central1/queues/tectaq/tasks/09687434589619534431"   
 }
 logName: "projects/[proj]/logs/cloudtasks.googleapis.com%2Ftask_operations_log"  
 receiveTimestamp: "2020-03-09T21:50:24.375681687Z"  
 resource: {
  labels: {
   project_id: "[proj]"    
   queue_id: "tectaq"    
   target_type: "APP_ENGINE_HTTP"    
  }
  type: "cloud_tasks_queue"   
 }
 severity: "ERROR"  
 timestamp: "2020-03-09T21:50:23.557842532Z"  
}
class ManutView(View):
    template_name = '[proj]/manut.html'

    def post(self, request, *args, **kwargs):
        relative_url = '/api/v1/tasks'
        ...
class ManutView(View):
    template_name = '[proj]/manut.html'

    def post(self, request, *args, **kwargs):
        relative_url = '/api/v1/tasks/'
        ...
from google.cloud import tasks_v2
from google.protobuf import timestamp_pb2
import datetime

class CloudTasksMixin:
@property
def _cloud_task_client(self):
        return tasks_v2.CloudTasksClient()

def send_to_cloud_tasks(self, url, http_method='POST', payload=None,in_seconds=None, name=None):
    """ Send task to be executed """
    parent = self._cloud_task_client.queue_path(settings.TASKS['PROJECT_NAME'], settings.TASKS['QUEUE_REGION'], queue=settings.TASKS['QUEUE_NAME'])

    task = {
        'app_engine_http_request': {
            'http_method': http_method,
            'relative_uri': url
        }
    }

    ...
class CloudTaskView(views.APIView):
    authentication_classes = []

    def post(self, request, *args, **kwargs):
        # Do your stuff
        return Response()
app.use((req, res, next) => {

   const protocol = req.headers['x-forwarded-proto']
   const userAgent = req.headers['user-agent']

   if (userAgent && userAgent.includes('AppEngine-Google')) {
      console.log('USER AGENT IS GAE, SKIPPING REDIRECT TO HTTPS.')
      return next()
   } else if (protocol === 'http') {
      res.redirect(301, `https://${req.headers.host}${req.url}`)
   } else {
      next()
   }

})