Pattern per verificare la disponibilità del servizio online

5

Non sono sicuro che sia interamente in argomento, ma cercherò di renderlo tale.

Ho un servizio online (API) e un'applicazione Android che lo utilizza per tutte le azioni nell'app . Al momento attuale, nulla è archiviato localmente, quindi devo dipendere dal fatto che l'API sia online e vorrei avvisare l'utente quando non lo è (per qualsiasi motivo).

Mi chiedo quale sia il metodo preferito per verificare la disponibilità. Poiché è la prima volta che lo faccio, ho cercato di fare la mia ricerca e ho trovato tre soluzioni potenziali:

1. Verifica la disponibilità sull'azione

Quando l'utente intraprende un'azione, controlla lo stato dell'API. Attualmente sto facendo questo (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;
    }

Funziona bene. Basta inviare una richiesta HEAD HTTP al sito e vedere se la risposta è buona. Ogni volta che l'utente esegue un'azione (ad es. Esegue una ricerca, fa clic sul profilo di qualcuno, ecc.) Chiama il metodo isAvailable() e visualizza un messaggio di errore nel caso in cui available = false .

Il vantaggio è che se il servizio si interrompe, l'utente lo saprà immediatamente e verrà avvisato che non sarà in grado di utilizzare l'app fino a quando il servizio non sarà nuovamente online.

Non riesco a pensare ad alcuno svantaggio di questo al momento ...

2. Verifica la disponibilità su intervallo

L'altra soluzione (che non ho effettivamente implementato) è eseguire un thread in background e HTTP HEAD il servizio ogni X secondi / minuti e aggiornare di conseguenza lo stato; a quel punto, potrei chiamare isAvailable() che restituirebbe semplicemente il valore booleano in base al risultato della richiesta HEAD.

Il vantaggio di questo è che un visual può essere mostrato (per la durata) quando il servizio non è online, consentendo all'utente di sapere in anticipo che la sua richiesta non verrà elaborata.

Lo svantaggio che vedo è che mentre le richieste HEAD sono molto minime nella quantità di larghezza di banda che usano, gli utenti 3G con pochi dati o utenti con connessioni lente potrebbero avere problemi nell'inviare l'HEAD e ricevere la risposta in modo tempestivo.

3. Combina i due

L'ultimo approccio che vedo è una combinazione, in cui il thread in background verifica la disponibilità ogni X secondi e i metodi di azione che utilizzano l'API verificano anche la disponibilità tramite una richiesta HEAD aggiuntiva.

Il vantaggio che vedo qui è che l'utente saprà (visivamente) quando il servizio è offline per tutta la durata, oltre ad avere un fallback se lo stato dell'API dovesse cambiare durante la durata di X secondi che l'ultima API è stata controllata.

Da quello che posso vedere, l'app Facebook Messenger (almeno per iOS) implementa questo. Quando apri l'app, "tenta di connettersi" (visual up top) e se la tua connessione cade, ti farà sapere con una visuale rosso acceso. Provare ad agire quando non sei connesso (al loro servizio) ti dà anche un errore.

Domanda

C'è uno solo di questi 3 metodi che sono preferibili o un metodo diverso che non ho menzionato? Inoltre, esiste un modello di progettazione reale per questo (ad es. Singleton su un thread), uno più preferibile rispetto a quello che ho implementato?

Modifica : in qualità di utente dell'app io stesso, sento che un elemento visivo mi dice che non sarò in grado di fare qualcosa prima che effettivamente prova sia meglio che provare e fallire. Inoltre, voglio implementarlo al fine di determinare più di uno stato "up" o "down" dell'API. Ad esempio, quando l'API è in manutenzione per un aggiornamento, voglio essere in grado di ricevere un 503 e far sapere visivamente all'utente che il servizio è in modalità manutenzione, sarà online a breve, e non a farsi prendere dal panico.

Non sono esattamente sicuro di quanti utenti utilizzeranno l'app a lungo termine, quindi cercherò di prepararmi in anticipo in caso di interruzioni e manutenzione dell'API. Non ho un'infrastruttura su larga scala in grado di supportare milioni di utenti come Facebook, quindi credo che questo controllo di disponibilità sia ragionevole al fine di fornire una buona (decente?) Esperienza utente, come so per certo che l'API sarà non avere il 100% di up-time. Per non parlare del fatto che sono l'unico sviluppatore e il servizio potrebbe andare giù mentre dormo!

    
posta Chris Cirefice 26.01.2015 - 17:02
fonte

3 risposte

5

Vorrei verificare la disponibilità sull'azione Non riuscita . Invia le chiamate normalmente e se riscontri un errore, chiama la funzione di disponibilità del servizio per verificare.

Supponiamo che il servizio sia attivo, se si ottiene un errore, quindi emettere la chiamata aggiuntiva per verificare la disponibilità.

    
risposta data 26.01.2015 - 19:28
fonte
2

Solo perché un http-ping alla volta t riceve una risposta, hai ancora una grande incertezza sul fatto che una richiesta al tempo t ' verrà completata.

Suggerisco di non eseguire il ping del server se può essere evitato perché è una misera misura proxy della disponibilità effettiva in futuro. Se viene effettuata una richiesta e non viene ricevuta alcuna risposta, riprovare con un intervallo di back-off esponenziale.

    
risposta data 26.01.2015 - 21:18
fonte
1

Capita che il servizio sia la tua risorsa e per qualche motivo potrebbe non essere disponibile. Cosa faresti se l'applicazione client parla direttamente al database. Vuoi verificare la disponibilità del database prima di provare a interrogarlo? Non lo farei.

Penso che il servizio non disponibile sia una circostanza eccezionale. Mi aspetterei che il mio servizio fosse sempre disponibile e, in caso contrario, accadrebbe qualcosa di eccezionale e aspetterò che la chiamata del client fallisca e che venga lanciata un'eccezione.

Come gestirò l'eccezione è una storia diversa. Potrei provare di nuovo a chiamare il servizio, potrei esaminare il tipo di eccezione per vedere se è un timeout e l'URI di servizio semplicemente non può essere risolto.

Quello che devi pensare è quale valore aggiungi al tuo programma verificando la disponibilità del servizio. Ok, dite all'utente che il servizio non è disponibile, ma probabilmente l'utente non si preoccupa e, in ogni caso, probabilmente si sentono più frustrati perché potrebbero non sapere quale servizio sia. Non impantanarli con i dettagli, digli che qualcosa è andato storto e l'esercito di scimmie ci sta lavorando.

    
risposta data 26.01.2015 - 22:01
fonte

Leggi altre domande sui tag