2

背景:我在 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”

4

1 回答 1

4

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

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

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

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

inbound_services:
  - warmup

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

但请注意:

..即使在您的应用中启用了预热请求,您也可能会遇到加载请求。

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

于 2015-04-28T08:23:26.007 回答