Jmeter protobuf 测试.无法读取 Protobuf 消息 [英] Jmeter protobuf testing. Could not read Protobuf message

查看:59
本文介绍了Jmeter protobuf 测试.无法读取 Protobuf 消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过 protobuf 协议并使用 HTTP 请求采样器测试一个项目.目标应用程序服务器也是用 Java 编写的.响应中存在错误问题:

I am testing one project via protobuf protocol and using HTTP Request Sampler. The target appserver is also written on Java. There is a problem with errors in reponses:

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

"Could not read Protobuf message: Protocol message contained an invalid tag (zero).; nested exception is com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero)"

这种情况不是在 100% 的请求中发生.当我使用 HttpClient4 时,大约有 30-40% 的请求失败.在我将其更改为 HttpClient3.1 后,错误率下降到了 ~10%,这也不是什么好事.

The case is that it is happening not in 100% requests. When i used HttpClient4 it was about 30-40% of failed requests. After i changed it to HttpClient3.1 error rate decreased down to ~10% which is also not a good deal.

为了发送 protobuf 消息,我在 HttpSampler 的 Bodydata 选项卡中使用了变量 ${data}.在 BeanShell 预处理器中,我执行以下操作:

To send a protobuf message I am using variable ${data} in Bodydata tab of HttpSampler. And in BeanShell preProcessor i do the next:

(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));

我还尝试使用不同的编码,例如 new String(data,"UTF-8") 等等.

Also I tryed to to use different encoding like a new String(data,"UTF-8") anso on.

如果查看请求选项卡,如果查看结果树,我可以说所有失败的消息都包含?"符号:

If to look on Request tab if View Result Tree I can say that all failed messages contain "?" symbol:

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

Seems like some weird symbols should not be sent, but ~10% of requests after saving a byte array to String contain them.

推荐答案

我确信您的问题是在从二进制流转换为字符串然后再转换回来时丢失了一些不可打印的字符.我正在考虑两种可能的解决方法:

I'm fairly convinced your issue is that you're losing some non-printable characters while converting from binary stream to String and then back. I'm thinking of two possible workarounds:

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

  1. Write the binary data to a file instead of saving to string, and then use the filename as variable in the HTTP sampler, in the body from file section

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

Use a beanshell sampler, and construct your own HTTPClient object and POST request, with the binary data in body and fire it yourself instead of using the HTTP sampler

我不喜欢第一个选项,因为所有额外的文件 I/O.我不喜欢第二个选项,因为测量响应时间现在将包括您在 beanshell 中执行的所有请求程序集 - 因此您必须选择我猜对您不那么困扰的那个.

I don't like the first option because of all the additional file I/O. I do not like the second option because measuring response time will now include all the request assembly you're doing in beanshell - so you'll have to pick the one that bothers you less I guess.

如果您想让我为这两种情况编写一些代码示例,请告诉我.

Let me know if you want me to write up some code examples for either case.

对于使用 HttpClient 4 的 beanshell HTTP 调用:

For beanshell HTTP call using 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 端点进行测试,请告诉我它对您的效果如何.

This is untested against a protobuf end point, let me know how it works out for you.

这篇关于Jmeter protobuf 测试.无法读取 Protobuf 消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆