Jmeter压力测试和性能调优

1.压力测试的概念

压力测试是模拟实际应用的软硬件环境及用户使用过程的系统负荷,长时间或超大负荷地运行测试软件,来测试被测系统的性能、可靠性、稳定性等

2.压力测试的目的

1)给出系统当前的性能状况

2)定位系统性能瓶颈或潜在性能瓶颈

3.压力测试工具(Jmeter)

1)安装:Apache JMeter - Download Apache JMeter

2)使用:下载对应的压缩包,解压运行 jmeter.bat 即可(注意:JDK版本最好是8,太高可能启动不了

3)JMeter 压测示例:        

        a)大家如英文界面,可以改为中文        

       b)   右击TestPlan添加线程组

 线程组参数详解:
1)线程数:虚拟用户数。一个虚拟用户占用一个进程或线程。设置多少虚拟用户数在这里
也就是设置多少个线程数。
2) Ramp-Up Period(in seconds)准备时长:设置的虚拟用户数需要多长时间全部启动。如果
线程数为 10,准备时长为 2,那么需要 2 秒钟启动 10 个线程,也就是每秒钟启动 5 个
线程。
3)循环次数:每个线程发送请求的次数。如果线程数为 10,循环次数为 100,那么每个线
程发送 100 次请求。总请求数为 10*100=1000 。如果勾选了“永远”,那么所有线程会
一直发送请求,一到选择停止运行脚本。

4) Delay Thread creation until needed:直到需要时延迟线程的创建。
5)调度器:设置线程组启动的开始时间和结束时间(配置调度器时,需要勾选循环次数为
永远)
6) 持续时间(秒):测试持续时间,会覆盖结束时间
7) 启动延迟(秒):测试延迟启动时间,会覆盖启动时间
8)启动时间:测试启动时间,启动延迟会覆盖它。当启动时间已过,手动只需测试时当前
时间也会覆盖它。
9) 结束时间:测试结束时间,持续时间会覆盖它。

加粗的几个参数比较重要

        c)添加http请求

 请求内容

        d)添加监听器,一般使用红框中的三个就够了 

 

 查看结果数:

 汇总报告:

 聚合报告和汇总报告差不多,我就不解释了

4.性能调优

给你一段代码,结合整个项目如何优化这个代码?

//获取当前一级分类下的子分类 

 @Override
    public Map<String, List<Catelog2Vo>> getCatalogJson() {
        List<CategoryEntity> list = this.list(null);
        //查出一级菜单
        List<CategoryEntity> categorys = this.list(new QueryWrapper<CategoryEntity>().eq("cat_level", 1));
        Map<String, List<Catelog2Vo>> collect1 = categorys.stream().collect(Collectors.toMap((k) -> {
            return k.getCatId().toString();
        }, (v) -> {
            List<CategoryEntity> categoryEntity2 = getParent_cid(list, v.getCatId());
            List<Catelog2Vo> catelog2Vos = categoryEntity2.stream().map((obj) -> {
                Catelog2Vo catelog2Vo = new Catelog2Vo();
                catelog2Vo.setCatalog1Id(v.getCatId().toString());
                catelog2Vo.setId(obj.getCatId().toString());
                catelog2Vo.setName(obj.getName());
                List<CategoryEntity> catelog3Vo = getParent_cid(list, obj.getParentCid());
                List<Catelog2Vo.Catalog3Vo> collect = catelog3Vo.stream().map((vo3) -> {
                    Catelog2Vo.Catalog3Vo catelo3Vo = new Catelog2Vo.Catalog3Vo();
                    catelo3Vo.setName(vo3.getName());
                    catelo3Vo.setId(vo3.getCatId().toString());
                    catelo3Vo.setCatalog2Id(obj.getCatId().toString());
                    return catelo3Vo;
                }).collect(Collectors.toList());
                catelog2Vo.setCatalog3List(collect);
                return catelog2Vo;
            }).collect(Collectors.toList());
            return catelog2Vos;
        }));
        return collect1;
    }

优化手段:

     1)调整日志输出级别为error

    2)开启thymeleaf缓存(前后端分离项目忽略)

         

    3)动静分离,将静态资源交个nginx来处理

     4)优化代码本身,减少与DB交互的次数,优化后代码:

//获取当前一级分类下的子分类 
public Map<String, List<Catelog2Vo>> getCatalogJsonForDB() {
        List<CategoryEntity> list = this.list(null);
        //查出一级菜单
        List<CategoryEntity> categorys = this.list(new QueryWrapper<CategoryEntity>().eq("cat_level", 1));
        Map<String, List<Catelog2Vo>> collect1 = categorys.stream().collect(Collectors.toMap((k) -> {
            return k.getCatId().toString();
        }, (v) -> {
            List<CategoryEntity> categoryEntity2 = this.list(new QueryWrapper<CategoryEntity>().eq("parent_cid", v.getCatId()));
            List<Catelog2Vo> catelog2Vos = categoryEntity2.stream().map((obj) -> {
                Catelog2Vo catelog2Vo = new Catelog2Vo();
                catelog2Vo.setCatalog1Id(v.getCatId().toString());
                catelog2Vo.setId(obj.getCatId().toString());
                catelog2Vo.setName(obj.getName());
                List<CategoryEntity> catelog3Vo = this.list(new QueryWrapper<CategoryEntity>().eq("parent_cid", obj.getCatId()));
                List<Catelog2Vo.Catalog3Vo> collect = catelog3Vo.stream().map((vo3) -> {
                    Catelog2Vo.Catalog3Vo catelo3Vo = new Catelog2Vo.Catalog3Vo();
                    catelo3Vo.setName(vo3.getName());
                    catelo3Vo.setId(vo3.getCatId().toString());
                    catelo3Vo.setCatalog2Id(obj.getCatId().toString());
                    return catelo3Vo;
                }).collect(Collectors.toList());
                catelog2Vo.setCatalog3List(collect);
                return catelog2Vo;
            }).collect(Collectors.toList());
            return catelog2Vos;
        }));
        return collect1;
    }

private List<CategoryEntity> getParent_cid(List<CategoryEntity> categoryEntities,Long parentCid) {
        List<CategoryEntity> collect = categoryEntities.stream().filter((obj) -> {
            return obj.getParentCid() == parentCid;
        }).collect(Collectors.toList());
        return collect;
    }

      5)  给where后面的字段创建索引(parent_cid)

create index idx_pid on pms_category(parent_cid)

      6)设置JVM的参数(大一些)

        7)加入本地缓存(Map),代码:

  //获取数据带有map的缓存
    public Map<String, List<Catelog2Vo>> getCatalogJsonForMapCache() {
        Map<String,Object> map = new HashMap<>();
        Map<String, List<Catelog2Vo>> cache = (Map<String, List<Catelog2Vo>>) map.get("catalogJson");
        if (cache==null){

            List<CategoryEntity> list = this.list(null);
            //查出一级菜单
            List<CategoryEntity> categorys = this.list(new QueryWrapper<CategoryEntity>().eq("cat_level", 1));
            Map<String, List<Catelog2Vo>> collect1 = categorys.stream().collect(Collectors.toMap((k) -> {
                return k.getCatId().toString();
            }, (v) -> {
                List<CategoryEntity> categoryEntity2 = getParent_cid(list,v.getCatId());
                List<Catelog2Vo> catelog2Vos = categoryEntity2.stream().map((obj) -> {
                    Catelog2Vo catelog2Vo = new Catelog2Vo();
                    catelog2Vo.setCatalog1Id(v.getCatId().toString());
                    catelog2Vo.setId(obj.getCatId().toString());
                    catelog2Vo.setName(obj.getName());
                    List<CategoryEntity> catelog3Vo = getParent_cid(list,obj.getParentCid());
                    List<Catelog2Vo.Catalog3Vo> collect = catelog3Vo.stream().map((vo3) -> {
                        Catelog2Vo.Catalog3Vo catelo3Vo = new Catelog2Vo.Catalog3Vo();
                        catelo3Vo.setName(vo3.getName());
                        catelo3Vo.setId(vo3.getCatId().toString());
                        catelo3Vo.setCatalog2Id(obj.getCatId().toString());
                        return catelo3Vo;
                    }).collect(Collectors.toList());
                    catelog2Vo.setCatalog3List(collect);
                    return catelog2Vo;
                }).collect(Collectors.toList());
                return catelog2Vos;
            }));
            map.put("catalogJson",collect1);
        }   //查出所有菜单

        return cache;
    }

        8)加入redis缓存

    //使用了redis缓存获取数据
    @Override
    public Map<String, List<Catelog2Vo>> getCatalogJson() {
        String jsonData = stringRedisTemplate.opsForValue().get("jsonData");
        if (jsonData==null){
            Map<String, List<Catelog2Vo>> catalogJsonForDB = getCatalogJsonForDB();
            stringRedisTemplate.opsForValue().set("jsonData",JSON.toJSONString(catalogJsonForDB));
            return catalogJsonForDB;
        }
        return JSON.parseObject(jsonData, new TypeReference<Map<String, List<Catelog2Vo>>>(){});
    }

 用redis做也会出现很多问题:比如缓存击穿,缓存雪崩,缓存穿透,关于这些大家可以参考我的这篇博客:

redis缓存雪崩,缓存穿透,缓存击穿_handsomeyxl的博客-CSDN博客

以及使用分布式锁(Redisson)所来解决问题,参考我的博客:

Redis分布式锁(不使用会出现哪些问题)_handsomeyxl的博客-CSDN博客

当然还有更多优化:比如线程池,异步编排,大家有兴趣可以了解一下

这篇文章希望对你有帮助,有问题私信一起交流!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
接口调优和JMeter压力测试是两个不同的概念,但它们可以相互配合来优化接口性能。下面我将分别介绍这两个方面的内容。 接口调优是指对接口进行优化,以提高其性能和效率。在进行接口调优时,可以考虑以下几个方面: 1. 代码优化:对接口的代码进行优化,如减少不必要的计算、避免重复查询等,以提高代码的执行效率。 2. 数据库优化:对接口所涉及的数据库进行优化,如建立索引、优化查询语句等,以减少数据库查询的时间。 3. 缓存优化:使用缓存技术,将接口的响应结果缓存起来,减少重复计算和查询,提高接口的响应速度。 4. 并发处理:针对高并发场景,对接口进行并发处理的优化,如使用线程池、异步处理等,提高接口的并发能力。 JMeter是一款常用的压力测试工具,可以模拟多用户同时访问接口,以测试接口的性能和稳定性。使用JMeter进行压力测试时,可以按照以下步骤进行: 1. 配置测试计划:设置测试计划,包括目标接口、并发用户数、请求频率等。 2. 添加线程组:添加线程组,设置并发用户数和持续时间等参数。 3. 添加HTTP请求:添加HTTP请求,配置接口的请求方式、URL、参数等。 4. 添加监听器:添加监听器,用于查看测试结果,如响应时间、吞吐量等。 5. 运行测试:运行测试计划,查看接口在不同并发条件下的性能表现。 通过JMeter压力测试,可以发现接口的性能瓶颈,并根据测试结果进行接口调优,以提高接口的性能和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值