Jmeter protobuf测试。无法读取Protobuf消息

时间:2015-11-17 09:18:41

标签: java jmeter protocol-buffers

我正在通过protobuf协议和使用HTTP Request Sampler测试一个项目。目标应用程序服务器也是用Java编写的。 回复中存在错误问题:

  

"无法读取Protobuf消息:协议消息包含一个   无效标签(零)。;嵌套异常是   com.google.protobuf.InvalidProtocolBufferException:协议消息   包含无效标签(零)"

案例是它不是100%的请求。当我使用 HttpClient4 时,大约有30-40%的失败请求。在我将其更改为 HttpClient3.1 后,错误率降低至 ~10%,这也不是一个好消息。

要发送protobuf消息,我在HttpSampler的Bodydata选项卡中使用变量$ {data}。在BeanShell preProcessor中我会做下一个:

(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 here enter image description here

似乎不应该发送一些奇怪的符号,但是将字节数组保存到String后约10%的请求包含它们。

2 个答案:

答案 0 :(得分:1)

我相信你的问题是你在从二进制流转换为String然后再转换时丢失了一些不可打印的字符。我想到了两种可能的解决方法:

  1. 将二进制数据写入文件而不是保存为字符串,然后使用文件名作为HTTP采样器中的变量,在文件部分的正文中

  2. 使用beanshell采样器,构建您自己的HTTPClient对象和POST请求,并在主体中使用二进制数据并自行触发,而不是使用HTTP采样器

  3. 由于所有额外的文件I / O,我不喜欢第一个选项。我不喜欢第二个选项,因为测量响应时间现在将包括你在beanshell中所做的所有请求程序集 - 所以你不得不选择一个困扰你的程序,我猜。

    如果您希望我为这两种情况编写一些代码示例,请告诉我。

    编辑:对于使用HttpClient 4的beanhell HTTP调用:

    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终点未经测试的,让我知道它是如何为你工作的。

答案 1 :(得分:-1)

在高负载下,Beanshell解释器可能是意外行为的原因,因为它有一些性能问题。尝试切换到JSR223 PreProcessor并使用groovy作为语言。 Groovy脚本引擎实现了Compilable接口,因此您可以遵循一些简单的规则来获得最佳性能,并且您的问题可能会消失。

有关groovy引擎安装说明,脚本最佳实践以及Beanshell与Groovy基准测试的详细信息,请参阅Beanshell vs JSR223 vs Java JMeter Scripting: The Performance-Off You've Been Waiting For!文章。