web-dev-qa-db-ja.com

オンラインサービスの可用性を確認するためのパターン

これが完全に話題になっているかどうかはわかりませんが、そうするよう努めます。

オンラインサービス(API)と、アプリのすべてのアクションにそれを使用するAndroidアプリケーションがあります。現在のところ、ローカルには何も保存されていないので、APIがオンラインであることに依存する必要があり、そうでない場合は(何らかの理由で)ユーザーに警告します。

可用性を確認するための推奨される方法は何でしょうか。私がこれを行ったのはこれが初めてなので、私は自分の研究を試みて、3つの潜在的な解決策を考え出しました。

1.アクションの可用性を確認する

ユーザーがアクションを実行したら、APIのステータスを確認します。現在私はこれをやっています(Java):

_public class ServiceAvailability implements Runnable {

    private volatile boolean available;

    @Override
    public void run() {

        available = false;

        try {
            HttpURLConnection connection =
                    (HttpURLConnection) new URL("http://myservice.com").openConnection();
            connection.setConnectTimeout(3000);
            connection.setReadTimeout(1000);
            connection.setRequestMethod("HEAD");

            int responseCode = connection.getResponseCode();

            if (200 <= responseCode && responseCode <= 399) {
                available = true;
            }
        } catch (IOException exception) {
            exception.printStackTrace();
        }
    }

    public boolean isAvailable() {

        return available;
    }
_

正常に動作します。 HTTP HEADリクエストをサイトに送信して、応答が適切かどうかを確認してください。ユーザーがアクション(検索の実行、誰かのプロファイルのクリックなど)を実行するたびに、isAvailable()メソッドを呼び出し、_available = false_が発生した場合にエラーメッセージを表示します。

これの利点は、サービスが停止した場合、ユーザーはすぐにそのことを認識し、サービスが再びオンラインになるまでアプリを使用できないことを警告されることです。

現時点ではこれのデメリットは考えられません...

2.間隔を空けて確認する

他の解決策(実際には実装していません)は、バックグラウンドでスレッドを実行し、HTTP HEADサービスをX秒/分ごとに実行し、それに応じてステータスを更新します。その時点でisAvailable()を呼び出すと、HEADリクエストの結果によってブールセットが返されます。

これの利点は、サービスがオンラインではないときに(期間中)ビジュアルを表示できるため、ユーザーにリクエストが処理されないことを事前に通知できることです。

私が目にする欠点は、HEADリクエストが使用する帯域幅の量が非常に少ない一方で、データが非常に少ない3Gユーザーまたは接続が遅いユーザーは、HEADの送信に問題がある可能性があることです。タイムリーに応答を受け取ります。

3. 2つを組み合わせる

私が目にする最後のアプローチは組み合わせです。バックグラウンドのスレッドがX秒ごとに可用性をチェックし、APIを使用するアクションメソッドも追加のHEADリクエストを通じて可用性をチェックします。

ここで私が見る利点は、サービスが期間中いつオフラインになるかをユーザーが(視覚的に)認識し、APIのステータスがX秒間変化した場合にフォールバックが発生することです。 APIは最後にチェックされました。

私が見ることができることから、Facebook Messengerアプリ(少なくともiOS)はこれを実装しています。アプリを開くと、「接続を試みます」(ビジュアルが上に表示されます)。接続が切断されると、明るい赤のビジュアルで通知されます。 (サービスに)接続していないときにアクションを実行しようとすると、エラーが発生します。

質問

これらの3つの方法のうち、望ましい方法は1つだけですか、それとも私が言及していない別の方法がありますか?さらに、これには実際の設計パターンがありますか(たとえば、スレッド上のシングルトン)、私が実装したものよりも好ましいものはありますか?

編集:私自身、アプリのユーザーとして、私は実際に試してみる前に何かを行うことができないことを示すかなり視覚的な感じを感じます試行して失敗するよりも優れています。さらに、これを実装して、APIの「アップ」または「ダウン」ステータスだけではないことを判別したいと考えています。たとえば、APIが更新のためにメンテナンス中である場合、_503_を受け取り、サービスがメンテナンスモードであり、間もなくオンラインになり、パニックにならないことをユーザーに視覚的に通知したいと考えています。

長期的には何人のユーザーがアプリを使用するか正確にはわからないので、APIの停止やメンテナンスが発生した場合に備えて、事前に準備をしています。私はFacebookのような何百万ものユーザーをサポートできる大規模なインフラストラクチャを持っていないので、APIが100%のアップタイムはありません。言うまでもなく、私が唯一の開発者であり、寝ている間にサービスがダウンする可能性があります!

6
Chris Cirefice

失敗アクションの可用性をチェックします。通常どおり呼び出しを発行し、エラーが発生した場合は、Service Availability関数を呼び出して確認します。

サービスが稼働していると想定し、エラーが発生した場合は、追加の呼び出しを発行して可用性を確認します。

6
Jon Raynor

時間tでのhttp-pingが応答を受け取ったからといって、時間t 'での要求が完了するという大きな不確実性がまだあります。

将来の実際の可用性のプロキシ指標として不十分であるため、回避できる場合はサーバーにpingしないことをお勧めします。要求が行われ、応答が受信されない場合は、指数バックオフ間隔で再試行してください。

2
msw

それはたまたまそのサービスがあなたのリソースであり、何らかの理由でそれが利用できないかもしれないということです。クライアントアプリケーションがデータベースと直接通信する場合はどうしますか。クエリを実行する前に、データベースの可用性を確認しますか?わたしは・・・しないだろう。

サービスが利用できないのは例外的な状況だと思います。私は自分のサービスがいつでも利用できることを期待します。それができない場合は、例外が発生してクライアントコールが失敗して例外がスローされるのを待ちます。

例外をどのように処理するかは別の話です。サービスの呼び出しを再試行したり、例外のタイプを調べて、それがタイムアウトであり、サービスURIを単純に解決できないかどうかを確認したりできます。

あなたが考えなければならないのは、サービスの可用性をチェックすることによってあなたのプログラムにどんな価値を加えるかです。わかりました、あなたはサービスが利用できないことをユーザーに伝えます、しかしユーザーはおそらく気にしておらず、もし彼らがおそらくサービスが何であるか知らないかもしれないのでおそらくもっと苛立たしいでしょう。細部にまで気を取られないでください。何かがおかしくなり、サルの軍隊がそれに取り組んでいることを伝えます。

1
CodeART