NetCore IIS Redis JMeter 登录压力测试

近期,由于某项目验收需要,需要登录接口同时满足至少400个账号同时并发登录,于是开始编写测试代码,以满足项目业务需要。首先,安装jdk,由于本机已安装jdk8:

如果你机器上没有安装jdk,请百度自行安装一下,因为JMeter由java编写,JMeter安装:

Windows 安装 jmeter-CSDN博客

安装redis,可以百度也可以参考之前发布的文章:部署.net6 到 Windows server 2008 r2 IIS_csdn_aspnet的博客-CSDN博客 

编写测试webapi登录接口代码:

1.写入redis测试账号:

 /// <summary>
 /// 添加或移除测试账号
 /// </summary>
 /// <param name="isDel">0:添加账号 1:移除账号</param>
 /// <returns></returns>
 [HttpPost]
 public async Task<ActionResult> AddYhzhRedis(int isDel = 0)
 {
     string sKey = "YH";

     if (isDel == 1)
     {
         for (int i = 0; i < 500; i++)
         {
             int nId = i + 1;
             string sYhm = "admin_" + nId;
             await _cache.RemoveAsync(sKey + ":" + sYhm);
         }

         return Ok(new
         {
             code = 200,
             success = true,
             msg = "移除测试账号成功!"
         });
     }

     Yhzh yhzh = null;

     for (int i = 0; i < 500; i++)
     {
         int nId = i + 1;
         yhzh = new Yhzh();
         yhzh.id = nId;
         yhzh.yhm = "admin_" + nId;
         yhzh.mm = MD5Helper.MD5Encrypt32(nId + "123456");

         await _cache.SetAsync(sKey + ":" + yhzh.yhm, yhzh, TimeSpan.FromHours(24));

         var vId = await SqlSugarHelper.Db.Insertable(yhzh).ExecuteReturnBigIdentityAsync();
     }

     return Ok(new
     {
         code = 200,
         success = true,
         msg = "添加测试账号成功!"
     });

 }

 代码中_cache 为注入的redis缓存接口,可自行编写或使用第三方包,MD5Helper.MD5Encrypt32 你可以在网络上找一个md5加密帮助类即可。

2.登录接口实现:

/// <summary>
/// 登录
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost]
public async Task<ActionResult> Login([FromBody] LoginVM model)
{
    string sKey = "YH:";

    if (await _cache.GetAsync(sKey + model.yhm))
    {
        var vCacheModel = await _cache.GetAsync<Yhzh>(sKey + model.yhm);

        if (null == vCacheModel)
        {
            return Ok(new
            {
                code = 400,
                success = false,
                msg = "登录失败,用户不存在!"
            });
        }

        string sAfferentPwd = MD5Helper.MD5Encrypt32(vCacheModel.id + model.mm);

        if (sAfferentPwd != vCacheModel.mm)
        {
            return Ok(new
            {
                code = 400,
                success = false,
                msg = "登录失败,用户或密码不正确!"
            });
        }

        //TODO:生成新的token 存储缓存信息

        return Ok(new
        {
            code = 200,
            success = true,
            msg = "登录成功!"
        });

    }

    var vUserModel = await SqlSugarHelper.Db.Queryable<Yhzh, Yhxx, Dwxx>((zh, yh, dw) =>
                    new JoinQueryInfos(JoinType.Left, zh.yhid == yh.id && yh.sczt == 0, JoinType.Left, zh.dwbh == dw.dwbh && dw.sczt == 0))
         .Where((zh, yh, dw) => zh.yhm == model.yhm || yh.lxdh == model.yhm || yh.jh == model.yhm)
         .Where((zh, yh, dw) => zh.sczt == 0)
         .Select((zh, yh, dw) => new YhzhxxVM
         {
             id = zh.id,
             yhid = zh.yhid,
             xm = yh.xm,
             yhm = zh.yhm,
             mm = zh.mm,
             lxdh = yh.lxdh,
             //yhtx = zh.yhtx,
             yhtx = yh.yhtx,
             dwbh = zh.dwbh,
             dwmc = dw.dwmc,
             qhbm = dw.qhbm,
             sfxtzh = zh.sfxtzh,
             zhzt = zh.zhzt,
             sfkdldp = zh.sfkdldp
         })
         .FirstAsync();

    if (null == vUserModel)
    {
        return Ok(new
        {
            code = 400,
            success = false,
            msg = "登录失败,用户名不存在!"
        });
    }

    string sUserPwd = MD5Helper.MD5Encrypt32(vUserModel.id + model.mm);

    if (sUserPwd != vUserModel.mm)
    {
        return Ok(new
        {
            code = 400,
            success = false,
            msg = "登录失败,用户名或密码错误!"
        });
    }

    Dictionary<string, string> dicUserInfo = new Dictionary<string, string>
        {
            { "zhid",vUserModel.id.ToString()},
            { "userid",vUserModel.yhid.ToString()},
            { "dwbh",vUserModel.dwbh??""},
            { "dwmc",vUserModel.dwmc??""},
            { "qhbm",vUserModel.qhbm??""},
            { "username",model.yhm??""},
            { "xm",vUserModel.xm??""},
            { "nickname",vUserModel.nc??""},
            { "lxdh",vUserModel.lxdh??""},
            { "yhtx",vUserModel.yhtx??""},
            { "jsmc",""},
            { "jsid",""},
            { "sfxtzh",vUserModel.sfxtzh==null?"0":vUserModel.sfxtzh.ToString()},
            { "logintime",DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")},
            { "tokenExpire",DateTime.Now.AddSeconds(AppSettings.CustomToken.KeyTimeEffectiveTime).ToString("yyyy-MM-dd HH:mm:ss")},
        };

    var vUserInfo = JsonHelper.ToJson(dicUserInfo);

    string sToken = Guid.NewGuid().ToString("N");

    await _cache.SetAsync(sToken, vUserInfo, TimeSpan.FromMinutes(10));

    return Ok(new
    {
        code = 200,
        success = true,
        msg = "登录成功!"
    });

}

代码中 SqlSugarHelper使用的第三方 SqlSugar包实现,此类代码如下:

/// <summary>
///  不能是泛型类
/// </summary>
public class SqlSugarHelper
{
    //多库情况下使用说明:
    //如果是固定多库可以传 new SqlSugarScope(List<ConnectionConfig>,db=>{}) 文档:多租户
    //如果是不固定多库 可以看文档Saas分库


    //用单例模式
    public static SqlSugarScope Db = new SqlSugarScope(new ConnectionConfig()
    {
        ConnectionString = "server=127.0.0.1;Database=db;Port=3306;Uid=mysqladmin;Pwd=20231024;Persist Security Info=True;SslMode=None;charset=utf8mb4;",//连接符字串
        DbType = DbType.MySql,//数据库类型
        IsAutoCloseConnection = true //不设成true要手动close
    },

  db =>
  {
      //(A)全局生效配置点,一般AOP和程序启动的配置扔这里面 ,所有上下文生效
      //调试SQL事件,可以删掉
      db.Aop.OnLogExecuting = (sql, pars) =>
          {
              Console.WriteLine(sql);//输出sql,查看执行sql 性能无影响


              //5.0.8.2 获取无参数化 SQL  对性能有影响,特别大的SQL参数多的,调试使用
              //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars)
          };

      //多个配置就写下面
      //db.Ado.IsDisableMasterSlaveSeparation=true;

      //注意多租户 有几个设置几个
      //db.GetConnection(i).Aop

      var vIsConnection = db.Ado.IsValidConnection();  //如果时间长,可以在连接字符串配置 连接超时时间

      Console.WriteLine("vIsConnection:"+ vIsConnection);
  });
}

打开swagger开始写入账号数据:

redis写入成功:

数据库写入成功:

启动JMeter,进入JMeter的bin目录,右键使用管理员身份运行jmeter.bat文件即可:

启动成功如下图:

修改名称,你可以使用默认名称,本测试修改为登录并发测试,在左侧登录并发测试节点右键添加线程组,如下图:

在左侧登录并发测试节点右键分别添加HTTP信息头管理器,HTTP请求默认值,CSV Data Set Config,如下图:

HTTP信息头管理,没有你可以不添加,点击添加后双击名称列单元格即可输入:

HTTP请求默认值,本次测试只填写红框内参数,IP和端口换成你自己的即可,其余默认:

CSV Data Set Config,如下图:

以上截图中 变量名称 后续会用到,csv文件内容其实就是上面代码中创建的账号信息,使用sql在数据库执行拼接登录名:

SELECT  yhm FROM jc_yhzh1;

在查询结果中全选、右键- 复制为- 制表符分隔值(数据),粘贴到txt中,将txt扩展名修改为csv即可。 

修改完成后,打开csv文件如下:

在左侧线程组节点右键添加HTTP请求,如下图:

配置信息如下:

请求报文中,${name}为变量,上面选择csv设置的,要一致。

在登录并发测试节点,右键添加查看结果树和聚合报告,添加即可不需要配置:

添加完成后,在线程组右键-启动:

启动后开始执行,绿色的三角变为灰色: 

点击查看结果树:

两个截图请求明显登录账号不一样,说明一次600请求是正常的,返回结果如下:

点击聚合报告,异常0.00%,符合预期结果:

至此测试任务完成,将业务过程搬到正式环境代码,改写相关业务接口。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/105001.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第6周 .NET

好嘛&#xff01;本来以为上周SQL Server环境配置等已经够恶心了&#xff0c;没想到这周又得去搞所谓的Microsoft Visual Studio 2005了。 首先非常离谱的是&#xff0c;这个Microsoft Visual Studio 2005如果就是指Visual Studio 2005&#xff0c;那么已经是8年前的老的不行的…

SpringCloud复习:(2)@LoadBalanced注解的工作原理

LoadBalanced注解标记了一个RestTemplate或WebClient bean使用LoadBalancerClient来进行负载均衡。 LoadBalancerAutoConfiguration类给带注解的RestTemplate添加了拦截器&#xff1a;LoadBalancerInterceptor. 具体流程如下&#xff1a; 首先定义一个LoadBalancerInterceptor…

大语言模型(LLM)综述(三):大语言模型预训练的进展

A Survey of Large Language Models 前言4. PRE-TRAINING4.1数据收集4.1.1 数据源4.1.2 数据预处理4.1.3 预训练数据对LLM的影响 4.2 模型架构4.2.1 典型架构4.2.2 详细配置4.2.3 预训练任务4.2.4 解码策略4.2.5 总结和讨论 4.3 模型训练4.3.1 优化设置4.3.2 可扩展的训练技术 …

SpringMVC Day 03 : 处理静态资源

前言 欢迎来到第三天的 SpringMVC 学习系列&#xff01;在前两天的教程中&#xff0c;我们已经学习了如何搭建 SpringMVC 环境、创建控制器和处理请求等基础知识。今天&#xff0c;我们将继续探索 SpringMVC 的功能&#xff0c;并学习如何处理静态资源。 在现代 Web 应用程序…

Apifox创建团队 项目 接口 邀请成员步骤演示

我们打开Apifox 找到 个人空间 然后 点击新建团队 然后这里 我们输入名字 点击确定 我们的团队就出来了 然后 我们点击新建项目 然后肯定是 http 项目名称输入一下 然后 语言 我们中国肯定是中文的 然后点击确定 建好之后 我们就会进入自己的项目啦 然后 我们可以新建个接…

【机器学习合集】人脸表情分类任务Pytorch实现TensorBoardX的使用 ->(个人学习记录笔记)

人脸表情分类任务 注意&#xff1a;整个项目来自阿里云天池&#xff0c;下面是开发人员的联系方式&#xff0c;本人仅作为学习记录&#xff01;&#xff01;&#xff01;该文章原因&#xff0c;学习该项目&#xff0c;完善注释内容&#xff0c;针对新版本的Pytorch进行部分代码…

R与Python结合,在安装tensorflow时遇到了报错--尚未解决

在服务器上安装tensorflow时&#xff0c;遇到了一个报错信息&#xff1a; 在网上找到一个类似的错误&#xff08;TensorFlow_error&#xff09;,见下图&#xff0c;但是博主没有给出解决办法。

解决javascript报错:SyntaxError: Invalid Unicode escape sequence

在处理cookie时报这个错&#xff1a; 网上搜了一圈都说是反斜杠问题&#xff0c;要把\替换成/ 但是试了网上的replace替换&#xff1a; replace(/\\/g, /) 结果没有用&#xff01;&#xff01;&#xff01; 然后我干脆直接做了一个最简单字符串赋值&#xff0c;再打印出来。…

macOS鼠标管理操作增强BetterMouse简体中文

BetterMouse是一款专为Mac用户设计的鼠标增强工具&#xff0c;旨在帮助用户更好地掌握和管理鼠标操作。它提供了全局鼠标手势、高度可定制的鼠标设置选项以及一些有用的鼠标增强功能&#xff0c;如鼠标放大镜、鼠标轨迹和应用程序切换功能。这些功能可以大大提高用户的工作效率…

单例模式及其使用场景

单例模式&#xff08;Singleton&#xff09;&#xff1a;指在一个系统中某个类只存在一个实例&#xff0c;类中自行实例化&#xff0c;实例向该系统提供统一的访问接口。 单例模式有两种表现形式&#xff0c;饿汉式&#xff1a;类加载时&#xff0c;就进行实例化&#xff1b;懒…

23款奔驰E300L升级几何多光束大灯 车辆自检等功能

奔驰几何多光束大灯核心特点就是通过内部的84颗可独立控制的LED光源&#xff0c;行车远光灯会甄别对向驶来的车辆或者行人&#xff0c;并且动态的跟随目标&#xff0c;之后阴影话该区域&#xff0c;避免晃到车辆和行人。 奔驰升级几何多光束 LED 大灯&#xff08;MULTIBEAM LED…

nu1l-死亡ping命令攻略

book-nu1l docker 虚拟化技术 把传统的虚拟机堪称容器 依赖镜像启动容器&#xff0c;镜像可以理解为模板克隆的虚拟机&#xff0c;删除容器&#xff0c;对镜像没有影响 镜像在云端 本地要使用某个镜像&#xff0c;根据地址&#xff0c;直接从云端拉取 基本命令 # 查看系统…

【unity3D】Rect Transform组件

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的Rect Transform组件 Rect Transform组件 基础知识详细介绍补充 基础知识 Rect Transform是Unity中的一个UI组件&#xff0c;用于…

适用于物联网的UI设计工具都有哪些?

随着科学技术的飞速发展&#xff0c;“万物相连的互联网”时代逐渐成为现实。如今&#xff0c;物联网已经不是什么新词了。事实上&#xff0c;早在各种屏幕设备诞生之前&#xff0c;人们就与物理世界交织在一起&#xff0c;产生了无数的互动。如何将人们多年积累的互动经验与物…

BurpSuite安装

下载 BurpSuite 下载 Java17 下载后确定版本 java -version获取启动器 密钥生成器 破解 将下载的 BurpSuite、启动器、密钥生成器&#xff0c;放入同一个目录 打开 CMD 进入该目录 启动密钥生成器 java -jar burp-keygen-scz.jar开启新的CMD&#xff0c;进入该目录 启动…

理解什么是接口测试?怎样做接口测试?

一 什么是接口&#xff1f; 接口测试主要用于外部系统与系统之间以及内部各个子系统之间的交互点&#xff0c;定义特定的交互点&#xff0c;然后通过这些交互点来&#xff0c;通过一些特殊的规则也就是协议&#xff0c;来进行数据之间的交互。接口测试主要用于外部系统与系统之…

微信小程序学习(02)

页面导航 - 声明式导航 1. 导航到 tabBar 页面 tabBar 页面指的是被配置为 tabBar 的页面。 在使用<navigator> 组件跳转到指定的 tabBar 页面时&#xff0c;需要指定 url 属性和 open-type 属性&#xff0c;其中&#xff1a; ⚫ url 表示要跳转的页面的地址&#xff0…

TX Text Control.NET For WPF 32.0 Crack

TX Text Control 支持VISUAL STUDIO 2022、.NET 5 和 .NET 6 支持 .NET WPF 应用程序的文档处理 将文档编辑、创建和 PDF 生成添加到您的 WPF 应用程序中。 视窗用户界面 功能齐全的文档编辑器 TX Text Control 是一款完全可编程的丰富编辑控件&#xff0c;它在专为 Visual Stu…

TensorFlow2从磁盘读取图片数据集的示例(tf.keras.utils.image_dataset_from_directory)

import os import warnings warnings.filterwarnings("ignore") import tensorflow as tf from tensorflow.keras.optimizers import Adam from tensorflow.keras.applications.resnet import ResNet50#数据所在文件夹 base_dir ./data/cats_and_dogs train_dir os…

ES 数据迁移最佳实践

ES 数据迁移最佳实践与讲解 数据迁移是 Elasticsearch 运维管理和业务需求中常见的操作之一。以下是不同数据迁移方法的最佳实践和讲解&#xff1a; 一、数据迁移需求梳理 二、数据迁移方法梳理 三、各方案对比 方案 优点 缺点&#xff08;限制&#xff09; 适用场景 是否有…