感悟
最近在做的项目中,需要去做核心接口的压测工作,初次在实际项目中进行接口压测,本人属实有点慌张.
在经历了几周的时间,自己的压测脚本,从最初的单线程,变成多线程,最后又通过协程的方式去实现.
接口压测,首先需要去选择一款适合自己的压测工具,jmeter,loadrunner,locust等,
这些都是一些主流的压测工具,我在这个项目中选择的是python多线程脚本去实现的,
后期将已经编写好的脚本成功迁移到locust上进行运行.
接口压测,最核心的地方是去监控接口的性能指标:TPS,RT等核心指标,并且在已知的目标下进行压测,
并且通过技术手段进行调优.本项目采用的是阿里云的arms数据监控平台,可以实时查看接口的关键性能指标
场景1:推送出库单场景
OMS系统通过对接系统(奇门)将出库单推送给双中心,双中心接收到数据以后,进行订单创建,寻源,出库通知单创建,
锁库存等业务操作
场景2:取消出库单
OMS系统取消订单,将取消订单的指令通过对接系统推送给双中心,双中心接到取消指令以后,进行取消订单操作,
通知WMS系统取消出库单据,同时双中心释放锁定库存,修改出库单通知单状态和订单状态
场景3:发货结果回传
WMS将发货结果回传给双中心,双中心拿到指令以后,创建出库结果单,更新库存数据,通知单状态和订单状态
解决思路
分析了如上三个场景以后,需要编写对应的压测脚本,在编写压测脚本之前,分析得出推送出库单的入参没有依赖
前置的业务单据数据,但是去取消订单和发货结果回传就需要依赖第一个场景的数据,所以从是否依赖前置单据
参数的角度开始分析需要编写两种不同的压测脚本
第一种:无依赖入参的脚本
第二种:有依赖入参的脚本
场景1:无依赖入参脚本编写
针对无依赖入参的这种脚本,很容易编写,此项目中该场景下,入参是xml格式的,我这里实现的方式是将入参中的参数进行模板字符串参数化,去构造xml形式的参数,在XML模板中凡是涉及到需要变动的参数全部用{变量名称}进行替换,在脚本执行前先拿到xml参数模板,接着利用replace()方进行一一替换,得到真正可以使用的XML参数
实现模板参数化的核心脚本:
第一步:读取xml内容
第二步:将XML内容中的模板化字段进行替换,得到真实的数据
第三步:拿到入参以后,进行接口调用
def read_xml(self, path):
with open(path, mode="r", encoding="utf-8") as f:
data = f.read()
# print(str(data.encode("utf-8"),encoding="utf-8"))
return str(data.encode("utf-8"), encoding="utf-8")
def create_data(self, start_num):
"""
deliveryOrderCode: 通过for循环,自动生成,数值类型
warehouseCode:渠道仓编码
createTime: 创建时间
shopNick: 店铺名称
senderInfo.name: 发货人名称
senderInfo.mobile:发货人手机号
senderInfo.province:发货人省份
senderInfo.city:发货人城市
senderInfo.area:发货人地区
senderInfo.detailAddress:发货人详细地址
receiverInfo.name:收件人名称
receiverInfo.mobile:收件人手机号
receiverInfo.province:收件人省份
receiverInfo.city:收件人城市
receiverInfo.area:收件人地区
receiverInfo.detailAddress:收件人详细地址
extendProps.oid:聚水潭oid
extendProps.shopId:店铺id
ownerCode:货主编码
itemCode:商品编码
itemName:商品名称
:return:
"""
index = "".join(random.sample(
'zFyVxwTvutRsrqpPonFmlkjLihSgfedcHbaABCvDEFGHIJKLMNOPQRSJHSADSWQWDewteyeydhgASsadavvfsvdDHSAJHQasdsadxzsdWEW2d323dfwefew4msadacodvuwivbyw8133289TUVWXYZ',
5))
warehouse_code_list = [
{
"warehouse_code": "CW20211125000001",
"shop_id": "10188246",
"shop_name": "小兔子乖乖",
"name": "九阳人",
"mobile": "18888888888",
"province": "浙江省",
"city": "杭州市",
"area": "滨江区",
"detailAddress": "沈阳创意工业园区"
}
]
# 多商品场景:从多个店铺发货
# warehouse_info = random.choice(warehouse_code_list)
# 热点商品场景:从单个店铺发货
warehouse_info = warehouse_code_list[1]
warehouse_code = warehouse_info["warehouse_code"]
shop_nick = warehouse_info["shop_name"]
sender_name = warehouse_info["name"]
sender_mobile = warehouse_info["mobile"]
sender_province = warehouse_info["province"]
sender_city = warehouse_info["city"]
sender_area = warehouse_info["area"]
sender_detail_address = warehouse_info["detailAddress"]
create_time = time.strftime('%Y-%m-%d %H:%M:%S')
receiver_name = "胡浩浩" + index
receiver_phone = "188" + str(random.randint(10000000, 99999999))
receiver_address_list = [{'province': '北京', 'city': '北京市', 'area': '昌平区'},
{'province': '台湾', 'city': '高雄市', 'area': '大社区'}]
address_info = random.choice(receiver_address_list)
receiver_province = address_info["province"]
receiver_city = address_info["city"]
receiver_area = address_info["area"]
receiver_address_detail = "晨光路110号"
shop_id = warehouse_info["shop_id"]
item_list = ['1AW01001009''13601600031', '12A01000044']
# 多商品场景:从商品列表选取任意一个商品
# item_code = random.choice(item_list)
# 热点商品场景:从商品列表选取单个商品
item_code = item_list[0]
owner_code = ["HZ210928014", "HZ210928003"][random.randint(0, 0)]
delivery_order_code = str(start_num) + index
so_id = str(start_num) + index
# 模板参数化核心脚本replace()
params_data = self.xml_data.replace("{deliveryOrderCode}", delivery_order_code).replace("{warehouseCode}",warehouse_code).replace(
"{createTime}", create_time).replace("{shopNick}", shop_nick).replace("{buyerNick}", sender_name).replace(
"{senderInfo.name}", sender_name).replace("{senderInfo.mobile}", sender_mobile).replace(
"{senderInfo.province}", sender_province).replace("{senderInfo.city}", sender_city).replace(
"{senderInfo.area}", sender_area).replace("{senderInfo.detailAddress}", sender_detail_address).replace(
"{receiverInfo.name}", receiver_name).replace("{receiverInfo.mobile}", receiver_phone).replace(
"{receiverInfo.province}", receiver_province).replace("{receiverInfo.city}", receiver_city).replace(
"{receiverInfo.area}", receiver_area).replace("{receiverInfo.detailAddress}",receiver_address_detail).replace("{extendProps.oid}",so_id).replace(
"{extendProps.shopId}", shop_id).replace("{itemCode}", item_code).replace("{ownerCode}", owner_code)
# print("数据创建中: %s" % str(time.strftime("%Y-%m-%d %H:%M:%S")))
# print(params_data)
return params_data
XML参数模板
<?xml version="1.0" encoding="utf-8"?>
<request>
<deliveryOrder>
<deliveryOrderCode>{deliveryOrderCode}</deliveryOrderCode>
<deliveryOrderId>D2110070000013</deliveryOrderId>
<warehouseCode>{warehouseCode}</warehouseCode>
<orderType>JYCK</orderType>
<status>DELIVERED</status>
<outBizCode>{expressCode}</outBizCode>
<confirmType>0</confirmType>
<orderConfirmTime>{orderConfirmTime}</orderConfirmTime>
<operatorCode>huhaohao</operatorCode>
<operatorName>胡浩浩</operatorName>
<operateTime>{operateTime}</operateTime>
<ownerCode>c12654</ownerCode>
</deliveryOrder>
<packages>
<package>
<logisticsCode>YTO</logisticsCode>
<logisticsName>圆通</logisticsName>
<expressCode>{expressCode}</expressCode>
<items>
<item>
<itemCode>{itemCode}</itemCode>
<itemId>10101011055</itemId>
<quantity>1</quantity>
</item>
</items>
</package>
</packages>
<orderLines>
<orderLine>
<itemCode>{itemCode}</itemCode>
<itemId>ST2109290002889</itemId>
<inventoryType>ZP</inventoryType>
<ownerCode>c12654</ownerCode>
<itemName>豆浆机、DJ03X-D110XL(BROWN)(00)、棕色、I类结构、220V、50Hz、500W、300mL</itemName>
<planQty>1</planQty>
<actualQty>1</actualQty>
</orderLine>
</orderLines>
</request>
参数化以后的xml文件:
<?xml version="1.0" encoding="utf-8"?>
<request>
<deliveryOrder>
<deliveryOrderCode>PDON916116367825895424</deliveryOrderCode>
<deliveryOrderId>D2110070000013</deliveryOrderId>
<warehouseCode>PW20210929000003</warehouseCode>
<orderType>JYCK</orderType>
<status>DELIVERED</status>
<outBizCode>YT122040ZSDcW8J</outBizCode>
<confirmType>0</confirmType>
<orderConfirmTime>2021-12-09 12:20:40</orderConfirmTime>
<operatorCode>huhaohao</operatorCode>
<operatorName>胡浩浩</operatorName>
<operateTime>2021-12-09 12:20:40</operateTime>
<ownerCode>c12654</ownerCode>
</deliveryOrder>
<packages>
<package>
<logisticsCode>YTO</logisticsCode>
<logisticsName>圆通</logisticsName>
<expressCode>YT122040ZSDcW8J</expressCode>
<items>
<item>
<itemCode>1AN01001002</itemCode>
<itemId>10101011055</itemId>
<quantity>1</quantity>
</item>
</items>
</package>
</packages>
<orderLines>
<orderLine>
<itemCode>1AN01001002</itemCode>
<itemId>ST2109290002889</itemId>
<inventoryType>ZP</inventoryType>
<ownerCode>c12654</ownerCode>
<itemName>豆浆机、DJ03X-D110XL(BROWN)(00)、棕色、I类结构、220V、50Hz、500W、300mL</itemName>
<planQty>1</planQty>
<actualQty>1</actualQty>
</orderLine>
</orderLines>
</request>
locust脚本实现脚本
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# author: 胡浩浩
# datetime: 2021/11/30 18:00
# ide: PyCharm
import random
from locust import HttpUser, task, between
import random
import time
class TestMemberCenter(HttpUser):
wait_time = between(0,0)
host = "http://api.test.c18c67cec6d8649f8a02fe333f6ad76228f9.cn-hang33zhou.alicontainer.com"
def on_start(self):
self.headers = {
'Content-Type': 'application/xml'
}
self.base_url = "http://api.test.c18c67cec336d8649f8a02fef6ad76228f9.cn-hangzhou.alicontainer.com"
self.xml_path = "../locust_press/tui_dan_data.xml"
self.xml_data = self.read_xml(self.xml_path)
def send_method(self, data):
if data['method'] == "get":
response = self.client.get(url=data['url'], headers=self.headers,
data=data['data'], name=data['name'])
# print(response.json())
elif data['method'] == "post":
response = self.client.post(url=data['url'], headers=self.headers,
data=data['data'], name=data['name'])
print(data["name"])
print(response.text)
elif data['method'] == "put":
response = self.client.put(url=data['url'], headers=self.headers,
json=data['data'], name=data['name'])
# print(data["name"])
# print(response.json())
elif data['method'] == "patch":
response = self.client.patch(url=data['url'], headers=self.headers,
json=data['data'], name=data['name'])
# print(data["name"])
# print(response.json())
elif data['method'] == "delete":
response = self.client.delete(url=data['url'], headers=self.headers,
data=data['data'], name=data['name'])
# print(data["name"])
# print(response.json())
else:
print("%s:请求参数不合法" % data['method'])
def read_xml(self, path):
with open(path, mode="r", encoding="utf-8") as f:
data = f.read()
# print(str(data.encode("utf-8"),encoding="utf-8"))
return str(data.encode("utf-8"), encoding="utf-8")
def create_data(self, start_num):
"""
deliveryOrderCode: 通过for循环,自动生成,数值类型
warehouseCode:渠道仓编码
createTime: 创建时间
shopNick: 店铺名称
senderInfo.name: 发货人名称
senderInfo.mobile:发货人手机号
senderInfo.province:发货人省份
senderInfo.city:发货人城市
senderInfo.area:发货人地区
senderInfo.detailAddress:发货人详细地址
receiverInfo.name:收件人名称
receiverInfo.mobile:收件人手机号
receiverInfo.province:收件人省份
receiverInfo.city:收件人城市
receiverInfo.area:收件人地区
receiverInfo.detailAddress:收件人详细地址
extendProps.oid:聚水潭oid
extendProps.shopId:店铺id
ownerCode:货主编码
itemCode:商品编码
itemName:商品名称
:return:
"""
index = "".join(random.sample(
'zFyVxwTvutRsrqpPonFmlkjLihSgfedcHbaABCvDEFGHIJKLMNOPQRSJHSADSWQWDewteyeydhgASsadavvfsvdDHSAJHQasdsadxzsdWEW2d323dfwefew4msadacodvuwivbyw8133289TUVWXYZ',
5))
warehouse_code_list = [
{
"warehouse_code": "CW20211125000001",
"shop_id": "10188246",
"shop_name": "小兔子乖乖",
"name": "九阳人",
"mobile": "18888888888",
"province": "浙江省",
"city": "杭州市",
"area": "滨江区",
"detailAddress": "九阳创意工业园区"
},
{
"warehouse_code": "CW20211105000001",
"shop_id": "12234716",
"shop_name": "小兔子乖乖1",
"name": "九阳人",
"mobile": "18888888888",
"province": "浙江省",
"city": "杭州市",
"area": "滨江区",
"detailAddress": "九阳创意工业园区"
},
{
"warehouse_code": "CW20211105000002",
"shop_id": "12234718",
"shop_name": "小兔子乖乖2",
"name": "九阳人",
"mobile": "18888888888",
"province": "浙江省",
"city": "杭州市",
"area": "滨江区",
"detailAddress": "九阳创意工业园区"
},
{
"warehouse_code": "CW20211105000003",
"shop_id": "12234719",
"shop_name": "小兔子乖乖3",
"name": "九阳人",
"mobile": "18888888888",
"province": "浙江省",
"city": "杭州市",
"area": "滨江区",
"detailAddress": "九阳创意工业园区"
},
{
"warehouse_code": "CW20211105000004",
"shop_id": "12234721",
"shop_name": "小兔子乖乖4",
"name": "九阳人",
"mobile": "18888888888",
"province": "浙江省",
"city": "杭州市",
"area": "滨江区",
"detailAddress": "九阳创意工业园区"
},
{
"warehouse_code": "CW20211105000005",
"shop_id": "12234723",
"shop_name": "小兔子乖乖5",
"name": "九阳人",
"mobile": "18888888888",
"province": "浙江省",
"city": "杭州市",
"area": "滨江区",
"detailAddress": "九阳创意工业园区"
}
]
# 多商品场景:从多个店铺发货
# warehouse_info = random.choice(warehouse_code_list)
# 热点商品场景:从单个店铺发货
warehouse_info = warehouse_code_list[1]
warehouse_code = warehouse_info["warehouse_code"]
shop_nick = warehouse_info["shop_name"]
sender_name = warehouse_info["name"]
sender_mobile = warehouse_info["mobile"]
sender_province = warehouse_info["province"]
sender_city = warehouse_info["city"]
sender_area = warehouse_info["area"]
sender_detail_address = warehouse_info["detailAddress"]
create_time = time.strftime('%Y-%m-%d %H:%M:%S')
receiver_name = "胡浩浩" + index
receiver_phone = "188" + str(random.randint(10000000, 99999999))
receiver_address_list = [{'province': '北京', 'city': '北京市', 'area': '昌平区'},
{'province': '上海', 'city': '上海市', 'area': '闵行区'},
{'province': '天津', 'city': '天津市', 'area': '大港区'},
{'province': '河北省', 'city': '保定市', 'area': '安国区'},
{'province': '河北省', 'city': '秦皇岛市', 'area': '北戴河区'},
{'province': '河北省', 'city': '石家庄市', 'area': '桥东区'},
{'province': '内蒙古自治区', 'city': '呼伦贝尔市', 'area': '海拉尔区'},
{'province': '内蒙古自治区', 'city': '包头市', 'area': '东河区'},
{'province': '辽宁省', 'city': '鞍山市', 'area': '立山区区'},
{'province': '山西省', 'city': '大同市', 'area': '南郊区'},
{'province': '山西省', 'city': '太原市', 'area': '晋源区'},
{'province': '山西省', 'city': '长治市', 'area': '高新区'},
{'province': '辽宁省', 'city': '大连市', 'area': '金州区'},
{'province': '辽宁省', 'city': '沈阳市', 'area': '大东区'},
{'province': '辽宁省', 'city': '铁岭市', 'area': '开原市'},
{'province': '吉林省', 'city': '四平市', 'area': '铁东区'},
{'province': '吉林省', 'city': '松原市', 'area': '宁江区'},
{'province': '黑龙江省', 'city': '哈尔滨市', 'area': '道里区'},
{'province': '黑龙江省', 'city': '大兴安岭市', 'area': '呼玛县'},
{'province': '上海', 'city': '上海市', 'area': '虹口区'},
{'province': '江苏省', 'city': '常州市', 'area': '金坛区'},
{'province': '江苏省', 'city': '南京市', 'area': '白下区'},
{'province': '江苏省', 'city': '无锡市', 'area': '北塘区'},
{'province': '江苏省', 'city': '苏州市', 'area': '常熟市'},
{'province': '江苏省', 'city': '连云港市', 'area': '东海县'},
{'province': '浙江省', 'city': '杭州市', 'area': '滨江区'},
{'province': '浙江省', 'city': '杭州市', 'area': '西湖区'},
{'province': '浙江省', 'city': '金华市', 'area': '兰溪市'},
{'province': '安徽省', 'city': '安庆市', 'area': '怀宁县'},
{'province': '安徽省', 'city': '蚌埠市', 'area': '蚌山区'},
{'province': '安徽省', 'city': '亳州市', 'area': '蒙城县'},
{'province': '安徽省', 'city': '合肥市', 'area': '包河区'},
{'province': '福建省', 'city': '福州市', 'area': '仓山区'},
{'province': '福建省', 'city': '龙岩市', 'area': '连城县'},
{'province': '福建省', 'city': '厦门市', 'area': '湖里区'},
{'province': '江西省', 'city': '福州市', 'area': '崇仁县'},
{'province': '江西省', 'city': '南昌市', 'area': '安义县'},
{'province': '江西省', 'city': '宜春市', 'area': '丰城市'},
{'province': '山东省', 'city': '济南市', 'area': '钢城区'},
{'province': '山东省', 'city': '菏泽市', 'area': '曹县'},
{'province': '山东省', 'city': '青岛市', 'area': '城阳区'},
{'province': '山东省', 'city': '日照市', 'area': '东港区'},
{'province': '河南省', 'city': '洛阳市', 'area': '高新区'},
{'province': '河南省', 'city': '郑州市', 'area': '高新区'},
{'province': '湖北省', 'city': '黄冈市', 'area': '红安县'},
{'province': '湖北省', 'city': '襄阳市', 'area': '樊城区'},
{'province': '湖北省', 'city': '宜昌市', 'area': '当阳市'},
{'province': '湖南省', 'city': '张家界市', 'area': '永定区'},
{'province': '湖南省', 'city': '长沙市', 'area': '开福区'},
{'province': '湖南省', 'city': '株洲市', 'area': '茶陵县'},
{'province': '广东省', 'city': '惠州市', 'area': '惠城区'},
{'province': '广东省', 'city': '珠海市', 'area': '斗门区'},
{'province': '广东省', 'city': '中山市', 'area': '板芙镇'},
{'province': '广东省', 'city': '深圳市', 'area': '宝安区'},
{'province': '广东省', 'city': '佛山市', 'area': '高明区'},
{'province': '广西壮族自治区', 'city': '北海市', 'area': '海城区'},
{'province': '广西壮族自治区', 'city': '桂林市', 'area': '灵山县'},
{'province': '海南省', 'city': '东方市', 'area': '八所镇'},
{'province': '海南省', 'city': '海口市', 'area': '龙华区'},
{'province': '海南省', 'city': '琼海市', 'area': '大路镇'},
{'province': '海南省', 'city': '三亚市', 'area': '吉阳区'},
{'province': '重庆', 'city': '重庆市', 'area': '巴南区'},
{'province': '重庆', 'city': '重庆市', 'area': '大足区'},
{'province': '四川省', 'city': '巴中市', 'area': '巴州区'},
{'province': '四川省', 'city': '绵阳市', 'area': '安州区'},
{'province': '四川省', 'city': '南充市', 'area': '高坪区'},
{'province': '四川省', 'city': '攀枝花市', 'area': '仁和区'},
{'province': '贵州省', 'city': '贵阳市', 'area': '白云区'},
{'province': '贵州省', 'city': '六盘水市', 'area': '盘县'},
{'province': '贵州省', 'city': '遵义市', 'area': '赤水市'},
{'province': '贵州省', 'city': '安顺市', 'area': '平坝区'},
{'province': '云南省', 'city': '昆明市', 'area': '安宁市'},
{'province': '云南省', 'city': '丽江市', 'area': '古城区'},
{'province': '云南省', 'city': '曲靖市', 'area': '富源县'},
{'province': '陕西省', 'city': '汉中市', 'area': '汉台区'},
{'province': '甘肃省', 'city': '酒泉市', 'area': '瓜州县'},
{'province': '青海省', 'city': '海东市', 'area': '乐都区'},
{'province': '宁夏回族自治区', 'city': '固原市', 'area': '彭阳县'},
{'province': '新疆维吾尔自治区', 'city': '北屯市', 'area': '北屯镇'},
{'province': '台湾', 'city': '高雄市', 'area': '大社区'}]
address_info = random.choice(receiver_address_list)
receiver_province = address_info["province"]
receiver_city = address_info["city"]
receiver_area = address_info["area"]
receiver_address_detail = "晨光路110号"
shop_id = warehouse_info["shop_id"]
item_list = ['1AW01001009', '1AW01001004', '38809002046', '13001001187', '12A01000046', '33809001001',
'61A05014001', '11A05000053', '1AN01001003', '18301002002', '12A01000089', '13001001188',
'62A00009003', '1AN01001002', '15601001037', '33809001002', '62A00998000', '18301002001',
'13601613075', '12A01000069', '1BW02002001', '61A05998024', '13601613055', '20201012001',
'12A01000045', '15701001013', '62A01009045', '13601613074', '1AP01001001', '11A05000055',
'62A01009098', '1BW02001001', '18301064001', '12A01000083', '11A05000111', '18701001001',
'13601113020', '15701001014', '38809002049', '1AW01001010', '15701001007', '1AC01001012',
'15701001003', '13601613011', '62A01009078', '13601214106', '13601600060', '11A05000073',
'1AW01001001', '2AU01001001', '15401006001', '62A03009010', '1AW01001003', '13601613076',
'13601613077', '11A05000112', '1AU01001001', '61A05003020', '13601113033', '18301002004',
'13601600059', '12A01000094', '13601571014', '18501001001', '13601214101', '18301002003',
'3AZ09002001', '1AU01001002', '13601600061', '61A04004006', '1AN01002001', '13601613119',
'13601600033', '15601001052', '11A82000010', '11401006077', '28307259007', '12A01000043',
'13601600031', '12A01000044']
# 多商品场景:从商品列表选取任意一个商品
# item_code = random.choice(item_list)
# 热点商品场景:从商品列表选取单个商品
item_code = item_list[0]
owner_code = ["HZ210928014", "HZ210928003"][random.randint(0, 0)]
delivery_order_code = str(start_num) + index
so_id = str(start_num) + index
params_data = self.xml_data.replace("{deliveryOrderCode}", delivery_order_code).replace("{warehouseCode}",warehouse_code).replace(
"{createTime}", create_time).replace("{shopNick}", shop_nick).replace("{buyerNick}", sender_name).replace(
"{senderInfo.name}", sender_name).replace("{senderInfo.mobile}", sender_mobile).replace(
"{senderInfo.province}", sender_province).replace("{senderInfo.city}", sender_city).replace(
"{senderInfo.area}", sender_area).replace("{senderInfo.detailAddress}", sender_detail_address).replace(
"{receiverInfo.name}", receiver_name).replace("{receiverInfo.mobile}", receiver_phone).replace(
"{receiverInfo.province}", receiver_province).replace("{receiverInfo.city}", receiver_city).replace(
"{receiverInfo.area}", receiver_area).replace("{receiverInfo.detailAddress}",receiver_address_detail).replace("{extendProps.oid}",so_id).replace(
"{extendProps.shopId}", shop_id).replace("{itemCode}", item_code).replace("{ownerCode}", owner_code)
# print("数据创建中: %s" % str(time.strftime("%Y-%m-%d %H:%M:%S")))
# print(params_data)
return params_data
@task()
def test_1(self):
start_num = random.randint(10000000000, 99999999999)
params_data=self.create_data(start_num)
data = {
"method": "post",
"url": "/api/qimen/JST/router/service?app_key=23060081&customerId=C1632333365246709&format=xml&method=deliveryorder.create&sign=E2CD56EB3C64F2333333323479A5F77346A47B&sign_method=md5&v=2.0\"",
"name": "聚水潭推单",
"data": params_data.encode("utf-8")
}
# print(data)
self.send_method(data)
if __name__ == '__main__':
# 终端启动允许:locust -f test_closing_center.py
pass
终端输入:locust -f 文件名.py,打开浏览器输入:http://localhost:8089/
会打开web运行监控平台,如下是启动页面截图,在启动页面可以设置最大用户数,和每秒并发数
检测页面
阿里云监测
python脚本实现脚本(多线程)
# #!/usr/bin/env python
# # -*- coding: utf-8 -*-
# # author: 胡浩浩
# # datetime: 2021/11/18 19:06
# # ide: PyCharm
import requests
import xlrd
import threading
import time
"""
模拟圆通发货
第一步:构造一个接口的入参
数据获取流程:
分页查询出库通知单列表页,拿到出库通知单号
通过出库通知单号,获取对应的详情信息
将获取的数据存错到Excel文件中
数据读取流程:
读取Excel文件中的数据
第二步:构造10和接口的入参
构造多个py文件,调用接口
每个py文件从一个data.xlsx文件中获取数据,多个运行文件需要从多个data文件中分批获取,达到并发的效果
第三步:批量执行一个接口
主程序修改线程数为1,运行单个文件
第四步:批量执行10个接口
主程序修改线程数为10,运行多个文件
"""
def send_request(params_data):
headers = {
'Content-Type': 'application/xml'
}
data = params_data.encode("utf-8")
url = "http://api.test.c18c67cec6d8649f8a022222fef6ad76228f9.cn-hangzhou.alicontainer.com/api/qimen/YTO/router/service?app_key=23212222523&customerId=YT594&format=xml&method=deliveryorder.confirm&sign=7D7C31D3967D955FA35090E4222D6F980A7&sign_method=md5&v=2.0"
res = requests.post(url=url, headers=headers, data=data)
print(res.status_code)
print(res.text)
def read_excel(current_row, data_path):
workbook = xlrd.open_workbook(data_path)
sheet = workbook.sheets()[0]
current_row_data=(sheet.cell_value(current_row, 0))
return current_row_data
def get_total_rows(data_path):
workbook = xlrd.open_workbook(data_path)
sheet = workbook.sheets()[0]
total_rows = sheet.nrows
return total_rows
def run(num):
"""
第一步:读取xml模板的数据
第二步:分页读取Excel中的数据,放到参数列表中
第三步:动态拼装入参参数
第四步:分页循环调用发货接口
"""
num = str(num)
excel_path = "../data_YT_100/data%s.xlsx" % (num)
print(excel_path)
xml_path = "fa_huo_data.xml"
total_rows = get_total_rows(excel_path)
# xml_template = read_xml(xml_path)
for i in range(total_rows):
print("第%s个程序执行第%d次" % (num, (i + 1)))
current_row_data = read_excel(i, excel_path)
print(current_row_data)
# params_data = join_data(xml_template, current_row_data)
send_request(current_row_data)
def thread_run(thread_num):
"""
:param thread_num:10,20,50
:return:
"""
for i in range(thread_num):
th = threading.Thread(target=run, args=((i + 1),))
th.start()
if __name__ == '__main__':
print("开始发货时间: %s" % str(time.strftime("%Y-%m-%d %H:%M:%S")))
"""
thread_num:10
thread_num:20
thread_num:50
"""
thread_run(1)
print("结束发货时间: %s" % str(time.strftime("%Y-%m-%d %H:%M:%S")))
优化方案
优化点1:单据表查询的时候需要加索引
优化点2:常用数据(省市区,店铺信息,仓库信息,商品信息等)不通过直接查库的方式去操作,而是把常用数据放到redis里面,或者是本地缓存里面