原生Servlet与Spring Controller性能比较

2023-10-27

  在实际项目工作,有同事提出,Java原生的Servlet性能(响应速度与并发数)要比封装过的Spring Controller高,基于这点,楼主用Apache的ab工具,对两个简单的应用做1000并发压力测试,查看两者的响应速度与并发数、平均响应时间等参数。


  ab工具的使用与介绍,楼主就不描述了,网上的文章很多,读者可以参考《Windows下Apache服务器自带Ab.exe的压力测试方法》一文。


原生Servlet应用描述:

  用简单的方式,在eclipse中建立一个Dynamic Web project,然后创建一个Servlet,用注解的方式即可,这样可以不用修改web.xml文件,逻辑处理的仿真代码如下(线程休眠50ms,模拟实际的业务处理时间)  

/**
 * Servlet implementation class AbTestServlet
 */
@WebServlet("/AbTestServlet")
public class AbTestServlet extends HttpServlet {
<span style="white-space:pre">	</span>private static final long serialVersionUID = 1L;
       
    public AbTestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
<span style="white-space:pre">	</span>System.out.println("Ab Test Servlet 响应 "+System.currentTimeMillis());
<span style="white-space:pre">	</span>try {
<span style="white-space:pre">		</span>Thread.sleep(50);
<span style="white-space:pre">	</span>    } catch (InterruptedException e) {
<span style="white-space:pre">		</span>e.printStackTrace();
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>response.getWriter().append("Served at: ").append(request.getContextPath());
<span style="white-space:pre">	</span>}

      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
<span style="white-space:pre">	</span>// TODO Auto-generated method stub
<span style="white-space:pre">	</span>doGet(request, response);
     }
}

Servlet项目源代码下载地址


Spring Controller应用描述:

  建立一个简单的maven项目,只导入spring-webmvc与spring-context即可(版本4.2.5),编写项目的web.xml文件如下

	<!-- 4:加入Spring Context 配置文件 与 Listener -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:/config/application-context.xml</param-value>
	</context-param>
	
	<!-- 4:加入Spring Context 配置文件 与 Listener -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- 1:启动Spring的MVC  DispatcherServlet -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value></param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
		<async-supported>true</async-supported>
	</servlet>
	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
  在编写Spring的配置文件如下

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
    xmlns:aop="http://www.springframework.org/schema/aop"    
    xmlns:tx="http://www.springframework.org/schema/tx"    
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
          http://www.springframework.org/schema/beans     
          http://www.springframework.org/schema/beans/spring-beans.xsd        
          http://www.springframework.org/schema/context     
          http://www.springframework.org/schema/context/spring-context.xsd     
          http://www.springframework.org/schema/mvc 
          http://www.springframework.org/schema/mvc/spring-mvc.xsd" >  
	
    <!-- 完成请求和注解POJO的映射(激活@Controller模式  ),它会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter两个bean, 这两个bean是spring MVC为@Controllers分发请求所必须的  -->
    <mvc:annotation-driven/> 
	<!-- 自动扫描组件Service -->  
	<context:component-scan base-package="com.cloud.abtest"/>
</beans>
  编写一个简单的Controller如下

package com.cloud.abtest.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;


@Controller
public class AbTestController {
	
	@RequestMapping("/AbTestController")
	@ResponseBody
	public String login(HttpServletRequest request, HttpServletResponse response) throws Exception{
		
		System.out.println("Ab Test Controller 响应 "+System.currentTimeMillis());
		try {
			Thread.sleep(50);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return "Served at: "+request.getContextPath();
	}

}
controller项目原代码下载地址

对原生Servlet项目进行并发压力测试命令和结果如下:

<span style="white-space:pre">	</span>命令为: ab -n 1000 -c 1000 http://localhost:8080/AbtestServlet/AbTestServlet
	Apache24\bin>ab -n 1000 -c 1000 http://localhost:8080/AbtestServlet/AbTestServlet
	This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
	Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
	Licensed to The Apache Software Foundation, http://www.apache.org/
	
	Benchmarking localhost (be patient)
	Completed 100 requests
	Completed 200 requests
	Completed 300 requests
	Completed 400 requests
	Completed 500 requests
	Completed 600 requests
	Completed 700 requests
	Completed 800 requests
	Completed 900 requests
	Completed 1000 requests
	Finished 1000 requests
	
	
	Server Software:        Apache-Coyote/1.1
	Server Hostname:        localhost
	Server Port:            8080
	
	Document Path:          /AbtestServlet/AbTestServlet
	Document Length:        25 bytes
	
	Concurrency Level:      1000
		<span style="background-color: rgb(51, 204, 0);">(并发线程数)</span>
	Time taken for tests:   0.850 seconds
		<span style="background-color: rgb(51, 204, 0);">(使用时间)</span>
	Complete requests:      1000
		<span style="background-color: rgb(51, 255, 51);">(成功的请求数量)</span>
	Failed requests:        0
		<span style="background-color: rgb(51, 255, 51);">(失败的请求数量)</span>
	Total transferred:      147000 bytes
		<span style="background-color: rgb(51, 255, 51);">(全部使用的流量)</span>
	HTML transferred:       25000 bytes
		<span style="background-color: rgb(51, 255, 51);">(Html文件使用的流量)</span>
	Requests per second:    1176.40 [#/sec] (mean)
		<span style="background-color: rgb(51, 255, 51);">(指标一 平均每秒请求数)</span>
	Time per request:       850.049 [ms] (mean)(测了好几次,500,800,1200都有,平均1000左右)
		<span style="background-color: rgb(51, 255, 51);">(指标二 平均事务响应时间)</span>
	Time per request:       0.850 [ms] (mean, across all concurrent requests)
		<span style="background-color: rgb(51, 255, 51);">(平均请求时间)</span>
	Transfer rate:          168.88 [Kbytes/sec] received
		<span style="background-color: rgb(51, 255, 51);">(传输速率)</span>
	
	Connection Times (ms)
	              min  mean[+/-sd] median   max
	Connect:        0    0   1.0      0      18
	Processing:   302  486  81.3    504     600
	Waiting:       93  392  91.2    394     546
	Total:        303  486  81.3    504     601
		<span style="background-color: rgb(51, 255, 51);">(所有请求的响应情况)</span>
	
	Percentage of the requests served within a certain time (ms)
	  50%    504
	  66%    545
	  75%    556
	  80%    562
	  90%    576
	  95%    585
	  98%    596
	  99%    599
	 100%    601 (longest request)
		<span style="background-color: rgb(51, 255, 51);">每个请求都有一个响应时间 。。 
		比如 其中 50% 的用户响应时间小于 504 毫秒 。。 
		最大的响应时间小于 601 毫秒 (100% 处) 。。 </span>

对Controller项目进行并发压力测试命令和结果如下:

<span style="white-space:pre">	</span>命令为: ab -n 1000 -c 1000 http://localhost:8080/abTestController/AbTestController
	Apache24\bin>ab -n 1000 -c 1000 http://localhost:8080/abTestController/AbTestControll
	This is ApacheBench, Version 2.3 <$Revision: 1748469 $>
	Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
	Licensed to The Apache Software Foundation, http://www.apache.org/
	
	Benchmarking localhost (be patient)
	Completed 100 requests
	Completed 200 requests
	Completed 300 requests
	Completed 400 requests
	Completed 500 requests
	Completed 600 requests
	Completed 700 requests
	Completed 800 requests
	Completed 900 requests
	Completed 1000 requests
	Finished 1000 requests
	
	
	Server Software:        Apache-Coyote/1.1
	Server Hostname:        localhost
	Server Port:            8080
	
	Document Path:          /abTestController/AbTestController
	Document Length:        28 bytes
	
	Concurrency Level:      1000
	Time taken for tests:   0.676 seconds
	Complete requests:      1000
	Failed requests:        0
	Total transferred:      195000 bytes
	HTML transferred:       28000 bytes
	<span style="background-color: rgb(51, 255, 51);">Requests per second:    1479.20 [#/sec] (mean)</span>
	Time per request:       676.039 [ms] (mean)
	Time per request:       0.676 [ms] (mean, across all concurrent requests)</span>
	Transfer rate:          281.68 [Kbytes/sec] received
	
	Connection Times (ms)
	              min  mean[+/-sd] median   max
	Connect:        0    0   0.5      0       4
	Processing:    96  325 107.4    358     475
	Waiting:       79  300 108.5    325     475
	Total:         96  325 107.4    358     476

结论:

  总体而言Servlet的并发与响应时间比Controller稍微好一些(同一个tomcat),但是几乎体现不出来,楼主贴的结果中Controller结果要好于Servlet的原因是刚好贴了个Controller效果好的,实际测试中每一个项目楼主都用1000的并发量测试好几十次,效果都差不多。

  PS:如果需要测试的URL是带参数的,需要用""号将URL包裹在里面,如下所示:

ab -n 1000 -c 1000 "http://localhost:8080/AbtestServlet/AbTestServlet?sId=1476067342641247&sourceId=0&test=10%KDO%"

  


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

原生Servlet与Spring Controller性能比较 的相关文章

  • 从 PDF 中提取不可选择的内容

    我正在使用 Apache PDFBox 从 PDF 文件中提取页面 但找不到提取不可选择的内容 文本或图像 的方法 从 PDF 文件中选择内容是没有问题的 请注意 相关 PDF 在复制内容方面没有任何限制 至少从我在文件的 文档限制摘要 中
  • Spring Batch如何作为Reader读取多个表(查询)并将其写入平面文件写入

    在我的项目中 我读取了具有不同查询的多个表 并将这些结果集合并到平面文件中 我该如何实现这一目标 我的意思是 JdbcReader 直接采用 1 个选择查询 我如何自定义它 如果 JdbcCursorItemReader 不能满足您的需求
  • JPA 实体中的方法是否允许抛出异常?

    我尝试创建的 Entity 有问题 当尝试使用 OpenJPA 实现在 Eclipse 中测试类时出现问题 我有not尝试过其他人 所以不确定它是否适用于他们 我的测试用例非常简单 因为它创建一个 EntityManagerFactory
  • 修复 java 内存泄漏的学习网站

    学习修复 java 内存泄漏的最佳地点是什么 我一直试图在网络上找到好的资源 但令我失望的是 我发现正在讨论玩具示例 我还能够对小型玩具转储进行故障排除 但现实世界的应用程序转储更具挑战性 并且提供的线索很少 我尝试过 Jhat JMap
  • Android 上的 setTimeOut() 相当于什么?

    我需要等效的代码setTimeOut call function milliseconds 对于安卓 setTimeOut call function milliseconds 您可能想查看定时任务 http developer andro
  • mvn dependency:analyze 结果不正确

    我一直在寻找一种工具 它能够向您显示未使用的依赖项 我很快就偶然发现了 Maven 命令mvn dependency analyze 这样做的问题是 它经常检测到 未使用的 依赖项 如果缺失 这些依赖项就会导致构建失败 这是优化项目的示例
  • JLabel.setText() 中的换行符

    使用 JLabel setText 时如何插入换行符 我尝试使用 Html 但似乎可以使其适用于 setText 仅适用于 jLabel 的初始声明 最初声明 jlabel 时的方法是 label new JLabel Hello Worl
  • java中如何围绕另一个移动对象旋转一个对象?

    我对 Java 很陌生 想要编写一个简单的太阳系统 其中月球绕地球旋转 地球绕太阳旋转 一切正常 除了月亮不想正确移动 由于地球偏离月球的初始位置 月球的自转半径会根据该距离而增大 同样 当地球接近月球惯性位置时 自转半径会减小 如果初始位
  • 如何通过keytool命令删除已经导入的证书/别名?

    我正在尝试通过 keytool 命令删除已导入的证书 keytool delete noprompt alias initcert keystore keycloak jks 但低于异常 keytool 错误 java lang Excep
  • lombok - 多个镜头中的 @Builder 模式

    I use Builder of 龙目岛项目 https github com rzwitserloot lombok 所以考虑我有这个例子 Builder public class Client private Getter Setter
  • 用户“root”@“localhost”的访问被拒绝

    我正在尝试从数据库中获取记录 但我面临这个访问被拒绝的问题 我尝试了 Stack Overflow 上提到的其他解决方案 例如向用户授予权限 但没有任何效果 访问数据库的代码 public void service HttpServletR
  • Java 创建 Thread 实例时会发生什么

    我有一个关于 Java 线程和操作系统线程的问题 我读了Java 线程与 Pthreads https stackoverflow com questions 5269535 java threads vs pthreads and Jav
  • 小米和oppo等中国ROM上的工作管理器,在电池优化时,将工作的计划延迟增加几个小时

    小米和 Oppo 等中国 ROM 上的工作管理器在进行电池优化时 会将计划的工作延迟增加几个小时 但是 我注意到一些应用程序即使在电池优化下也能够让计划的作业安静地完美运行 我注意到的一个区别是 它们每次运行作业时都会显示一条通知 那么这是
  • 让 Java 与 Windows 10 Ubuntu 一起使用

    我安装了 Windows 10 周年更新 以便可以在 Windows 上的 Ubuntu 上尝试 Bash 看如何安装 http www howtogeek com 249966 how to install and use the lin
  • 从 Java 调用 Python 代码时出现问题(不使用 jython)

    我发现这是从 java 运行 使用 exec 方法 python 脚本的方法之一 我在 python 文件中有一个简单的打印语句 但是 我的程序在运行时什么也没做 它既不打印Python文件中编写的语句 也不抛出异常 程序什么都不做就终止了
  • 如何迭代SparseArray?

    有没有办法迭代 Java SparseArray 适用于 Android 我用了sparsearray通过索引轻松获取值 我找不到 看来我找到了解决方案 我没有正确注意到keyAt index 功能 所以我会这样做 for int i 0
  • 对于每个抛出异常的语句,try/catch 是否被视为反模式?

    我目前正在审查同事的 Java 代码 我看到很多情况下 每个可能抛出异常的语句都被封装在自己的 try catch 中 其中 catch 块都执行相同的操作 哪个操作与我的问题无关 对我来说 这似乎是一种代码味道 我记得读到过它是一种常见的
  • SAXParseException:找不到元素“定义”的声明

    我对 camunda 和 DMN 完全陌生 我试图在 spring boot 中运行 DMN 示例 链接在这里 https github com camunda camunda bpm examples tree master dmn en
  • gwt - 在 RPC 调用中使用 List

    我有一个 RPC 服务 方法如下 public List
  • 文件构造函数说明

    我无法理解以下文件构造函数 public File String parent String child and public File File parent String child 参数有什么作用parent and child该文件

随机推荐

  • linux 查看一个g以上的文件夹,Linux系统中查找大文件的方法有哪些

    今天小编要跟大家分享的文章是关于Linux系统中查找最大文件的方法有哪些 正在从事Linux相关工作的小伙伴们 如果你也想知道如何查找Linux系统中的最大文件的方法就来和小编一起来看一看本篇文章吧 一 ls命令 最简单的方法就是借助 ls
  • 目标检测指标之树编辑距离TEDS (Tree-Edit-Distance-based Similarity)

    因为最近的项目需要用到TEDS这个指标 看原始论文没有看明白 整理了一下网上的资料汇总在这里做一个记录 如有侵权请联系我删除 首先是数据类型 表格的树结构图 HTML序列化结构 对于树而言 同样定义了树编辑距离的增删改操作 增 添加一个节点
  • 疯壳AI语音及人脸识别教程2-3定时器

    目录 1 1寄存器 1 1 2 实验现象 18 详情地址 https fengke club GeekMart views offline ai 购买链接 https fengke club GeekMart su fKw7Nb7oC js
  • 嵌入式(有名管道和无名管道)(进程间通讯)

    进程间通信 IPC InterProcess Communication 概念 就是进程和进程之间交换信息 常用通信方式 无名管道 pipe 有名管道 fifo 信号 signal 共享内存 mmap 套接字 socket 过时的IPC通信
  • 写论文注意事项

    文献检索 搜索引擎的高级功能 搜索引擎主要www google com和scholar google com www baidu com则仅在检索中文时稍好点 英文很差 用处不大 我们常用的google侧重于网页的检索 Scholar则主要
  • Linus Torvalds接受来自微软的Linux Hyper-V升级

    导读 微软最近推送了一些变更 旨在改进即将发布的 Linux 内核 6 6 版本对 Hyper V 的支持 这些改进包括在 Hyper V 上支持 AMD SEV SNP guest 和 Intel TDX guest 除了这两项 还有其他
  • TIM_TimeBaseInitStruct 和TIM_TimeBaseStructInit

    TIM TimeBaseInit的简介 brief Initializes the TIMx Time Base Unit peripheral according to the specified parameters in the TI
  • C与C++混合编程

    一 C与C 混合编程的原理 首先 我先了解一下编译的过程 分为四步 预处理 预处理用于将所有的 include头文件以及宏定义替换成其真正的内容 编译 将经过预处理之后的程序转换成特定汇编代码 assembly code 的过程 汇编 汇编
  • libero soc 11.9 modelsim仿真

    只是记录一个仿真过程 首先建立一个工程 简单的分频程序 点击图片处新建一个testbench 定义testbench名字随意 由于用的16M时钟 所以62 5ns ok 写testbench 双击下图位置开始仿真 双击以后modelsim会
  • Android、Flutter为不同的CPU架构包打包APK(v7a、v8a、x86)

    默认情况下 Android和Flutter打包出来的Apk都是包含了所有架构的 这样打出来的apk体积相对于单架构的apk有点大 这时 我们就需要分别打出不同的架构包 架构 一般来说 x86代表32位CPU x64 或者叫x86 64 代表
  • 全国职业技能大赛云计算--高职组赛题卷①(容器云)

    全国职业技能大赛云计算 高职组赛题卷 容器云 第二场次题目 容器云平台部署与运维 任务1 Docker CE及私有仓库安装任务 5分 任务2 基于容器的web应用系统部署任务 15分 任务3 基于容器的持续集成部署任务 15分 任务4 Ku
  • python图像处理-形状提取和识别1(基于Hough的形状提取)

    python图像处理 形状提取和识别1 基于Hough的形状提取 本系列一个分为两大部分 一个是形状提取 一个是形状识别 1 形状提取中 基于Hough函数法进行直线提取和圆形提取 还有即基于颜色的形状提取 这里扩展了一个小程序 识别一张棋
  • vs2010复制粘贴

    void CjiantiebanDlg OnBnClickedButton1 TODO 在此添加控件通知处理程序代码 复制 CString str GetDlgItem IDC EDIT1 gt GetWindowText str HGLO
  • ubantu配置运行orb-slam2小记

    虚拟环境 参考这篇即可 sudo apt install virtualenv sudo apt install virtualenvwrapper 配置 mkdir HOME virtualenvs export WORKON HOME
  • MySQL数据库的命令行语句

    1 命令行连接数据库的方法 本地连接 必须管理员身份打开cmd窗口 win R输入cmd后 shift ctrl enter mysql u 用户名 p 用户名 CaoQian 密码 cq2227558856 2 显示所有数据库 图中是四个
  • 进制转换(二进制、八进制、十进制、十六进制之间的转换)

    进制转换 1 1 二进制与十进制之间的转换 十进制转二进制 方法为 十进制数除2取余法 即十进制数除2 余数为权位上的数 得到的商值继续除 直到商为0为止 二进制转十进制 方法为 把二进制数按权展开 相加即得十进制数 1 2 二进制与八进制
  • visibility 与 overflow

    display 3 属性描述 设置或获取对象是否及如何显示 版本变更 是 语法模板 display none inline block list item inline block table inline table table capt
  • 如何高效的进行版本管理,版本管理的方法

    如何进行高效的版本管理 版本管理的方法 云效Projects版本管理为不同的产品线 模块建立版本 对集成版本进行相关活动的管理 在Projects版本管理中规划发布内容 可以关联需求 任务 缺陷 立即体验 开启版本管理 项目管理员和项目拥有
  • 【Hyper-v 管理器虚拟机配置内网外网固定ip】

    1 Default Switch Hyper v默认虚拟网卡 无法设置固定ip Hyper V自带一个不能删除的Default Switch虚拟交换机 虚拟机使用该网络可以自动获取IP直接上网 但这个网络的网关地址每次重启后都会改变 所以你
  • 原生Servlet与Spring Controller性能比较

    在实际项目工作 有同事提出 Java原生的Servlet性能 响应速度与并发数 要比封装过的Spring Controller高 基于这点 楼主用Apache的ab工具 对两个简单的应用做1000并发压力测试 查看两者的响应速度与并发数 平