【问题标题】:Fetching a URL From the init() func in Go on AppEngine从 AppEngine 上的 Go 中的 init() 函数获取 URL
【发布时间】:2015-07-06 21:13:50
【问题描述】:

背景:我在 GAE 上运行 Go 并为我的路由器使用 Mux。为了获取 URL GAE 要求我使用其内置的 urlFetch 功能。我想在我的模块 init() 期间进行此 URL 获取,但据我所知,我只能在通过处理程序调用时使用 urlFetch。

func init() {
  r := mux.NewRouter()
  r.HandleFunc("/", homeHandler)
  r.HandleFunc("/about", anotherHandler)
  http.Handle("/", r)
}

GAE 建议使用以下代码来制作 urlFetch:

c := appengine.NewContext(r)
client := urlfetch.Client(c)

... 但它的参数是一个 http 路由器,如果我通过我的 mux 路由器,它就不会工作。所以我不知道如何让这个 urlFetch 在 URL 处理程序的范围之外发生。

传递多路复用路由器时出错:“不能在“appengine”.NewContext 的参数中使用 r(类型 *mux.Router)作为类型 *http.Request”

【问题讨论】:

  • "... 但它的参数是一个 http 路由器..." 它不是一个 http 路由器,它是一个 *http.Request 所以显然你不能传递一个 @ 987654324@ 值。

标签: google-app-engine go spreadsheet mux


【解决方案1】:

您不能在处理程序之外使用需要 Context 的 AppEngine 服务(因为创建 Context 需要 *http.Request 值)。这本质上意味着您也不能在包 init() 函数中使用它们。
请注意,您可以从添加到任务队列的 cron 作业和任务中使用它们,因为任务和 cron 作业是通过发出 HTTP 来执行的GET 请求。

您必须重组代码,以便从处理程序调用服务(在您的情况下为 urlFetch)。

一个可能的解决方案是检查 init 是否在服务用户请求的处理程序中完成。如果没有,请在继续处理请求之前执行初始化函数,否则您将在 init() 中输入。

是的,这可能会导致首次请求的服务时间要长得多。为此(为避免这种情况),我建议您使用Warmup requests。在新实例“上线”之前,在它开始为用户请求提供服务之前,会向它发出预热请求。在您的 app.yaml 配置文件中,您可以通过将 -warmup 添加到 inbound_services 指令来启用预热请求:

inbound_services:
  - warmup

这将导致 App Engine 基础架构首先向 /_ah/warmup 发出 GET 请求。您可以向此 URL 注册处理程序并执行初始化任务。与任何其他请求一样,您将在预热处理程序中拥有一个http.Request

但请注意:

..您可能会遇到loading requests,即使您的应用中启用了预热请求。

这意味着在极少数情况下,新实例可能不会收到预热请​​求,因此最好也检查用户处理程序中的初始化状态。

【讨论】:

  • 继续加油,感谢 Icza !超级有帮助,热身请求很划算。
猜你喜欢
  • 2011-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
相关资源
最近更新 更多