【接口压测】

感悟

最近在做的项目中,需要去做核心接口的压测工作,初次在实际项目中进行接口压测,本人属实有点慌张.
在经历了几周的时间,自己的压测脚本,从最初的单线程,变成多线程,最后又通过协程的方式去实现.
接口压测,首先需要去选择一款适合自己的压测工具,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里面,或者是本地缓存里面

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值