从Go on AppEngine中的init()函数获取URL



背景:我在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路由器,它就不想工作。因此,我不知道如何在URL处理程序的范围之外进行urlFetch。

传递mux路由器时出错:"不能将r(类型*mux.router)用作"appengine".NewContext"的参数中的类型*http.Request

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

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

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

是的,这可能会导致首次请求需要相当长的时间才能送达。为此(为了避免这种情况),我建议您使用预热请求。在新实例"运行"之前,在它开始为用户请求提供服务之前,会向它发出一个预热请求。在app.yaml配置文件中,您可以通过将-warmup添加到inbound_services指令来启用预热请求:

inbound_services:
- warmup

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

但请注意:

。。你可能会遇到加载请求,即使你的应用程序中启用了预热请求。

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

最新更新