java vuser 采用cmd调用python,执行zeromq请求protobuf反序列化

背景:由于第一次接触zeromq,对其了解甚少,于是度娘对其原理了解一番后,就开始了接下来实践“坑”中,首先在LR中,对于用socekt、java、c那种方式来实现,通过抓包对比,以及socekt和c语言可实现,但复杂度有点”呵呵“,而用java开发的zeromq请求脚本(见:实现过程一),实现挺简单,但是在回放脚本时,遇见了我一个”大坑“,由于开发的隐瞒,导致回放的结果总是乱码,后面通过加编码方式,始终不行,于是判断是否开发加了其他加密方式,结果如我所料,开发对返回数据采用了protobuf反序列,于是只能傻眼、蒙逼,乖乖的百度了解protobuf原理,发现大多都是转换成c++、python、java等代码来解析数据,庆幸的是,开发将python实现了解析数据方法发给我,可悲剧的是,loadrunner不支持python语言开发,于是只能决定用java来实现zeromq接收数据和数据反序列(见:实现过程二),但开发过程中,遇见的第二个”大坑“,发现proto文件生成java代码中,存在类与类之间依赖关系问题无法解决情况,此方法也只能作罢。再次选择调整思路,想到开发已经写好的python代码,能否直接调用python代码,通过百度,这种思路是可以的,但有2种方式,第一种采用jpython来调用,第二种采用cmd调用,通过操作,遇到了第三个“大坑”,发现jpython方式,很容易出现python文件中import包,无法引用python底层包,也需第一次用jpython,了解不深吧,最终也只能选择暂时放弃,最后选择采用cmd调用,却能成功调用到,但存在一些注意事项(见:实现过程三)。

实现过程一:

1、loadrunner引用的zmq.jar包,要jdk1.6的32位生成,否则引用进来会报错,原因:loadrunner11只支持32位的jdk1.6,

参考下载地址:https://download.csdn.net/download/liu_xp2003/8981985 或

https://blog.csdn.net/sinat_29673403/article/details/53195733

2、将以上下载的压缩包里,找到jzmq.dll和 libzmq.dll 文件,并把这两个问题,放到jdk1.6的安装路径下in目录下

3、LR编写java vuser代码:

import java.io.IOException;

import java.net.URLDecoder;

import java.util.StringTokenizer;import org.zeromq.ZMQ;

import org.zeromq.ZMQ.Socket;

import lrapi.lr;

public class Actions

{

ZMQ.Socket subscriber;

ZMQ.Context context;

public int init() throws Throwable {

context = ZMQ.context(1);

System.out.println("Connecting to hello world server...");

subscriber = context.socket(ZMQ.SUB);

subscriber.connect("tcp://ip:端口");

String request = "";

lr.log_message("Send data: "+request);

subscriber.subscribe("".getBytes());

while(true){

byte[] stringValue = subscriber.recv(0);

String message =new String(stringValue);

lr.log_message("recv data01:"+message);

lr.think_time(1);

}

}//end of init

public int action() throws Throwable {

return 0;

}//end of action

public int end() throws Throwable {

subscriber.close();

context.term();

return 0;

}//end of end

}

结果:无法实现zeromq返回数据protobuf反序列化

实现过程二:

对照开发python代码思路,用参考开发protobuf版本下载(参考地址:https://blog.csdn.net/junerseven7/article/details/71077875?utm_source=blogxgwz2), 将proto文件,生成java代码

建立项目,引用zmq相关包,以及protoc生成的java代码,发现这些新生成的java代码,存在很多问题(1、依赖关系存在问题;2、生成的单个java文件有些超过10几w行,总是开发工具崩溃,后续也尝试了,根据文件大小,进行生成java文件,但是文件之间依赖关系问题)

结果:无法实现zeromq返回数据protobuf反序列化

java vuser 采用cmd调用python,执行zeromq请求protobuf反序列化

实现过程三:

先安装python,并配置环境变量(如果不配置环境变量,java vuser代码中,就需要python.exe的绝对路径)

用pip安装zmq包

安装32位的jdk1.6,并配置环境变量

将将protobuf生成的python代码文件(需下载protoc来生成),放到proto文件夹中

在loadrunner中新建java vuser后,将proto文件夹和调用zmq发送和接收数据的xxx.py文件,放到脚本路径下。(如果protobuf生成的python代码文件和xxx.py文件不放在lr脚本目录,请修改java vuser代码中路径,以及xxx.py文件中sys.path.append('./proto')的proto路径位置)

xxx.py代码:

#!/usr/bin/env python

# -*- coding=utf-8 -*-

import sys

sys.path.append('./proto')

import zmq

# 导入protobuf文件

import messages_pb2

ip = "xxx.xxx.xxx.xxx"

port = 'xxxx'

if len(sys.argv) == 3:

print("请输入Ip和Port")

ip = sys.argv[1]

port = sys.argv[2]

print("ip = %s port = %s" % (ip, port))

class SubData():

def __init__(self):

self.ctx = zmq.Context()

self.subSock = self.ctx.socket(zmq.SUB)

self.subSock.connect("tcp://%s:%s" % (ip, port))

self.subSock.setsockopt(zmq.SUBSCRIBE, "")

def Sub(self):

while (True):

qdata = messages_pb2.Qdata()

qdata = messages_pb2.Data()

recvData = self.subSock.recv_multipart()

print(len(recvData))

if len(recvData) == 2:

data.ParseFromString(recvData[1])

qdata .ParseFromString(data.Message)

print(qdata)

if __name__ == '__main__':

sub_data = SubData()

sub_data.Sub()

5、java vuser代码,主要实现cmd调用xxx.py文件,通过xxx.py文件,执行zmq数据接收,以及protobuf反序列:

import java.io.IOException;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import lrapi.lr;

public class Actions

{

public int init() throws Throwable {

return 0;

}

public int action() throws Throwable {

try {

System.out.println("start");

Process pr = Runtime.getRuntime().exec("python ./xxx.py");

BufferedReader in= new BufferedReader(new InputStreamReader(pr.getInputStream()));

String line;

while ((line = in.readLine()) != null) {

System.out.println(line);

}

in.close();

pr.waitFor();

System.out.println("end");

} catch (Exception e) {

e.printStackTrace();

}

return 0;

}//end of action

public int end() throws Throwable {

return 0;

}//end of end

}

结果:可成功采用cmd方式调用python文件,并执行zeromq请求和数据protobuf反序列化

总结:

1、为了短期完成lr脚本开发,采用cmd执行python的方式,只能说暂时一个解决方式,不是最佳解决方式,还需继续摸索java直接实现zeromq请求和数据protobuf反序列化,这种最佳方式,研究为什么protoc生成java代码会出现类依赖问题。

2、接触一种新事物时,一定要了解其原理,不能一味去堆代码,导致返工。

相关推荐