HttpURLConnection.getInputStream очень медленно

HttpURLConnection.getInputStream занимает очень много времени по сравнению с iPhone App, который использует те же сервисы на стороне сервера.

Для сервиса используется следующий код:

         date= new java.util.Date();             
         Log.d("time","Time Stamp before posting  "+new Timestamp(date.getTime()));

         URL ur= new URL(url);           
         HttpURLConnection conn = (HttpURLConnection) ur.openConnection();
         conn.setRequestProperty("Connection", "close");
         conn.setReadTimeout(10000);
         conn.setConnectTimeout(15000);
         conn.setRequestMethod("POST");
         conn.setDoInput(true);
         conn.setDoOutput(true);             
         OutputStream os = conn.getOutputStream();
         BufferedWriter writer = new BufferedWriter(
                 new OutputStreamWriter(os, "UTF-8"));
         writer.write(getQuery(nameValuePairs));
         writer.close();
         os.close();
         conn.connect();

         StringBuffer response=null;             
         try{           
             Log.d("time","Time Stamp bfr InputStream  "+new Timestamp(date.getTime()));    

             InputStream is = conn.getInputStream();

             date= new java.util.Date();             
             Log.d("time","Time Stamp aftr InputStream  "+new Timestamp(date.getTime()));            

             BufferedReader rd = new BufferedReader(new InputStreamReader(is));
             String line;
             response = new StringBuffer(); 
             while((line = rd.readLine()) != null) {
                 response.append(line);
                 response.append('\r');
             }
             rd.close();
             response.toString();
             result=response.toString();

         } catch (Exception e) {

        }

Чтобы проверить, где служба занимает время, я помещаю записи в журнал для печати TimeStamp.

Среднее время для процесса выглядит следующим образом:

Среднее время отправки на сервер занимает менее 2 млн. Секунд
Среднее время создания входного потока занимает почти 5 секунд

Среднее время написания ответа составляет менее 2 мил секунд.

Любая идея о том, почему входной поток занимает много времени, что делает весь сервис очень медленным?

3 ответа

Вы не измеряете то, что думаете. Ничего не записывается на сервер, пока вы не вызовете getInputStream() или getResponseCode(). Итак, вы действительно измеряете:

  • время соединения
  • время передачи
  • время обработки на сервере

когда вы думаете, что вы просто измеряете время getInputStream().

Причина в том, что HttpURLConnection автоматически устанавливает заголовок длины содержимого, буферизуя весь вывод. Вы можете избежать этого, используя режим передачи по частям. Тогда, по крайней мере, вы увидите, куда действительно идет время.

Это может быть связано с ошибкой, введенной в JDK 7. "HttpServer вызывает задержку в 1000 мс при использовании кеша поддержки активности". Увидеть:

http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8009548

В зависимости от ваших целей, предлагаемое решение - это многопоточность HttpUrlConnection. Например, если вы используете HttpServer, вы можете сделать:

server.setExecutor( Executors.newFixedThreadPool( 5 ) );

Установите для urlConnection.setConnectTimeout() меньшее время ожидания.

Документация класса для URLConnection.setConnectTimeout() гласит:

Устанавливает максимальное время ожидания в миллисекундах при подключении. Соединение с сервером не удастся с SocketTimeoutException, если время ожидания истекло до установления соединения. Значение по умолчанию 0 заставляет нас делать блокирующее соединение. Это не означает, что у нас никогда не будет тайм-аута, но это, вероятно, означает, что через несколько минут вы получите тайм-аут TCP

Предупреждение: если имя хоста разрешается на несколько IP-адресов, этот клиент будет пытаться использовать каждый в порядке RFC 3484. Если не удается подключиться к каждому из этих адресов, истечет время ожидания, прежде чем попытка подключения вызовет исключение. Имена хостов, которые поддерживают IPv6 и IPv4, всегда имеют как минимум 2 IP-адреса.

У меня изначально был мой набор urlConnection.setConnectTimeout(30000); а затем изменил его на urlConnection.setConnectTimeout(1000), Сразу же я увидел более быстрые результаты.

Надеюсь это поможет!

Другие вопросы по тегам