0

私は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

さらに、ローカル dev では API 呼び出しは 3 秒未満で返されますが、Heroku では 30 秒間タイムアウトしてそのエラーが返されます。

Heroku でこれが発生するのはなぜですか?

4

2 に答える 2

0

彼らの API では、進行中の最初のリクエストの途中でアプリへの 2 番目のリクエストが発生する必要があるため、ロジックをワーカー プロセスに移動することをお勧めします。

  1. キャンペーンを作成するアプリへのリクエストは、Campaign Monitor と通信しません。代わりに、テーブルにジョブを作成し、そのジョブのステータスを確認するページにリダイレクトします。
  2. ワーカー dyno がジョブを確認して作業を開始し、Campaign Monitor API に投稿します。これは Web dyno ではないため、待機しても問題ありません。
  3. その後、CM API はニュースレターのページをリクエストし、ワーカー dyno に応答します。
  4. その後、ワーカー dyno はジョブのステータスを更新できます
  5. その間ずっと、最初のステップでリダイレクトしたページは、ジョブのステータスをポーリングして更新を続け、ジョブが完了したことに気付くと最終ページを表示できます。
于 2012-09-12T22:29:44.913 に答える
0

短い答え: @kch の答えを見てください

310: HTML Content URL Required1 つの Web dyno を実行しているときにエラーが発生しました。

関連するログは次のとおりです。

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=1Campaign Monitor がすぐにすべてのニュースレター アセットに対してアプリをコールバックしていたことを思い出しました。

Web dyno の数を 2 つに増やしたところ、エラーが に変わり、312: Text Content URL RequiredでタイムアウトすることがありましたGET my-app-1111.herokuapp.com/newsletters/1.txt。それ以外の場合 (まだ 2 つの dyno がある場合)、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 の数を 3 つに増やしても、まだアセットのタイムアウトが発生していました。

4 つの Web dynoを使用すると、プロセス全体が正常に完了することがありました (つまり、常にではありません!)。とにかく、常に成功したとしても、Campaign Monitor ニュースレターを作成するだけでも 4 つの dyno はコストがかかりすぎます。


CDN 上のアセット

asset_syncと fog のおかげでCDN アセット ホスト (Amazon S3) を使用するようにアプリを変換しましたが、Heroku の Campaign Monitor を使用してこの問題に戻りました。

私のアプリは資産を提供しなくなったため (Amazon S3 によって提供されます)、本質的に責任があるのは HTML を返すことだけです。

キャンペーン モニターに関しては、ニュースレターに基づいてキャンペーンを作成するために API にクエリを実行した瞬間に、ニュースレターをダウンロードするようにすぐに電話がかかってきます。これは実際には、2 つの並行した要求を送信することを意味します。1 つはニュースレターの HTML バージョン用で、もう 1 つはニュースレターのテキスト バージョン用です。API への元の呼び出しによって 1 つの dyno がブロックされ、すべてのアセットが CDN でホストされている場合、2 番目の dyno がそのトリックを行うと考えるでしょう。実際、1 秒の 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 が 2 番目の要求を受信して​​いるのですが、投稿要求を完了するには 2 番目の要求の結果が必要なようで、デッドロックします。


ソリューション

考えられる暫定的な解決策の 1 つはunicorn、アプリ サーバーに unicorn を 2 つ使用することですworker_processes。そうすれば、Heroku が忙しい dyno にディスパッチしても、2 番目のユニコーン リスナーがリクエストに応答します。

最終的には、unicorntwoworker_processesで使用することに加えて、正しい解決策は、 のような方法でリクエストを非同期的に処理し、必要に応じて Heroku ワーカー dyno をスピンアップするために使用することです。そのため、使用した分だけ支払うことになりますdelayed_jobworkless

于 2012-07-04T19:42:21.800 に答える