在实际工作中,也经常会遇到基于 tcp 协议的测试需求,而 jmeter 工具也是支持 tcp 协议的,只是平时用的最多的还是 http 而已,今天就总结整理了 jmeter 的 tcp 脚本编写时候的最核心知识点,帮助理解。
更多测试技能干货,可以关注微信公众号<大话性能>
更多好文章
jmeter 的 tcp 取样器如图所示,下面是各个字段的含义。
TCPClient classname:
缺省的org.apache.jmeter.protocol.tcp.sampler。TCPClientImpl, TCPClient只能实现基于文本格式的套接字应用的测试。
随JMeter提供的还有另外的两个实现,分别是BinaryTCPClientImpl和LengthPrefixedBinaryTCPClientImpl,用于处理二进制格式的数据,后文将对这两个做详细的介绍。
ServerName or IP: 套接字服务器应用的地址
Port Number: 套接字服务器应用的端口
Re-use connection: 如果选中,连接会一直处于打开状态,否则读取到数据之后就关闭
Close connection: 如果选中,在TCP Sampler运行完毕之后就会被关闭
SO_LINGER:该配置项用于控制在关闭连接之前是否要等待缓冲区中的数据发送完成。如果SO_LINGER选项指定了值,则在得到关闭连接的请求之后还会等待指定的秒数以完成缓冲区中数据的发送,在指定的SO_LINGER秒数完成后,关闭连接。因此,如果你把该选项设置成0,那么所有连接在收到关闭连接的时候都会立即关闭,避免产生很多处于TIME_WAIT状态的套接字。
End of line(EOL) byte value:判断行结束的byte值,如果你指定的值大于127或者小于-128,则会跳过EOL检测。比如服务器端返回的字符串都是以回车符结尾,那么我们可以将该选项设置成10。
EOL是与读数据相关的,就是设定来自于服务器数据流的一个结束标识字节。没有设置EOL将会一直读到输入流结束为止。
这里值得注意的是,这是个十进制的值(千万不要写成hex),比如你可以查询ASCII表,来确认一个表示结束字符的十进制值.
Connect Timeout:与服务器套接字应用连接超时时间(毫秒)。
Response Timeout:响应超时时间(毫秒),这个值的设置跟End of line(EOL) byte value有关系,如果End of line(EOL) byte value中的值设置不正确,会导致JMeter一直在等待无法结束,但是如果指定了Response Timeout这个值的话,在到达这个值的时候就关闭连接。
Set NoDelay:是否使用Nagle算法,是否需要使用该选项,需要跟实际的业务情况结合。
Text to Send:发送的文本,跟“CSV dataset config”一起使用能够从文件中直接读取。
Username和Password:这两个选项在TCP相关的Sampler中都未使用,请忽略这两个选项。
关于 Jmeter 的 TCP 测试,需要明确两个问题:
第一、发送给服务器的数据格式,是文本形式还是十六进制格式;
第二、一条数据的结束符是什么;
问题 1 涉及到到底用哪个 TCPClient classname 去发送数据。
问题 2 涉及发送给服务端的数据,服务端是怎么判断客户端发送结束;服务端返回给客户端的数据,客户端如何知道服务端已经发送结束。所以这就有客户端读数据的结束符号和服务端读取数据结束符号 2 个。
上面这些如果你不清楚的话,是需要你和开发去确认的。
TCP Sampler 提供了 3 个 Sampler 的实现,分别是
org.apache.jmeter.protocol.tcp.sampler.TCPClientImp,
org.apache.jmeter.protocol.tcp.sampler.BinaryTCPClientImpl 和
org.apache.jmeter.protocol.tcp.sampler.LengthPrefixedBinaryTCPClientImpl。
其中 TCPClientImpl 实现了以文本编辑器中所编辑的纯文本为内容进行发送,BinaryTCPClientImpl 则以文本编辑器中所编辑的 16 进制字符(hex)内容为基础转换为二进制的字节内容进行发送,LengthPrefixedBinaryTCPClientImpl 则会在 BinaryTCPClientImpl 基础上默认以发送内容的长度以字节前缀进行填充。
下面具体讲讲这 3 个实现类的使用方式。
例 1: TCPClientImpl
这个比较简单,只需要直接发送字符串文本即可。注意点是结束符。
你会发现测试发生了阻塞,原因是例子中的服务端代码需要根据发送数据中的 CRLF(\r 或\n)判断一行的结束。而我们制作的发送内容并不包括 CRLF 标识内容,因此,服务器阻塞在了读数据,测试客户端得不到服务器响应,同样也阻塞在了读数据,正确的配置需要添加一个 “回车”
例 2: BinaryTCPClientImpl
BinaryTCPClientImpl 的配置只需要将 “hello,this is test.” 转换为 hex 就可以实现同样的测试内容,注意尾部增加 0a(\n)作为 CRLF 标识。
所以在发送字符串内容前,需要先转换为 hex。这里利用 jmeter 的前置处理器。
把处理好的内容传送给一个变量 stringHex。
在这里,响应内容为 hex 显示,内容不明了直观,需要转换为字符串,顾可以写一个 BeanShell 断言。如下:
经过解析后,如下,可以返回人看得懂的字符串。
例 3: LengthPrefixedBinaryTCPClientImp
LengthPrefixedBinaryTCPClientImpl 会自动在前缀增加内容长度,默认是 2 个字节,其他的和 BinaryTCPClientImp 类似。
可以发现服务端在收到内容前会在前面添加内容长度。
遇到问题:
报 Response message: org.apache.jmeter.protocol.tcp.sampler.ReadException: Error reading from server, bytes read: 0
解决方法:
这个问题应该和读取数据有关系,你需要指定传输完毕的判断符;
End of line(EOL) byte value:设置为指定的值,根据实际项目情况,可能是换行,也可能是特殊字符。
更多性能测试相关学习可以关注公众号大话性能。更多好文章