【Python】Thrift rpc 接口测试 python

本文详细介绍了如何在Windows上使用Python和Thrift库进行RPC接口测试,包括Thrift命令行工具的使用、服务器和客户端设计,以及通信过程中的关键点。文章还探讨了Thrift的基本语法,如数据类型、协议和服务器类型选择,并解决可能出现的编程问题。此外,还强调了客户端和服务器通信一致性的重要性。
摘要由CSDN通过智能技术生成

author: jwesh
date: 2022.08.06

Thrift rpc 接口测试 python

在 window 上使用 python + thrift 库来进行接口测试,通过官网下载的 thrift-0.11.0.exe 进行接口文件生成

一 .基础的命令

默认的命令

thrift-0.11.0.exe -r  --gen py xAnti.thrift

修改输入路径的命令(设置gen-*包的输出目录(默认值是当前目录),他会生成gen-py目录)

thrift-0.11.0.exe -o ../src/xAnti/ --gen py xAnti.thrift

修改输入路径的命令(为生成的文件设置输出位置(不会创建gen-*文件夹))

thrift-0.11.0.exe -out ../src/xAnti/ --gen py xAnti.thrift

使用docker: thrift 构建代码(兼容mac、liunx、window;避免thrift版本冲突)

cd /Users/apple/jayzhen/qadev/qadev-test-script/thrift_test
docker run --rm --privileged -v "$PWD:/data" thrift:0.11.0 thrift -out /data/src/kgc/lib --gen py /data/thrift-files/kgc_bridge.thrift

如果有`include`其他文件(注意生成后的文件引入问题)

docker run --rm --privileged -v "$PWD:/data" thrift:0.11.0 thrift -r -out /data/src/jayzhen --gen py /data/thrift-files/doc/jayzhen_storage.thrift

如果想在指定目录下生成指定的目录层级

  1. 自己先创建好对应的目录树,然后在-out加上路径
  2. 在thrift文件中的namespace后面定义包空间
  3. 注意thrift文件名一定要放到最后面,不然会报错Unrecognized option

二. thrift的sever设计

在服务器端启动 thrift 框架的部分代码比较简单,不过在写这些启动代码之前需要先确定服务器采
用哪种工作模式对外提供服务,Thrift 对外提供几种工作模式,例如:TSimpleServer
TNonblockingServerTThreadPoolServerTThreadedSelectorServer 等模式,每种服务模
式的通信方式不一样,因此在服务启动时使用了那种服务模式,客户端程序也需要采用对应的通信
方式。

另外,Thrift支持多种通信协议格式:TCompactProtocolTBinaryProtocol
TJSONProtocol 等,因此,在使用 Thrift 框架时,客户端程序与服务器端程序所使用的通信
协议一定要一致,否则便无法正常通信。

三. thrift 的 client 设计

有上面生成的 gen-py 文件夹,所有接口对应的服务代码都在里面了,我们需要设计客户端代码来进行调用

1.创建一个传输层对象(TTransport),具体采用的传输方式是 TFramedTransport ,要与服务器端保持一致,这里的THRIFT_HOST, THRIFT_PORT分别是 Thrift 服务器程序的主机地址和监听端口号,这里的 2000socket 的通信超时时间;即:

  • java
m_transport =new TFramedTransport(newTSocket(THRIFT_HOST,THRIFT_PORT, 2000));
  • python
tsocket = TSocket.TSocket(host, port)
transport = TTransport.TFramedTransport(tsocket)

2.创建一个通信协议对象(TProtocol),具体采用的通信协议是二进制协议,这里要与服务器端保持一致,即:

  • java
TProtocol protocol =new TBinaryProtocol(m_transport);
  • python
protocol = TBinaryProtocol.TBinaryProtocol(transport)

3.创建一个Thrift客户端对象(TestThriftService.Client),Thrift的客户端类 TestThriftService.Client 已经在文件TestThriftService.java 中,由Thrift编译器自动为我们生成,即:

  • java
TestThriftService.ClienttestClient =new TestThriftService.Client(protocol);
  • python
client = Client(protocol)

4.打开 socket,建立与服务器直接的 socket连 接,即:

  • java
m_transport.open();
  • python
transport.open()

5.通过客户端对象调用服务器服务函数getStr,即:

  • java
String res = testClient.getStr("test1","test2");
System.out.println("res = " +res);
  • python
dta = UserNumReq()
dta.Uid = 115775
dta.NumTypes = [1, 2]
result = client.get_user_num(dta)

6.使用完成关闭socket,即:

  • java
m_transport.close();
  • python
transport.close()

这里有以下几点需要说明:

  1. 在同步方式使用客户端和服务器的时候,socket 是被一个函数调用独占的,不能多个调用同时使用一个 socket,
    例如通过 m_transport.open() 打开一个socket,此时创建多个线程同时进行函数调用,这时就会报错,
    因为 socket 在被一个调用占着的时候不能再使用;

  2. 可以分时多次使用同一个socket进行多次函数调用,即通过 m_transport.open() 打开一个socket之后,
    你可以发起一个调用,在这个次调用完成之后,再继续调用其他函数而不需要再次通过 m_transport.open()
    打开socket;

三. 通信之间的关注点

1.Thrift 的服务器端和客户端使用的通信方式要一样,否则便无法进行正常通信;

Thrift的服务器端的种模式所使用的通信方式并不一样,因此,服务器端使用哪种通信
方式,客户端程序也要使用这种方式,否则就无法进行正常通信了。例如,上面的代码2.3
中,服务器端使用的工作模式为 TNonblockingServer,在该工作模式下需要采用的传输
方式为 TFramedTransport,也就是在通信过程中会将 tcp 的字节流封装成一个个的帧,
此时就需要客户端程序也这么做,否则便会通信失败。

2.在服务器端或者客户端直接使用 IDL 生成的接口文件时,可能会遇到下面两个问题:

[1] Cannotreduce the visibility of the inherited method fromProcessFunction<I,TestThriftService.getStr_args>

[2] The typeTestThriftService.Processor<I>.getStr<I> must implement theinherited abstract methodProcessFunction<I,TestThriftService.getStr_args>.isOneway()

问题产生的原因:

问题[1] 是继承类的访问权限缩小所造成的;
问题[2] 是因为存在抽象函数isOneWay所致;

解决办法:

问题[1]的访问权限由protected修改为public;
问题[2]的解决办法是为抽象函数添加一个空的函数体即可。

3.还有就是thrift的版本和生成代码的有必要加上版本号

四. thrift 基本语法

1. 编写IDL文件时需要注意的问题

函数的参数要用数字依序标好,序号从1开始,形式为:“序号:参数名”;

每个函数的最后要加上“,”,最后一个函数不加;

在IDL中可以使用/*……*/添加注释

2. IDL支持的数据类型

IDL大小写敏感,它共支持以下几种基本的数据类型

string, 字符串类型,注意是全部小写形式;例如:string aString

i16, 16位整形类型,例如:i16 aI16Val;

i32,32位整形类型,对应C/C++/java中的int类型;例如:      I32  aIntVal

i64,64位整形,对应C/C++/java中的long类型;例如:I64 aLongVal

byte,8位的字符类型,对应C/C++中的char,java中的byte类型;例如:byte aByteVal

bool, 布尔类型,对应C/C++中的bool,java中的boolean类型; 例如:bool aBoolVal

double,双精度浮点类型,对应C/C++/java中的double类型;例如:double aDoubleVal

void,空类型,对应C/C++/java中的void类型;该类型主要用作函数的返回值,例如:void testVoid(),

除上述基本类型外,ID还支持以下类型:

map,map类型,例如,定义一个map对象:map<i32, i32> newmap;

set,集合类型,例如,定义set<i32>对象:set<i32> aSet;

list,链表类型,例如,定义一个list<i32>对象:list<i32> aList;

3. 在Thrift文件中自定义数据类型

在IDL中支持两种自定义类型:枚举类型和结构体类型,具体如下:

enum, 枚举类型,例如,定义一个枚举类型:

enum Numberz
{
  ONE = 1,
  TWO,
  THREE,
  FIVE = 5,
  SIX,
  EIGHT = 8
}

注意: 枚举类型里没有序号

struct,自定义结构体类型,在IDL中可以自己定义结构体,对应C中的struct,c++中的struct和class,java中的class。例如:

struct TestV1 {
       1: i32 begin_in_both,
       2: string old_string,
       3: i32 end_in_both
}

注意: 在 struct 定义结构体时需要对每个结构体成员用序号标识:“序号: ”。

4. 定义类型别名

Thrift的IDL支持C/C++中类似typedef的功能,例如:

typedef i32  Integer 

就可以为i32类型重新起个名字Integer。

5. 支持的数据类型、数据传输格式、数据传输方式和服务器类型

数据类型

Base Types:基本类型
Struct:结构体类型
Container:容器类型,即List、Set、Map
Exception:异常类型
Service: 定义对象的接口,和一系列方法

数据传输格式
Thrift支持二进制和文本2类协议,二进制协议比本文协议更优。但是文本协议在某些情况下更有用(如debug)。

TBinaryProtocol –二进制编码格式
TCompactProtocol –使用Variable-Length Quantity (VLQ) 编码对数据进行压缩,高效
TJSONProtocol – JSON编码格式
TSimpleJSONProtocol –只提供JSON只写协议, 生成的文件很容易通过脚本语言解析。
TDebugProtocol – 使用易懂的可读的文本格式,以便于debug
TDenseProtocoal – 和TCompactProtocol相似,但在发送时省略了meta信息,在接收端重新加上。还在实验中,java实现还不可用。

数据传输方式

TSocket -阻塞式socketI/O
TFramedTransport – 以frame为单位进行传输,要求服务器为非阻塞式方式。
TFileTransport – 以文件形式进行传输,不支持java方式,但实现起来也很简单。
TMemoryTransport – 使用内存I/O,如同Java中的ByteArrayOutputStream实现。
TZlibTransport – 使用zlib进行压缩, 与其他传输方式联合使用。当前无java实现。

服务器类型

TSimpleServer –单线程服务模型,使用标准的阻塞式I/O,常用于测试
TThreadPoolServer – 多线程服务模型,使用标准的阻塞式I/O。
TNonblockingServer – 多线程服务模型,使用非阻塞式I/O(需使用TFramedTransport数据传输方式)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值