简短回答:查看@kch 的回答。
310: HTML Content URL Required
运行一个网络测功机时出现错误。
以下是相关日志:
2012-07-04T19:11:13+00:00 heroku[router]: Error H12 (Request timeout) -> POST my-app-1111.herokuapp.com/campaigns dyno=web.1 queue= wait= service=30000ms status=503 bytes=0
2012-07-04T19:11:13+00:00 app[web.1]: cache: [GET /favicon.ico] miss
2012-07-04T19:11:13+00:00 heroku[router]: GET my-app-1111.herokuapp.com/favicon.ico dyno=web.1 queue=0 wait=0ms service=50ms status=304 bytes=0
2012-07-04T19:11:14+00:00 heroku[router]: Error H12 (Request timeout) -> GET my-app-1111.herokuapp.com/newsletters/1?cm=1 dyno=web.1 queue= wait= service=30000ms status=503 bytes=0
2012-07-04T19:11:14+00:00 app[web.1]: [error] CampaignMonitor error: The CreateSend API responded with the following error - 310: HTML Content URL Required
看到Request timeout
错误GET my-app-1111.herokuapp.com/newsletters/1?cm=1
让我想起了 Campaign Monitor 立即为所有时事通讯资产回调我的应用程序。
当我将网络测功机的数量增加到两个时,有时错误会变为312: Text Content URL Required
并且它会超时GET my-app-1111.herokuapp.com/newsletters/1.txt
;其他时候(仍然有两个 dynos)API 不会出错(实际上创建了活动草稿),但应用程序在其他资产上超时(并且网站仍然产生股票Application Error
)。以下是其中一些资产超时:
2012-07-04T19:20:21+00:00 heroku[router]: Error H12 (Request timeout) -> POST my-app-1111.herokuapp.com/campaigns dyno=web.1 queue= wait= service=30000ms status=503 bytes=0
2012-07-04T19:20:24+00:00 heroku[router]: Error H12 (Request timeout) -> GET my-app-1111.herokuapp.com/assets/video/play.png dyno=web.1 queue= wait= service=30000ms status=503 bytes=0
2012-07-04T19:20:24+00:00 heroku[router]: Error H12 (Request timeout) -> GET my-app-1111.herokuapp.com/assets/video/pause.png dyno=web.1 queue= wait= service=30000ms status=503 bytes=0
当我将网络测功机的数量增加到三个时,仍然存在资产超时。
使用四个 web dyno,整个过程有时会成功完成(即并非总是如此!)——无论如何,即使它总是成功,四个 dyno 仅用于创建 Campaign Monitor 时事通讯就太昂贵了。
CDN 上的资产
由于asset_sync和fog,我已将我的应用程序转换为使用CDN 资产主机(Amazon S3) ,我又回到了这个问题:使用Heroku 的Campaign Monitor。
由于我的应用程序不再提供资产(它们由 Amazon S3 提供服务),因此它基本上只负责返回 HTML。
就 Campaign Monitor 而言,当您查询他们的 API 以根据您的时事通讯创建营销活动时,他们会立即给您回电以下载您的时事通讯。这实际上意味着它们发送两个并行请求:一个用于新闻通讯的 HTML 版本,一个用于新闻通讯的 TEXT 版本。如果一个 dyno 被最初调用他们的 API 阻塞,并且所有资产都托管在 CDN 上,你会认为第二个 dyno 可以解决问题。事实上,我已经看到一秒钟的测功机处理“并行”请求(用于新闻通讯的 HTML 和 TEXT 版本)。但它是不可靠的,因为仍然存在随机超时():Error H12 (Request timeout)
2012-08-16T23:00:42+00:00 heroku[router]: Error H12 (Request timeout) -> POST my-app-1111.herokuapp.com/campaigns dyno=web.2 queue= wait= service=30000ms status=503 bytes=0
2012-08-16T23:00:42+00:00 heroku[router]: GET my-app-1111.herokuapp.com/favicon.ico dyno=web.4 queue=0 wait=0ms service=7ms status=304 bytes=0
2012-08-16T23:00:42+00:00 heroku[router]: Error H12 (Request timeout) -> GET my-app-1111.herokuapp.com/newsletters/1?cm=1 dyno=web.2 queue= wait= service=30000ms status=503 bytes=0
2012-08-16T23:00:43+00:00 app[web.2]: [error] CampaignMonitor error: The CreateSend API responded with the following error - 310: HTML Content URL Required
Heroku 的支持说这是因为他们独立地发送每个请求,期望最终接收的测功机能够处理它。这里发生的情况是,在某些情况下,发出帖子的同一个测功机是接收第二个请求的那个,但它似乎需要第二个请求的结果来完成发布请求,所以它死锁了。
解决方案
一种可能的临时解决方案是unicorn
为您的应用服务器使用两个 unicorn worker_processes
。这样即使 Heroku 派发到繁忙的测功机,第二个独角兽监听器也会响应请求。
最终,除了使用unicorn
with two之外worker_processes
,正确的解决方案是异步处理请求,通过类似的方式delayed_job
,并用于workless
根据需要启动 Heroku worker dynos,因此您只需为使用的内容付费。