OkHttpClient z problemem z operatorem komórkowym

Aug 28 2020

Moje API aplikacji działa dziwnie. Oczekiwany czas odpowiedzi jednego z interfejsów API mojej aplikacji na żywo to 2 do 3 sekund, ale odpowiedź zajmuje dużo czasu!

Przypadki testowe:

  1. Działa z WIFI = Tak
  2. Współpracuje z przewoźnikiem Airtel = Tak
  3. Działa z nośnikiem Jio = Tak
  4. Działa w sieci innych krajów = Tak
  5. Działa w przeglądarce mobilnej z nośnikiem Vodafone Idea = Tak
  6. Działa z Same API z aplikacją IOS przy użyciu nośnika Vodafone Idea = Tak

Główny problem: problem z nośnikiem Vodafone Idea używającym aplikacji = bardzo wolno

Przypadek 1.

 URL url = new URL("https://example.com");
                urlConnection = (HttpsURLConnection) url.openConnection();
                urlConnection.setReadTimeout(10000);
                urlConnection.setConnectTimeout(10000);
                int code = urlConnection.getResponseCode();
                if (code !=  200) {
                    throw new IOException("Invalid response from server: " + code);
                }

                BufferedReader rd = new BufferedReader(new InputStreamReader(
                        urlConnection.getInputStream()));
                String line;
                while ((line = rd.readLine()) != null) {
                    Log.e("data", line);
                }

Wynik:

  • Pierwszy raz 40 do 50 sekund.
  • Przy każdym kolejnym połączeniu powróci w ciągu 2 do 5 sekund zgodnie z oczekiwaniami.

Przypadek 2:

OkHttpClient okHttpClient = new OkHttpClient.Builder().build();

        Request.Builder requestBuilder = new Request.Builder()
                .url("https://example.com")
                .addHeader("Content-Type", "application/json");
        Request request = requestBuilder.build();
        Log.e("APi", "REQUEST: "+request.toString());

        Call call1 = okHttpClient.newCall(request);
        call1.enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                Log.e("APi", "APi Failed");
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                Log.e("APi", "APi isSuccessful:" + response.isSuccessful());
                Log.e("APi", "Response:" + response.body().string());
            }
        });

Wynik:

  • Za każdym razem trwa od 40 do 50 sekund.

Przypadek 3:

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.SECONDS).build();
    
            Request.Builder requestBuilder = new Request.Builder()
                    .url("https://example.com")
                    .addHeader("Content-Type", "application/json");
            Request request = requestBuilder.build();
            Log.e("APi", "REQUEST: "+request.toString());
    
            Call call1 = okHttpClient.newCall(request);
            call1.enqueue(new Callback() {
                @Override
                public void onFailure(@NotNull Call call, @NotNull IOException e) {
                    Log.e("APi", "APi Failed");
                }
    
                @Override
                public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                    Log.e("APi", "APi isSuccessful:" + response.isSuccessful());
                    Log.e("APi", "Response:" + response.body().string());
                }
            });

Wynik:

  • Za każdym razem zajmuje to od 5 do 6 sekund.

Uwaga: boję się używać .connectTimeout (1, TimeUnit.SECONDS) jako 1 sekundę w aplikacji. Zaczęło to dawać więcej błędów API i również nie wygląda na poprawne rozwiązanie.

Zaktualizuj CaseStudy:

https://github.com/square/okhttp Szczegóły debugowania OkHttpClient. poniżej daje błąd 4 razy ok.
failed to connect to xxx.com/2001:4860:4802:36::15 (port XXX) from /2402:3a80:1b8f:ca21:847:21a8:5ffc:fc30 (port XXX) after 10000ms  

pakiet okhttp3.internal.connection.RealConnection, klasa. próbuję ustanowić connectSocket, ale pojawia się błąd.

-> Po dodaniu „www” www.example.com do mojej domeny. Czas odpowiedzi zmienia się z 40 sekund do około 12 sekund dla biblioteki okhttp.

Odpowiedzi

1 BertoldKolics Sep 07 2020 at 03:40

Trudno jest zobaczyć cały obraz, ponieważ nie wyjaśniasz, w jaki sposób wykonujesz kolejne połączenia. Jest całkowicie możliwe, że ponownie używasz istniejącego połączenia. Domyślnie HTTP / 1.1 utrzymuje połączenia przy życiu.

Sprawdzenie, czy użycie zwykłego tekstu HTTP w porównaniu z HTTPS ma znaczenie, może być również interesujące, ponieważ koszt konfiguracji połączenia jest wyższy w przypadku HTTPS. Twój klient może również przeprowadzić dokładniejszą weryfikację na podstawie zwróconego certyfikatu.

Jeśli zmiana nazwy hosta robi tak dużą różnicę, to zdecydowanie przyjrzałbym się, jak skonfigurowany jest program rozpoznawania nazw w systemie.

Przechwyciłbym również ruch w sieci i zobaczył, co trwa długo. tcpdump to twój przyjaciel lub zawsze możesz rozważyć użycie wireshark

Jak sugerowali inni, możesz również chcieć wyłączyć stos IPv6 na pudełku, aby wykluczyć jako źródło problemu.