浅谈Spring Boot: 接口压测及简要优化策略

工程做好之后,需要对接口进行压力测试。可以自己编写线程池模拟多用户访问测试,也可以使用jmeter进行压测。jmeter的好处是测试方便,并且有完善的结果分析功能。本次采用jmeter进行压力测试。

1.准备数据,为了测试准备200w条以上的数据。一个简单的方法是使用下面的sql快速创建。

INSERT INTO table (user_name,address)

SELECT user_name, address FROM table;

但这样创建的数据不同记录的重复部分太多,和实际业务不太相符。一般业务上,除了主键之外还会有某一个字段是唯一,比如手机号,用户名等。本次将user_name设置为唯一,简单采用UUID的方式生成。

@RequestMapping("/create")
public Integer createData(Integer password) {
if (password != 1024) {
return 0;
}
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(10,
20, 1, TimeUnit.MINUTES,
new ArrayBlockingQueue<Runnable>(100000),
Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
int max = 1000000;
for (int i = 0; i < max; i++) {
poolExecutor.execute(() -> {
Date now = new Date();
User user = new User();
user.setStatus(0);
user.setUserName(UUID.randomUUID().toString().replace("-", ""));
user.setAddress("");
user.setCreateTime(now);
user.setUpdateTime(now);
userService.saveUser(user);
});
}
return 1;
}

采用线程池技术来生成数据。部分参数参考自己的配置进行设置。我这里采用核心线程数10,最大线程数20,阻塞队列容量10w,拒绝策略CallerRunsPolicy的参数来生成。

数据生成以后,确认下生成数量,可以看到所有的user_name都是不同的。

select count(*),count(distinct user_name) from user

2.改造接口。为了测试方便,使用公共mapper。引入依赖

<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>

修改启动类MapperScan注解为import tk.mybatis.spring.annotation.MapperScan;

mapper接口继承extends Mapper,(import tk.mybatis.mapper.common.Mapper;)。这样就会为mapper生成insert,select等基本方法。

3.测试。

所测试的接口为

@RequestMapping(value = "/hello", method = {RequestMethod.POST})
public List<User> getUser(User user) {
return userService.getUserByUser(user);
}

打开jmeter,通过Option选择中文语言。创建测试计划,这次仅对接口进行压力测试。

测试参数选择userName,并使用随机生成的UUID,这样可以保证最终访问DB时不触发任何缓存。

1.文件-新建测试计划

2.编辑-添加-线程-线程组

3.选中线程组,编辑-添加-逻辑控制器-事务控制器

4.选中事务控制器,编辑-添加-取样器-BeanShell 取样器

5.选中事务控制器,编辑-添加-HTTP请求

6.选中BeanShell取样器,将下面代码复制到脚本框里面,内容即为设置user_name变量为UUID。

import java.util.UUID;
UUID uuid1 = UUID.randomUUID();
vars.put("user_name",(uuid1.toString()).toUpperCase().replaceAll("-","")); 

7.选中HTTP请求,设置如下,其中参数部分内容为:

名称
userName ${user_Name}

这样就可以将步骤6生成的参数传递为HTTP POST请求的参数了。

添加结果树,汇总报告等,最终结构:

8.选中线程组,设置线程数等信息,详细请参照官网:https://jmeter.apache.org/usermanual/index.html

这里先设置线程数为2000,由于要压力测试,设置Ramp-up为1秒,即1秒内启动所有线程。

9.启动线程组。在这里插入图片描述

10.结果树里面可以确认具体每次请求的参数:

汇总报告里面可以查看总体信息:

通过以上步骤,可以初步预估下系统各个接口的吞吐量等信息。第一次压测中user_name自动没有设置索引,可以通过一些方法来提高系统性能:

1.为user_name设置索引。

2.使用redis缓存,其一是缓存最近检索数据,其二是将表中所有user_name存入缓存(Set),请求到来时首先去缓存中查看是否存在,只有存在的时候才去检索DB。

3.若数据量过大,可采用布隆过滤器存储user_name。

4.限流,这里只说API层面的,guava包下RateLimiterJ;自写切面+Redis;Spring Cloud GateWay。

工程地址:https://github.com/showsys20/spring-demo-cm.git

以上这篇浅谈Spring Boot: 接口压测及简要优化策略就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • SpringBoot使用knife4j进行在线接口调试

    前言 我们在开发一个Java Web的项目,如果项目整体采用前后端分离的架构的方式,我们会经常使用Swagger来进行接口调试和为前端提供接口文档,但是Swagger并没有实际上那么方便,比如我们在发送Post请求时,参数选填还是非常不友好,那么有没有更好的工具呢? 正文 knife4j knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案,前身是swagger-bootstrap-ui,具有小巧,轻量,并且功能强悍的优点. Knife4j提供两大核心功能:文档说

  • springboot基于过滤器实现接口请求耗时统计操作

    Spring Boot中实现一个过滤器相当简单,实现javax.servlet.Filter接口即可. 下面以实现一个记录接口访问日志及请求耗时的过滤器为例: 1.定义ApiAccessFilter类,并实现Filter接口 @Slf4j @WebFilter(filterName = "ApiAccessFilter", urlPatterns = "/*") public class ApiAccessFilter implements Filter { @Ov

  • 浅析springboot通过面向接口编程对控制反转IOC的理解

    IoC是什么 Ioc-Inversion of Control,即"控制反转",不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制.如何理解好Ioc呢?理解好Ioc的关键是要明确"谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了",那我们来深入分析一下: ●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象

  • SpringBoot后端接口的实现(看这一篇就够了)

    摘要:本文演示如何构建起一个优秀的后端接口体系,体系构建好了自然就有了规范,同时再构建新的后端接口也会十分轻松. 一个后端接口大致分为四个部分组成:接口地址(url).接口请求方式(get.post等).请求数据(request).响应数据(response).如何构建这几个部分每个公司要求都不同,没有什么"一定是最好的"标准,但一个优秀的后端接口和一个糟糕的后端接口对比起来差异还是蛮大的,其中最重要的关键点就是看是否规范! 本文就一步一步演示如何构建起一个优秀的后端接口体系,体系构建

  • springboot统一接口返回数据的实现

    一,没有异常的情况,正常返回数据 希望接口统一返回的数据格式如下: { "status": 0, "msg": "成功", "data": null } 和接口数据对应的bean /** * 统一返回结果的实体 * @param <T> */ public class Result<T> implements Serializable { private static final long serial

  • SpringBoot中整合knife4j接口文档的实践

    在项目开发中,web项目的前后端分离开发,APP开发,需要由前后端工程师共同定义接口,编写接口文档,之后大家都根据这个接口文档进行开发,到项目结束前都要一直维护 接口文档使得项目开发过程中前后端工程师有一个统一的文件进行沟通交流开发,项目维护中或者项目人员更迭,方便后期人员查看.维护 一.界面先赏 1.首页 2.接口文档 3.调试 二.整合 knife4j 1.引入 maven 依赖 <!-- knife4j接口文档 start --> <dependency> <group

  • 浅谈Spring Boot: 接口压测及简要优化策略

    工程做好之后,需要对接口进行压力测试.可以自己编写线程池模拟多用户访问测试,也可以使用jmeter进行压测.jmeter的好处是测试方便,并且有完善的结果分析功能.本次采用jmeter进行压力测试. 1.准备数据,为了测试准备200w条以上的数据.一个简单的方法是使用下面的sql快速创建. INSERT INTO table (user_name,address) SELECT user_name, address FROM table; 但这样创建的数据不同记录的重复部分太多,和实际业务不太相

  • 浅谈spring boot 1.5.4 异常控制

    spring boot 已经做了统一的异常处理,下面看看如何自定义处理异常 1.错误码页面映射 1.1静态页面 必须配置在 resources/static/error文件夹下,以错误码命名 下面是404错误页面内容,当访问一个不存在的链接的时候,定位到此页 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Not F

  • 浅谈spring boot 集成 log4j 解决与logback冲突的问题

    现在很流行springboot的开发,小编闲来无事也学了学,开发过程中遇见了log4j日志的一个小小问题,特此记载. 首先在pox.xml中引入对应的maven依赖: <!-- 引入log4j--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency&g

  • 浅谈Spring Boot 开发REST接口最佳实践

    本文介绍了Spring Boot 开发REST接口最佳实践,分享给大家,具体如下: HTTP动词与SQL命令对应 GET 从服务器获取资源,可一个或者多个,对应SQL命令中的SELECT GET /users 获取服务器上的所有的用户信息 GET /users/ID 获取指定ID的用户信息 POST 在服务器上创建一个新资源,对应SQL命令中的CREATE POST /users 创建一个新的用户 PUT 在服务器上更新一个资源,客户端提供改变后的完整资源,对应SQL命令中的UPDATE PUT

  • 浅谈Spring Boot 整合ActiveMQ的过程

    RabbitMQ是比较常用的AMQP实现,这篇文章是一个简单的Spring boot整合RabbitMQ的教程. 安装ActiveMQ服务器,(也可以不安装,如果不安装,会使用内存mq) 构建Spring boot项目,增加依赖项,只需要添加这一项即可 <!-- 添加acitivemq依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring

  • 浅谈Spring Boot日志框架实践

    Java应用中,日志一般分为以下5个级别: ERROR 错误信息 WARN 警告信息 INFO 一般信息 DEBUG 调试信息 TRACE 跟踪信息 Spring Boot使用Apache的Commons Logging作为内部的日志框架,其仅仅是一个日志接口,在实际应用中需要为该接口来指定相应的日志实现. SpringBt默认的日志实现是Java Util Logging,是JDK自带的日志包,此外SpringBt当然也支持Log4J.Logback这类很流行的日志实现. 统一将上面这些 日志

  • 浅谈Spring Boot中Redis缓存还能这么用

    经过Spring Boot的整合封装与自动化配置,在Spring Boot中整合Redis已经变得非常容易了,开发者只需要引入Spring Data Redis依赖,然后简单配下redis的基本信息,系统就会提供一个RedisTemplate供开发者使用,但是今天松哥想和大伙聊的不是这种用法,而是结合Cache的用法.Spring3.1中开始引入了令人激动的Cache,在Spring Boot中,可以非常方便的使用Redis来作为Cache的实现,进而实现数据的缓存. 工程创建 首先创建一个Sp

  • 浅谈Spring Boot中如何干掉if else的方法

    前言 看到crossoverJie的文章<利用策略模式优化过多 if else 代码>后受到启发,可以利用策略模式简化过多的if else代码,文章中提到可以通过扫描实现处理器的自注册,我在这里介绍在Spring Boot框架中的实现方法. 需求 这里虚拟一个业务需求,让大家容易理解.假设有一个订单系统,里面的一个功能是根据订单的不同类型作出不同的处理. 订单实体: public class OrderDTO { private String code; private BigDecimal

  • 浅谈Spring Boot 2.0迁移指南主要注意点

    Spring官方的Spring Boot 2变动指南,主要是帮助您将应用程序迁移到Spring Boot 2.0,变化部分还是很多很细节的,摘录主要点如下: Spring Boot 2.0需要Java 8或更高版本.不再支持Java 6和7.它还需要Spring Framework 5.0,许多配置属性被重新命名/删除,开发者需要更新他们的application.properties/ application.yml相应.为了帮助您,Spring Boot提供了一个新spring-boot-pr

  • 浅谈Spring Boot 微服务项目的推荐部署方式

    如果开发过spring boot的程序,应该都知道,使用spring boot官方的maven打包插件(spring-boot-maven-plugin) 来打包,打出来的jar包一般有40M以上. 如果公司的服务器上传带宽不高,那么手动上传一个jar或者jenkins部署一次jar,都是非常痛苦的........ 但是,如果打包的时候不引入lib,那么打出来的jar包一般只有几十k而已,非常小,想怎么传就怎么传......... 本文会提供一个bash启动脚本,只需要稍做更改,即可适应你的程序

随机推荐