程序员的简单接口压测 - 编程语言

博主:xiaoweixiaowei 2023-01-18 条评论

接口必然需要压测,但有时候往往没有专门压测人员,程序员自己动手。以实名接口为例,传入姓名、×××号上有返回一致、不一致等信息,一致信息则插入用户信息表,下次调用时先查询该表,如果有直接返回结果。

1.restful接口
使用springboot很容易搭建接口,过程略

2.造数据
2.1java批量插入数据,略
2.2存储过程造数据
2.3sql造数据

-- 建表
drop table if exists `t_identity_info`;
create table `t_identity_info` (
  `id` int(11) not null auto_increment comment '主键id',
  `real_name` varchar(20) default null comment '姓名',
  `id_card` varchar(18) not null comment '×××号',
  `create_time` varchar(19) not null comment '创建时间',
  primary key (`id`),
  key `index_id_card` (`id_card`)
) engine=innodb auto_increment=1 default charset=utf8 comment='用户信息表';

-- 存储过程
drop procedure if exists insert_t_identity_info_data;

delimiter ;;
create procedure insert_t_identity_info_data()
begin 
declare i int;
declare tempName varchar(4);
declare tempAreaCode varchar(6);
declare tempDate varchar(8);

set i = 0;
while i < 10000 do
set tempAreaCode = concat((CEILING(RAND()*1000 mod 50) + 10),(CEILING(RAND()*1000 mod 50) + 10),(CEILING(RAND()*1000 mod 50) + 10)) ; 
set tempDate = DATE_FORMAT(date_add(now(), interval - CEILING(RAND()*1000000 mod 10000) day),'%Y%m%d');
set tempName = concat(substring('赵钱孙李周吴郑王冯陈褚卫蒋沈韩',CEILING(RAND()*1000 mod 15),1),
substring('嘉懿煜城懿轩烨伟苑博伟泽熠彤鸿',CEILING(RAND()*1000 mod 15),1));

insert into t_identity_info (real_name,id_card,create_time) values 
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now()),
(tempName,concat(tempDate,CEILING(RAND()*100000) mod 9999+1000),now());
select count(1) from t_identity_info;
set i = i +1; 

end while; 
end 
;;
DELIMITER ;

-- 调用存储过程
call insert_t_identity_info_data();

-- 循环造数据,执行一次数据量*2
insert into t_identity_info(real_name,id_card,create_time) select real_name,id_card,now() from t_identity_info;

完成接口的httpclient

程序员的简单接口压测 - 编程语言

3.压测
运行spring boot
运行n个接口客户端

注意:
不要在本机压测,数据库、服务、客户端都应在服务器上,
压测至少半个小时,根据tps启动客户端个数、每个客户端的数量;
检测服务器的内存、cpu;
考虑网络瓶颈。

package com.ld.api;

import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.ld.util.LoggerUtil;

@RestController
@RequestMapping("/identity")
public class IdentityApi {

    private static final Logger logger = LoggerFactory.getLogger(LoggerUtil.class);

    @PostMapping("/check")
    public String check(@RequestBody Map<String, String> map) {
        String transNo = getTransNoByType("identityCheck");
        long beginTime = System.currentTimeMillis();
        logger.info("transNo = {} , map = {}", transNo, map);

        // 查询db
        sleepSomeTime();

        // 返回结果
        String result = null;

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("transNo", transNo);
            jsonObject.put("state", System.currentTimeMillis() % 2 + 1);
            jsonObject.put("costTime", System.currentTimeMillis() - beginTime);// 接口耗费时间
        } catch (Exception e) {
            e.printStackTrace();
        }

        result = jsonObject.toString();
        logger.info("transNo = {} , result = {}", transNo, result);
        return result;
    }

    /**
     * 通过流水号串联日志,方便定位问题
     * 
     * @param transNoType
     * @return 2019年3月27日
     */
    private String getTransNoByType(String transNoType) {
        return transNoType + "_" + DateFormatUtils.format(new Date(), "yyMMddHHmm") + "_"
                + RandomStringUtils.randomAlphabetic(4);
    }

    /**
     * 随机休眠
     * 
     * 2019年3月27日
     */
    private void sleepSomeTime() {
        try {
            Thread.sleep(System.currentTimeMillis() % 300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

package com.ld;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;

public class IdentityCheck {
    public static void main(String[] args) {
        try {

            for (int i = 0; i < 100; i++) {
                check();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void check() throws Exception {
        CloseableHttpClient httpclient = HttpClientBuilder.create().build();
        String loginUrl = "http://localhost:8080/identity/check";

        HttpPost httppost = new HttpPost(loginUrl);
        httppost.addHeader("Content-Type", "application/json;charset=UTF-8");

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("idCard", "131024199901010011");
        jsonObject.put("realName", "李四");

        StringEntity stringEntity = new StringEntity(jsonObject.toString(), "utf-8");
        httppost.setEntity(stringEntity);

        CloseableHttpResponse response = httpclient.execute(httppost);
        System.out.println("response = " + response.toString());

        HttpEntity entity = response.getEntity();
        String jsonStr = EntityUtils.toString(entity, "utf-8");
        System.out.println("jsonStr = " + jsonStr);

        httppost.releaseConnection();
    }

}

The End

发布于:2023-01-18,除非注明,否则均为 主机评测原创文章,转载请注明出处。