Heroku Go应用程序崩溃

5
按照这个教程,我在本地环境中一切正常。但是当我将应用部署到Heroku并在浏览器上访问时,出现了503错误和以下信息:

应用程序错误 应用程序发生错误,无法为您提供页面服务。请稍后再试。 如果您是应用程序所有者,请检查日志以获取详细信息。

日志显示:

2015-09-08T16:31:53.976824+00:00 heroku[web.1]: State changed from crashed to starting
2015-09-08T16:31:56.174376+00:00 heroku[web.1]: Starting process with command `mywebsite`
2015-09-08T16:31:59.312461+00:00 app[web.1]: Listening on port: 39461
2015-09-08T16:32:56.471550+00:00 heroku[web.1]: Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
2015-09-08T16:32:56.471550+00:00 heroku[web.1]: Stopping process with SIGKILL
2015-09-08T16:32:57.390752+00:00 heroku[web.1]: Process exited with status 137
2015-09-08T16:32:57.404208+00:00 heroku[web.1]: State changed from starting to crashed
2015-09-08T16:32:57.645135+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" host=boiling-eyrie-6897.herokuapp.com request_id=ec26... fwd="xx.xxx.xxx.xxx" dyno= connect= service= status=503 bytes=
2015-09-08T16:32:58.233774+00:00 heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/favicon.ico" host=boiling-eyrie-6897.herokuapp.com request_id=ef40...fwd="xx.xxx.xxx.xxx" dyno= connect= service= status=503 bytes=

我明白出现了什么错误,但是一个如此简单的教程应用怎么会导致启动超时(R10)呢?
我该如何更好地调试并修复应用程序以使其运行?

你的应用程序是否可能只绑定在本地连接循环上而不是所有连接上(这会导致平台无法检测到端口已被绑定,从而使应用程序崩溃)? - Damien MATHIEU
@DamienMATHIEU 抱歉,我不确定你的意思。"在本地连接循环上而不是所有连接上"是什么意思? - sargas
如果您的应用程序仅在localhost上进行侦听,则进程监视器无法检测到绑定的端口。您需要在所有可用的网络连接上进行绑定。请参见https://github.com/heroku/go-getting-started/blob/master/cmd/go-getting-started/main.go#L27 - Damien MATHIEU
1
@DamienMATHIEU,确实是这种情况。代码中有 http.ListenAndServe("127.0.0.1:"+port, nil),而应该是 http.ListenAndServe(":"+port, nil)。请将此作为答案提交。 - sargas
1
有趣的是,当你问一个初学者问题时,却会被负评。我不想评判为什么人们会给这样格式良好的问题点赞,而不管它是否对他们的水平来说很愚蠢。至少留下一条评论说明负评的原因或编辑问题。 - sargas
我投了一票给你以示赞赏 :) - Damien MATHIEU
2个回答

9

当您通过Heroku部署应用程序时,它不允许您指定端口号
换句话说,您无法将您的Web服务的端口号指定为8000或其他任何值,Heroku在运行时决定端口号。
因此,您不能使用以下代码:

    log.Fatal(http.ListenAndServe(":8000", router))

您可以获取Heroku的运行时端口。
简而言之,只需使用以下代码:
    log.Fatal(http.ListenAndServe(":" + os.Getenv("PORT"), router))

7
你的应用程序需要监听所有的网络连接。如果仅仅监听本地连接,Heroku 的进程监视器就无法检测到你已绑定端口,也无法向你的应用程序发送请求。
这意味着,不要这样做:
http.ListenAndServe("127.0.0.1:"+port, nil)

您需要调用:

http.ListenAndServe(":"+port, nil)

还可参考Heroku使用Go应用的入门指南:https://github.com/heroku/go-getting-started/blob/master/cmd/go-getting-started/main.go#L27


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接