背景:我在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
。
但请注意:
。。你可能会遇到加载请求,即使你的应用程序中启用了预热请求。
这意味着在极少数情况下,新实例不会收到预热请求,因此最好也在用户处理程序中检查初始化状态。