繁体   English   中英

Cron 总是失败,手动执行总是成功。 如何?

[英]Cron always fails and manual execution always succeeds. How?

我有一份工作,每晚运行计算并将结果存储在 sqlite 文件谷歌存储中。 当我手动运行时,计划任务总是成功。 当 cron (Google Cloud Scheduler) 运行它时,它总是失败。 日志没有给出有意义的错误消息。 502 错误代码。 启动一个无关紧要的新实例。 我设置了 cron.yaml 重试 2 次。 但所有处决都失败了。

我的 cron.yaml

- description: "PAPER GO calc from alpaca to /tmp/entries.sqlite"
  target: default
  url: /calcentriesindb
  schedule: every sun,mon,tue,wed,thu  20:00
  timezone: America/New_York
  retry_parameters:
    job_retry_limit: 2
    min_backoff_seconds: 30

最上面的日志条目是手动执行。 以下 3 次是 cron 尝试。 在此处输入图像描述

从 502 错误完成日志条目

{
  "protoPayload": {
    "@type": "type.googleapis.com/google.appengine.logging.v1.RequestLog",
    "appId": "s~wc2022-356423",
    "versionId": "20220730t143529",
    "requestId": "62eb0c5d00ff0bb76d8eabcbfc0001737e7763323032322d3335363432330001323032323037333074313433353239000100",
    "ip": "0.1.0.2",
    "startTime": "2022-08-04T00:01:33.767986Z",
    "endTime": "2022-08-04T00:01:34.565759Z",
    "latency": "0.797773s",
    "method": "GET",
    "resource": "/calcentriesindb",
    "httpVersion": "HTTP/1.1",
    "status": 502,
    "responseSize": "288",
    "userAgent": "AppEngine-Google; (+http://code.google.com/appengine)",
    "urlMapEntry": "auto",
    "host": "default.wc2022-356423.uc.r.appspot.com",
    "cost": 3.2186e-8,
    "taskQueueName": "__cron",
    "taskName": "05697141537686660811",
    "wasLoadingRequest": true,
    "instanceIndex": -1,
    "finished": true,
    "instanceId": "00c61b117c3c5fa64d13a841d4e8db781b8d5f07b01c3875537cbb754a073373efdb153e58e5d70a725960c452ea04b253df39c0c286628e0dec6d",
    "line": [
      {
        "time": "2022-08-04T00:01:34.565621Z",
        "severity": "INFO",
        "logMessage": "This request caused a new process to be started for your application, and thus caused your application code to be loaded for the first time. This request may thus take longer and use more CPU than a typical request for your application."
      }
    ],
    "appEngineRelease": "1.9.71",
    "traceId": "115ab8ca6be26417bc63bb90824dbd71",
    "first": true,
    "traceSampled": true,
    "spanId": "1960824541831512114"
  },
  "insertId": "62eb0c5e0008a2c1355ad083",
  "httpRequest": {
    "status": 502
  },
  "resource": {
    "type": "gae_app",
    "labels": {
      "project_id": "wc2022-356423",
      "zone": "us16",
      "module_id": "default",
      "version_id": "20220730t143529"
    }
  },
  "timestamp": "2022-08-04T00:01:33.767986Z",
  "severity": "INFO",
  "labels": {
    "clone_id": "00c61b117c3c5fa64d13a841d4e8db781b8d5f07b01c3875537cbb754a073373efdb153e58e5d70a725960c452ea04b253df39c0c286628e0dec6d"
  },
  "logName": "projects/wc2022-356423/logs/appengine.googleapis.com%2Frequest_log",
  "operation": {
    "id": "62eb0c5d00ff0bb76d8eabcbfc0001737e7763323032322d3335363432330001323032323037333074313433353239000100",
    "producer": "appengine.googleapis.com/request_id",
    "first": true,
    "last": true
  },
  "trace": "projects/wc2022-356423/traces/115ab8ca6be26417bc63bb90824dbd71",
  "receiveTimestamp": "2022-08-04T00:01:34.572846740Z",
  "spanId": "1960824541831512114",
  "traceSampled": true
}

从处理程序调用的关键 function :

func CalcEntriesInDb() (interface{}, error) {
    symbols, err := getTradableSymbols()
    if err != nil {
        log.Fatal("getTradableSymbols failed.", err)
    }

    log.Println(len(symbols), "symbols to scan.")
    createPath(c.EntryDbPath) // forces a specific path to exist including creation of folders.
    runList := GetRunList(c.RefDbPath)
    ////loadHistory because of weekends and holidays lets gather more than 13 days to get enough trail for minlow
    rowcount, err := loadHistory(20, symbols, c.EntryDbPath)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(`Running `, len(runList), `sql scripts.`)
    runSqlScripts(runList, c.EntryDbPath)

    err = gcsUp(c.EntryDbPath)
    sendEmail("Entries Calculated", PrintTableHTML(c.EntryDbPath, "entry"), c.EntryDbPath)

    return rowcount, err
}

这是我的 indexHandler 的摘录

func indexHandler(w http.ResponseWriter, r *http.Request) {
    spew.Dump(r.URL.Query())
    params := r.URL.Query()
    var apikey string
    log.Println("X-Appengine-Cron", r.Header["X-Appengine-Cron"])
    //log.Println(params["marina"])
    if len(params["marina"]) == 1 {
        apikey = params["marina"][0]
    }

    if len(r.Header["X-Appengine-Cron"]) > 0 || apikey == c.Apikey {
        log.Println("Key or Param passed.")
    } else {
        http.NotFound(w, r)
        return
    }
    //spew.Dump(r.URL.Path)
    switch r.URL.Path {
    case "/calcentriesindb":
        resp, err := CalcEntriesInDb()
        if err != nil {
            _, err = fmt.Fprint(w, err)
        } else {
            _, err = spew.Fprint(w, resp)
        }

我曾经遇到过类似的问题,但我不记得状态代码是否为 502。过去发生的事情是 - 当我通过 Cron UI 运行作业时,它会报告“失败”状态,但如果我手动调用该作业,它将成功完成。

后来我发现问题是 - cron 作业旨在返回 200 - 299 之间的状态(请参阅文档)。 我的 cron 作业调用的路由将任务添加到队列,然后重定向到我的主页(这意味着它返回 301)。 我将其更改为返回一个固定的文本(例如“完成”),它是一个 200 状态并解决了问题。

我终于让 gae cron 工作了。 我创建了一个包含 apikey 的 cron 条目。 这是一种解决方法,而不是修复方法。 我没有安排/calcentriesindb我安排了/calcentriesindb?marina=apikey 我编写的代码在从应用引擎 cron 执行时不需要 api 密钥。 那好吧。 应用引擎处理计划请求的方式肯定仍然存在问题。 此外,如果您没有在其他评论中看到 - 使用 curl 从完全不同的服务器调度请求完美无缺。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM