关于springmvc的hello world的压测报告

栏目: Java · 发布时间: 5年前

内容简介:都说hello world 很简单,应该能承受很大的请求压力,那么到底有多大?你知道吗?如果知道,那咱们就不继续了。如果不知道,我们来看一下!1. 准备工作,快速建立一个基于springmvc的helloworld1.1. 在pom.xml引入spring必须的包级日志组件

都说hello world 很简单,应该能承受很大的请求压力,那么到底有多大?你知道吗?如果知道,那咱们就不继续了。如果不知道,我们来看一下!

1. 准备工作,快速建立一个基于springmvc的helloworld

1.1. 在pom.xml引入spring必须的包级日志组件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yougewe</groupId>
    <artifactId>mvn-local-test</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <org.springframework.version>4.3.20.RELEASE</org.springframework.version>
        <freemarker.version>2.3.23</freemarker.version>
        <slf4j.version>1.7.12</slf4j.version>
        <mybatis.version>3.4.5</mybatis.version>
        <aspectj.version>1.8.13</aspectj.version>
    </properties>

    <dependencies>
            <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.44</version>
            </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.8</version>
        </dependency>

            <!-- https://mvnrepository.com/artifact/junit/junit -->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <!-- 不关注位置先 -->
                <!--<scope>test</scope>-->
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.18</version>
                <scope>provided</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
            <dependency>
                <groupId>com.rabbitmq</groupId>
                <artifactId>amqp-client</artifactId>
                <version>5.1.1</version>
            </dependency>

        <!-- 配合slf4j使用  -->
        <!-- 日志记录 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>


    </dependencies>

    <build>
        <!--<finalName>sjd-yzbank-api</finalName>-->
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>2.6</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.20.1</version>
                <configuration>
                    <skipTests>false</skipTests>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-report-plugin</artifactId>
                <version>2.20.1</version>
                <!--<configuration>
                    <includes>
                        <include>**/*Test.java</include>
                    </includes>
                </configuration>-->
            </plugin>

            <!-- clean插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-clean-plugin</artifactId>
            </plugin>

            <!-- install插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-install-plugin</artifactId>
            </plugin>

            <!-- deploy插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
            </plugin>

            <!-- dependency插件 -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
            </plugin>

            <plugin>
                <!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->
                <!-- 用于更好的编译,如jdk版本太低等问题 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

1.2. 添加一个 web.xml, 只加一个dispatcherServlet 和一个字符集转换过滤器

    <filter>
        <filter-name>SpringEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SpringEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 防止Spring内存溢出监听器 -->
    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
    </listener>
    <!-- 如下 listener 会查找 WEB-INF/applicationContext.xml 文件 -->
    <!--<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>-->
    <!-- springMVC核心配置 -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- 拦截设置 -->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

1.3. 添加log4j.properties日志配置文件

log4j.rootLogger=DEBUG,console,im,logFile
log4j.additivity.org.apache=true
# 控制台(console)
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d(%r) [%t] %-5p %l: %m %x %n
# 日志文件(logFile)
log4j.appender.logFile=org.apache.log4j.FileAppender
log4j.appender.logFile.Threshold=DEBUG
log4j.appender.logFile.ImmediateFlush=true
log4j.appender.logFile.Append=true
log4j.appender.logFile.File=D:/logs/log.log4j
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=%d(%r) [%t] %-5p %l: %m %x %n
# 回滚文件(rollingFile)
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.Threshold=DEBUG
log4j.appender.rollingFile.ImmediateFlush=true
log4j.appender.rollingFile.Append=true
log4j.appender.rollingFile.File=D:/logs/log.log4j
log4j.appender.rollingFile.MaxFileSize=200KB
log4j.appender.rollingFile.MaxBackupIndex=50
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.ConversionPattern=%d(%r) [%t] %-5p %l: %m %x %n

1.4. 添加一个HelloController, 返回一个 字符串

@RestController
@RequestMapping("/hello")
public class HelloController {

    @RequestMapping(value = "/world", method = {RequestMethod.GET, RequestMethod.POST}, produces = "application/json")
    @ResponseBody
    public Object world(@ModelAttribute UserInfo info) {
        return "hello world!";
    }
}

好了,一切准备就绪!是时候让我们来看一下它的能力如何了!

测试工具: jmeter + 台式测试机一台

前提1:

机器配置: 4c8g 笔记本

网卡: 高通 QCA9377, 共享带宽: 100M, 网络测速: 下载:3.5MB/s 上传:475KB/s

web容器: tomcat7, 运行模式: apr(apache portable runtime)

压测过程如下:

并发100-5组连续请求, TPS: 146.2, error: 0, 平均响应时间: 0.381s, 最大响应时间: 2.44s

server端cpu有一瞬间的飙高,内存几乎无变化!

关于springmvc的hello world的压测报告

下面,按照规律,翻倍并发,200-5组连续请求!看下数据!

关于springmvc的hello world的压测报告

TPS增加了,为275;平均响应时间慢了点,0.429;没有 error。

再翻倍并发量:400-5组连续请求:

关于springmvc的hello world的压测报告

TPS下降了,为208;平均响应时间翻番,1.1秒;不过幸好还是没有error;

再翻倍并发量:800-5组连续请求:

关于springmvc的hello world的压测报告

TPS再次下降,为144;平均响应时间再翻番,3.6秒,这在生产环境已经不符合要求了!error仍为0;

再翻倍: 1600-5组:

关于springmvc的hello world的压测报告

注意,此时已经有error出现了,1.09%的错误率! TPS继续下降: 93.4,平均响应时间继续翻倍:8.9秒;

综上,springmvc的helloworld 能力差不多也就在1600了,因为已经有错误出现,在实际生产中已经完全不能接受了!

不过,我还是想看一下server到底能承受多大压力,也就是jvm完全宕机!

压到3000并发-5组:

关于springmvc的hello world的压测报告

看起来还能响应,其实再server端,jvm已经挂掉了!所以结论是,tomcat7(apr模式)是扛不住3000并发的!

降到2800,也依然jvm挂了!

关于springmvc的hello world的压测报告

降到2600,jvm没挂,但是错误量较多,由于错误导致并发只跑到12000就未能继续进行了,数据不准:

关于springmvc的hello world的压测报告

改了下失败策略后,2600,还是挂了,重启后可以扛住压力!

关于springmvc的hello world的压测报告

压到4840个请求就挂了!

2500并发,挂!

2300并发,挂!

2200并发,操作系统提示jre没有响应,被迫关闭 java 进程!

2000并发,挂!

1900并发,扛住了!cpu在80左右跳动!内存不变!

关于springmvc的hello world的压测报告

看来,1900还行,极限就2000吧!

好了,tomcat7看来是没辙了!

换tomcat8 的 nio 看下效果!

前提2:

tomcat8, nio 模式运行!

NIO介绍如下:

Java NIO: Channels and Buffers(通道和缓冲区)

标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

关于springmvc的hello world的压测报告

Java NIO: Non-blocking IO(非阻塞IO)

Java NIO可以让你非阻塞的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。

Java NIO: Selectors(选择器)

Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

关于springmvc的hello world的压测报告

直接从2000并发开测!

并发2000-5组连续请求!

关于springmvc的hello world的压测报告

server ok, 但是,仍然存在数错误,有几个并发请求卡死! TPS: 62.9, 平均响应: 14.7s

关于springmvc的hello world的压测报告

server ok, TPS: 77.2, error: 55%, 平均响应时间: 25s。只能说,服务端没死,但是基本已经不怎么可用了!

到最后,我压到 6000 的并发时,server 仍然没有挂掉!

所以,nio,是比较强悍的!


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Seasoned Schemer

The Seasoned Schemer

Daniel P. Friedman、Matthias Felleisen / The MIT Press / 1995-12-21 / USD 38.00

drawings by Duane Bibbyforeword and afterword by Guy L. Steele Jr.The notion that "thinking about computing is one of the most exciting things the human mind can do" sets both The Little Schemer (form......一起来看看 《The Seasoned Schemer》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具