Clojure 应用程序无法在 Heroku 上启动;阿莱夫+ RedisToGo 超时
我的 clojure noir 应用程序在本地运行 100% 正常,并且连接到 RedisToGo 没有问题。
问题是当我部署到 Heroku (git push heroku master) 时,出现超时错误:
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
完整日志在这里: https ://gist.github.com/1842439
当我删除这个redis连接代码时,它部署得很好:
(:use [aleph.redis :only (redis-client)])
(def r (redis-client {:host redis-url :password redis-pass :port redis-port}))
奇怪的是,当我运行“heroku run lein run repl”并粘贴到aleph时上面的代码,它可以很好地连接到redis,并且我可以读取/写入数据。
因此,这与 heroku 如何启动应用程序有关,从而中断与 RedisToGo 的连接并使其超时。
My clojure noir app works 100% fine locally and connects to RedisToGo no problem.
The problem is when I deploy to Heroku (git push heroku master), I get a timeout error:
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
Full log is here: https://gist.github.com/1842439
When I remove this redis connection code, it deploys fine:
(:use [aleph.redis :only (redis-client)])
(def r (redis-client {:host redis-url :password redis-pass :port redis-port}))
The weird thing is that when I run "heroku run lein run repl" and paste in the aleph code above, it connects to redis fine and I can read/write data.
So it something about how heroku boots up the app thats breaking the connection to RedisToGo and timing it out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在顶层做一些副作用是非常可疑的——代码在编译时和执行时都被执行,所以 Heroku 的自动 uberjar 所做的可能会失败,因为 redis 在编译时不可用,或者类似的事情。
相反,请在调用
-main
后初始化您的 Redis 客户端,这将确保您处于生产环境中。您可以通过多种方式实现此目的,例如,首先将其定义为 nil,然后在-main
中执行alter-var-root
。我首选的解决方案可能是这样的:现在,直到有人解除对客户端的引用后,才会执行连接代码,而在应用程序启动并运行之前,他们不应该这样做。
Doing something side-effecty at the top level is very suspect - that code is executed when compiling as well as when executing, so probably the automatic uberjar Heroku does is failing because redis isn't available at compile time, or something like that.
Instead, initialize your redis client after
-main
has been called, which will ensure you are in a production environment. You can accomplish this in a number of ways, for example by initially defining it to nil and then performing analter-var-root
in-main
. My preferred solution would probably be something like:Now the code to connect isn't performed until someone derefs the client, which they should never do until the app is up and running.