26

Apple プッシュ通知を定期的に 100 万ユーザーに送信するアプリがあります。そのためのセットアップは、少数の通知に対して構築およびテストされています。その規模で送信をテストする方法がないため、一括プッシュ通知の送信に問題があるかどうかを知りたいと思っています。プッシュ サーバーへの単一の接続を開き、その接続を介してすべての通知を送信する Python で記述されたスクリプトがあります。Apple は、できるだけ長く開いたままにしておくことをお勧めします。しかし、接続が終了し、再確立する必要があることも確認しました。

全体として、成功した送信が確認されず、エラーのある送信のみがフラグ付けされることは当惑させられます。プログラマーの観点からは、単に「成功した場合」という 1 つのことをチェックするのではなく、問題が発生する可能性のある多くのことを監視する必要があります。

私の質問は次のとおりです。メッセージが黙って忘却されないように注意する必要がある典型的なエラーのセットは何ですか? 接続を閉じるのは簡単です。他にもありますか?

4

2 に答える 2

12

私は、この API が非常に苛立たしいものであることに完全に同意します。また、通知ごとに応答を送信していれば、実装がはるかに簡単だったでしょう。

そうは言っても、これがAppleがあなたがすべきだと言っていることです(テクニカルノートから):

プッシュ通知のスループットとエラー チェック

APNs を使用するための上限やバッチ サイズの制限はありません。iOS 6.1 のプレス リリースによると、APNs は設立以来 4 兆回以上のプッシュ通知を送信しています。WWDC 2012 で、APNs が毎日 70 億の通知を送信していることが発表されました。

スループットが 1 秒あたり 9,000 件未満の通知である場合、サーバーは改善されたエラー処理ロジックの恩恵を受ける可能性があります。

拡張バイナリ インターフェイスを使用する場合のエラーを確認する方法は次のとおりです。書き込みが失敗するまで書き込みを続けます。ストリームの書き込み準備が整ったら、通知を再送信して続行します。ストリームが書き込みの準備ができていない場合は、ストリームが読み取り可能かどうかを確認してください。

存在する場合は、ストリームから利用可能なすべてを読み取ります。0 バイトが返された場合は、無効なコマンド バイトやその他の解析エラーなどのエラーが原因で、接続が閉じられています。6 バイトが返された場合、それはエラー応答であり、応答コードと、エラーの原因となった通知の ID を確認できます。その後、すべての通知を再度送信する必要があります。

すべてが送信されたら、エラー応答の最後のチェックを行います。

通常の遅延のため、切断された接続が APNs からサーバーに戻るまでに時間がかかる場合があります。接続が切断されたために書き込みが失敗する前に、500 を超える通知を送信することができます。約 1,700 件の通知の書き込みが、パイプがいっぱいになったという理由だけで失敗する可能性があるため、その場合は、ストリームが再び書き込み可能になったら再試行してください。

さて、ここでトレードオフが興味深いものになります。書き込みのたびにエラー応答を確認でき、すぐにエラーをキャッチできます。ただし、これにより、通知のバッチを送信するのにかかる時間が大幅に増加します。

デバイス トークンを正しく取得し、正しい環境に送信している場合、デバイス トークンはほとんどすべて有効です。したがって、失敗がめったにないと仮定して最適化することは理にかなっています。エラー応答をチェックする前に、書き込みが失敗するか、バッチが完了するのを待つと、ドロップされた通知を再度送信する時間を数えても、パフォーマンスが大幅に向上します。

これは APN に固有のものではなく、ほとんどのソケットレベルのプログラミングに適用されます。

選択した開発ツールが複数のスレッドまたはプロセス間通信をサポートしている場合、エラー応答を常に待機しているスレッドまたはプロセスを保持し、メインの送信スレッドまたはプロセスに、いつ中断して再試行する必要があるかを知らせることができます。

于 2013-05-03T16:27:20.630 に答える
7

私たちは毎日何百万もの APNS 通知を送信しているため、一人称視点で話をしたいと思いました.

残念ながら、@Eran の引用は、Apple が APNS ソケットを管理する方法について私たちが持っている最高のリソースに関するものです。ボリュームが少ない場合は問題ありませんが、Apple のドキュメント全体は、カジュアルでボリュームの少ない開発者向けに大きく偏っています。スケールすると、文書化されていない動作がたくさん表示されます。

エラー検出を非同期で行うことに関するそのドキュメントの部分は、高スループットにとって重要です。送信ごとにエラーをブロックすることを主張する場合は、スループットを維持するためにワーカーを大幅に並列化する必要があります。ただし、推奨される方法は、送信できる限り速く送信し、エラーが発生した場合はいつでも修復して再生することです。

私が例外とするその投稿の部分は次のとおりです。

デバイス トークンを正しく取得し、正しい環境に送信している場合、デバイス トークンはほとんどすべて有効です。したがって、失敗がまれであると仮定して最適化することは理にかなっています

このような巨大な「IF」でそのアドバイスを述語することは、非常に誤解を招くように思えます。ほとんどの開発者がトークンを取得せず、Apple のフィードバック サービスを 100% 「正しく」処理していないことはほぼ保証できます。たとえそうであったとしても、システムは本質的に損失が多いため、ドリフトが発生します。

0 以外のエラー #8 応答 (無効なデバイス トークン) が表示されます。これは、root 化された電話、クライアントのバグ、または意図的にトークンを偽装しているユーザーに起因すると考えられます。また、過去に多数のエラー #7 (無効なペイロード サイズ) を確認しており、開発者が弊社側で追加した不適切にエンコードされたメッセージに突き止めました。もちろん、それは私たちの責任でしたが、それが私の言いたいことです。「失敗がめったに起こらないと仮定して最適化する」ということは、学習中の開発者に送るのは間違ったメッセージです。代わりに私が言うことは:

エラーが発生すると仮定します。

頻繁に発生しないことを願っていますが、そうでない場合に備えて防御的にコーディングしてください。

エラーがほとんど発生しないと想定して最適化すると、APNS サービスがダウンし、送信するすべてのメッセージがエラー #10 を返すたびに、インフラストラクチャが危険にさらされる可能性があります。

問題は、エラーに適切に対応する方法を見つけようとするときに発生します。さまざまなエラーを適切に処理して回復する方法に関するドキュメントがあいまいまたは欠落しています。これは明らかに読者の演習として残されています。

于 2013-10-05T01:52:29.150 に答える