为什么即使我提供了 URL,广告系列监视器仍以错误"310: HTML Content URL Required"响应?



我正在使用 CreateSend API gem,在我的本地开发环境中,我能够成功创建草稿活动。

生产(暂存)中,在 Heroku 上,完全相同的代码返回错误:

310: HTML Content URL Required

我肯定会传递 HTML 内容 URL 以及所有其他必需的参数来Campaign.create(我已经通过记录变量直观地验证了这一事实)。下面是 API 调用:

cm_campaign_id = CreateSend::Campaign.create client_id, subject, name, from_name, from_email, reply_to, html_url, text_url, list_ids, segment_ids

此外,在本地开发中,API 调用在不到 3 秒的时间内返回,而在 Heroku 上,它会超时 30 秒并返回该错误。

为什么这会发生在 Heroku 上?

由于他们的 API 要求在第一个正在进行的请求中间对您的应用进行第二次请求,因此我建议您将逻辑移至工作进程:

  1. 对创建广告系列的应用的请求不会与广告系列监视器通信,而只是在表格中创建作业,并重定向到检查该作业状态的页面
  2. 一个工人测功机看到工作并开始处理它,发布到活动监视器 API...因为这不是网络测功机,所以等待不是问题
  3. 然后,CM API 将请求时事通讯页面并回复工人测功机。
  4. 然后,工作人员测功机可以更新作业的状态
  5. 一直以来,您在第一步中重定向到的页面可以继续刷新自身,轮询作业的状态,并在注意到作业已完成后显示最后一页。

简短的回答:看看@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

看到GET my-app-1111.herokuapp.com/newsletters/1?cm=1上的Request timeout错误让我想起,Campaign Monitor 会立即回调我的应用程序以获取所有时事通讯资产。

当我将网络测功机的数量增加到两个时,有时错误会变为312: Text Content URL Required并且它会在GET my-app-1111.herokuapp.com/newsletters/1.txt超时;其他时候(仍然有两个测功机)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

当我将网络测功机的数量增加到三个时,仍然存在资产超时。

使用四个网络测功机,整个过程有时会成功完成(即并非总是如此!) - 无论如何,即使它总是成功,四个测功机对于创建活动监视器新闻通讯来说也太昂贵了。


CDN 上的资产

由于asset_sync和雾,我已经将我的应用程序转换为使用 CDN 资产主机 (Amazon S3),并且我又回到了这个问题:使用 Heroku 的活动监视器。

由于我的应用程序不再提供资产(它们由 Amazon S3 提供),因此基本上它负责的只是返回 HTML。

就活动监视器而言,当您查询他们的API以根据您的时事通讯创建广告系列时,他们会立即给您回电以下载您的时事通讯。这实际上意味着它们发送两个并行请求:一个用于新闻稿的 HTML 版本,另一个用于新闻稿的 TEXT 版本。由于一个测功机被对其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的支持人员表示,这是因为他们独立地发送每个请求,期望最终接收dyno能够处理它。这里发生的事情是,在某些情况下,发出帖子的同一个dyno是接收第二个请求的dyno,但它似乎需要第二个请求的结果来完成post请求,所以它死锁了。


解决 方案

一种可能的临时解决方案是将unicorn用于应用服务器,并带有两个独角兽worker_processes。这样,即使 Heroku 调度到繁忙的测功机,第二个独角兽侦听器也会响应请求。

最终,除了使用具有两个worker_processesunicorn之外,正确的解决方案是通过类似 delayed_job 异步处理请求,并使用workless根据需要启动 Heroku worker dynos,因此您只需为使用的内容付费。

最新更新