1. 問題の背景
Web サイトは Nginx をリバース プロキシとして使用し、2 つの Tomcat が負荷分散を実行します。
ウェブサイトにはグループテキストメッセージモジュールがあり、管理者は送信内容と携帯電話番号リストを入力できます。 「送信」をクリックすると、バックグラウンドでグループテキストメッセージの操作が実行され、送信が完了すると送信結果が返されます。
私はずっと前に繰り返し送信の問題に遭遇しました。最初は管理者の異常かと思い送信ボタンを連打してしまいました。したがって、フロントエンドの送信には制限が設けられています。 [送信] をクリックすると、ボタンを無効に設定し、実行後に戻りデータを取得してから、フロント エンドからの繰り返しの送信を制限するために使用可能に設定します。
今日、同僚が突然このモジュールを再び使用し、それぞれ 2 つのテキスト メッセージ (8000 と 1600) を送信しました。フロントエンドは操作が失敗したことを通知しましたが、彼の携帯電話は重複したテキスト メッセージを受信しました。
2. 問題分析
まず、携帯電話番号リストに重複がないことを確認し、また、フロントエンドが繰り返しリクエストを開始していないことをブラウザのデバッグを通じて確認しました。
2台のサーバーのログを確認したところ、繰り返し送信が発生しており、送信時刻が同時ではないことが分かりました。
ログから、テキスト メッセージの送信にかかる時間は 10 ミリ秒であると推定できます。
ログを通じて処理タイムアウトログも確認したところ、繰り返しのリクエストが異なるマシンで処理され、処理間隔が一定しているパターンが見つかりました
Aログ
10:03:05,878 INFO TIMEOUT.info:252 - time: 75701ms, concurrent: 1, url: /push/sendmessage.10:07:24,705 INFO TIMEOUT.info:252 - time: 15148ms, concurrent: 0, url: /push/sendmessage.
Bログ
10:03:21,599 INFO TIMEOUT.info:252 - time: 76471ms, concurrent: 1, url: /push/sendmessage.10:07:39,718 INFO TIMEOUT.info:252 - time: 15113ms, concurrent: 0, url: /push/sendmessage.
上記に基づいています。情報から推測すると、リクエストの実行時間が制限を超え、フロントエンド プロンプトが失敗したためであると考えられます。重複した送信は、再試行メカニズムによって発生する必要があります。
そこで、運用保守に確認の連絡をしました。関連する応答を受け取りました:
Nginx は、タイムアウトが 15 秒に設定されていると仮定して、タイムアウトを設定でき、リクエストが処理されて返されるまでに 16 秒かかります。 Nginx は処理のためにサーバー A にルーティングします。A が 15 秒目まで実行されると、Nginx はそれを B サービスに再送信して処理されます。フロントエンドは 30 秒待って、最終的に失敗を返します。 A と B はそれぞれ対応するリクエストを受信し、内部で処理しました。
運用保守の同級生に理由を確認した後、関連する情報を基に自分で検索することができます。
nginx の再試行メカニズム
この記事では、IP 経由でサービスにアクセスし、nginx をバイパスできるソリューションについても言及しています。
また、当社のウェブサイトにはダウンロード機能がありますが、最適化前は各ダウンロードの実行時間も非常に長かったですが、タイムアウトの問題は発生しませんでした。 GET と POST の間で考えられる違いを分析しました。一般的な考え方を判断するために、次のリンクも上記に記載されています。
http://serverfault.com/questions/528653/how-can-i-stop-nginx-from-retrying-put-or-post-requests-on-upstream-server-timeo
3. 質問の概要
オンライン情報参照を通じて、Nginx はファイルのアップロード、ダウンロード、GET、および POST リクエストに対してさまざまなタイムアウト戦略を設定できます。
さらに、SMS 一括送信ビジネスの場合、実際には、ルールを通じて構成を管理し、オフライン タスクの実行を実行する別のモジュールがあります。既存の一括送信モジュールは小規模ビジネスのみを対象としています。