背景:我在 GAE 上运行 Go 并为我的路由器使用 Mux。为了获取 URL,GAE 要求我使用其内置的 urlFetch 功能。我想让这个 URL 获取在我的模块 init() 期间发生,但据我所知,我只能在通过处理程序调用时使用 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 处理程序的范围之外发生。
传递 mux 路由器时出错:“无法在“appengine”.NewContext 的参数中使用 r(类型 *mux.Router)作为类型 *http.Request”
最佳答案
您无法使用需要 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
在预热处理程序中。
但请注意:
..you may encounter loading requests, even if warmup requests are enabled in your app.
这意味着在极少数情况下,新实例可能不会收到预热请求,因此最好也检查用户处理程序中的初始化状态。
关于google-app-engine - 从 Go on AppEngine 中的 init() 函数获取 URL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29912318/