2015-11-17 3 views
1

Я тестирую один проект через протокол protobuf и используя HTTP Request Sampler. Целевой сервер приложений также написан на Java. Существует проблема с ошибками в Reponses:Испытание на пробойбу Jmeter. Не удалось прочитать сообщение Protobuf

«Не удалось прочитать Protobuf сообщение: Протокол сообщение содержало недопустимый тег (ноль) .; вложенной исключение составляет com.google.protobuf.InvalidProtocolBufferException: Протокол сообщение содержал недопустимый тег (ноль) «

Дело в том, что это происходит не в 100% -ном запросе. Когда я использовал HttpClient4, это было около 30-40% неудачных запросов. После того, как я изменил его на HttpClient3.1 коэффициент ошибок снизился до ~ 10%, что тоже не очень хорошо.

Чтобы отправить сообщение protobuf, я использую переменную $ {data} на вкладке Bodydata HttpSampler. И в BeanShell препроцессоре я сделать следующее:

(import and non-necessary stuff were ommited) 
MapViewport mv = MapRequest.MapViewport.newBuilder().setMaxX(mc.getX()+15).setMaxY(mc.getY()+15).setMinX(mc.getX()-15).setMinY(mc.getY()-15).build(); 

byte[] data = mv.toByteArray(); 
vars.put("data", new String(data)); 

Также я судимый для использования различных кодировок, как новой строки (данные, «UTF-8») АНСО на.

Если посмотреть на вкладке «Запрос», если «Посмотреть дерево результатов», я могу сказать, что все несоответствующие сообщения содержат «?» символ:

enter image description hereenter image description here

Кажется, некоторые странные символы не должны быть отправлены, но ~ 10% запросов после сохранения массива байтов в строку содержать их.

+0

Итак, вы конвертируете двоичный поток в String для сохранения в виде var, что может быть сопряжено с проблемами в зависимости от кодировки. Это также зависит от системы, и поведение может измениться. Более того, когда вы '$ {data}', вы отправляете строку, которая для некоторых двоичных данных вставляет '?' Первое решение, которое приходит на ум, - это записать двоичный поток в файл и использовать путь к файлу как переменная в bodydata. Но это может привести к большому объему ввода-вывода файлов. Хм .. это немного мыслитель. – RaGe

+0

В качестве альтернативы вы можете собрать свой собственный HTTP-запрос и отправить его из пробоотборника beanshell вместо использования пробоотборника HTTP. Интересно, будет ли полезен «HTTP Raw Request» из jmeter-плагинов. – RaGe

ответ

1

Я уверен, что ваша проблема в том, что вы теряете некоторые непечатаемые символы при преобразовании из двоичного потока в String, а затем обратно. Я имею в виду два возможных путей их устранения:

  1. Написать двоичные данные в файл вместо сохранения в строку, а затем использовать имя файла в качестве переменной в HTTP пробоотборник, в теле из раздела файла

  2. Используйте Beanshell пробник, и построить свой собственный объект HTTPClient и запрос POST, с бинарными данными в теле и огонь его самостоятельно, вместо того, чтобы использовать HTTP пробник

Мне не нравится первый вариант из-за все дополнительные файлы ввода/вывода. Мне не нравится второй вариант, потому что измерение времени отклика теперь включает всю сборку запросов, которую вы делаете в beanshell, - поэтому вам придется выбирать ту, которая вас беспокоит меньше, я думаю.

Сообщите мне, если вы хотите, чтобы я написал несколько примеров кода для обоих случаев.

Edit: Для BeanShell HTTP вызова с использованием HttpClient 4:

import org.apache.http.HttpEntity; 
import org.apache.http.HttpHeaders; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.ClientProtocolException; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpPost; 
import org.apache.http.entity.ByteArrayEntity; 
import org.apache.http.impl.client.DefaultHttpClient; 

byte[] data = null; 
//...assign protobuf binary buffer to data... 

HttpClient client = new DefaultHttpClient(); 
HttpPost post = new HttpPost("http://127.0.0.1"); 
HttpEntity entity = new ByteArrayEntity(data); 
post.setEntity(entity); 
post.setHeader(HttpHeaders.CONTENT_TYPE, "application/octet-stream"); 
HttpResponse response=null; 
try { 
    response = client.execute(post); 
} catch (ClientProtocolException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 

ResponseCode = response.getStatusLine().getStatusCode().toString(); 
//if some assert is true then 
Issuccess = true; 
ResponseMessage="Some Response Message"; 

Это непроверенное против Protobuf конечной точки, дайте мне знать, как это работает для вас.

+0

Возможно, базовая кодировка данных поможет? (FWIW, проблема, безусловно, связана с попыткой перетащить нетекстовые двоичные данные в 'String' - это никогда не работает.) –

+0

@RaGe вы могли бы привести некоторый пример HTTPClient в Beanshell? – v0devil

+0

обновление с помощью некоторого кода. Я протестировал его с помощью обычной конечной точки http, но не снова st конечная точка protobuf, не имеют одной удобной. – RaGe

-1

При высоких нагрузках интерпретатор Beanshell может быть причиной неожиданного поведения, так как он имеет некоторые проблемы с производительностью. Попробуйте переключиться на JSR223 PreProcessor и используйте groovy в качестве языка. Groovy скриптовый движок реализует интерфейс Compilable, поэтому, учитывая, что вы следуете нескольким простым правилам, вы можете достичь наилучшей производительности, и ваша проблема может исчезнуть.

См. Статью Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For!, содержащую инструкции по установке двигателя, рекомендации по созданию сценариев и тесты Beanshell против Groovy.

+0

Попробовал JSR223 PreProcessor, результат абсолютно такой же :( – v0devil

+0

@ v0devil Ваша проблема в том, что вы конвертируете из двоичных данных в строки и обратно и теряете некоторые непечатаемые символы в преобразовании. Стабильность Beanshell - это не проблема – RaGe

+0

@RaGe yep похоже. Я не получил ваш комментарий об использовании HTTP Raw Request - это будет так же, нет? – v0devil