Java开发(五)--- web并发问题

使用框架为springMVC。

测试方法为在浏览器中打开多个窗口,手动访问同一耗时方法。

结论:当Chrome浏览器打开多个窗口发起多个请求访问同一个接口时,springMVC中的方法会顺序执行,当一个方法过于耗时,那么由于多个请求是顺序执行,有些请求可能等待几十秒。

代码为:

	@RequestMapping("index")
	public String index(Model model) {
		long startTime = System.currentTimeMillis();
		String begin = Thread.currentThread().getName()+":springmvc method begin";
		logger.info(begin);
		try {
			Thread.sleep(6000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		String end = Thread.currentThread().getName()+":springmvc method end";
		logger.info(end);
		model.addAttribute("msg", begin+"<br/>"+end+"<br/>"+this);
		logger.info(Thread.currentThread().getName()+(System.currentTimeMillis()-startTime));
		return "index";
	}

打印的日志为:

2018/02/27 14:40:23 809: INFO [http-nio-8082-exec-46] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-46:springmvc method begin
 2018/02/27 14:40:29 811: INFO [http-nio-8082-exec-46] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-46:springmvc method end
 2018/02/27 14:40:29 811: INFO [http-nio-8082-exec-46] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-466002
 2018/02/27 14:40:29 845: INFO [http-nio-8082-exec-50] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-50:springmvc method begin
 2018/02/27 14:40:35 846: INFO [http-nio-8082-exec-50] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-50:springmvc method end
 2018/02/27 14:40:35 846: INFO [http-nio-8082-exec-50] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-506001
 2018/02/27 14:40:35 865: INFO [http-nio-8082-exec-42] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-42:springmvc method begin
 2018/02/27 14:40:41 866: INFO [http-nio-8082-exec-42] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-42:springmvc method end
 2018/02/27 14:40:41 866: INFO [http-nio-8082-exec-42] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-426001

如上。

但是,使用ab压力测试工具,却可以得到不一致的结论,测试如下:

命令为:

ab -c 4 -n 4 http://192.168.56.1:8082/concurent/controller/index

指定并发为4,请求的总数量为4。

打印的日志为:

2018/02/27 14:44:22 127: INFO [http-nio-8082-exec-53] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-53:springmvc method begin
 2018/02/27 14:44:28 129: INFO [http-nio-8082-exec-53] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-53:springmvc method end
 2018/02/27 14:44:28 129: INFO [http-nio-8082-exec-53] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-536002
 2018/02/27 14:44:28 153: INFO [http-nio-8082-exec-55] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-55:springmvc method begin
 2018/02/27 14:44:28 156: INFO [http-nio-8082-exec-57] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-57:springmvc method begin
 2018/02/27 14:44:28 160: INFO [http-nio-8082-exec-54] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-54:springmvc method begin
 2018/02/27 14:44:28 168: INFO [http-nio-8082-exec-58] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-58:springmvc method begin
 2018/02/27 14:44:34 155: INFO [http-nio-8082-exec-55] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-55:springmvc method end
 2018/02/27 14:44:34 155: INFO [http-nio-8082-exec-55] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-556002
 2018/02/27 14:44:34 160: INFO [http-nio-8082-exec-57] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-57:springmvc method end
 2018/02/27 14:44:34 161: INFO [http-nio-8082-exec-57] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-576005
 2018/02/27 14:44:34 168: INFO [http-nio-8082-exec-54] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-54:springmvc method end
 2018/02/27 14:44:34 169: INFO [http-nio-8082-exec-54] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-546009
 2018/02/27 14:44:34 173: INFO [http-nio-8082-exec-58] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-58:springmvc method end
 2018/02/27 14:44:34 174: INFO [http-nio-8082-exec-58] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-586006

可见第一个请求单独进入方法,其余的请求等待,当第一个请求完成之后,剩余的三个请求同时进入方法。不明白是什么原因,和java虚拟机的运行机制有关?

不过第一种测试方式更加的贴近真实应用场景,这种情况下一个请求接口不能同时处理多个请求,这种情况下,并发量怎么会高?

补充:

    单独运行java程序,不同的线程是可以同时进入同一个方法进行执行的。

    代码为:

package com.hurricane.learn.concurent.test;

public class TestFun implements Runnable{

	/**
	 * 多线程可以并行进入同一方法,方法内部变量是线程安全的
	 * @param args
	 */
	public static void main(String[] args) {
		TestFun fun = new TestFun();
		Thread thread1 = new Thread(fun);
		Thread thread2 = new Thread(fun);
		thread1.start();
		thread2.start();
	}
	
	private void method() throws InterruptedException {
		int i=0;
		long start = System.currentTimeMillis();
		i++;
		System.out.println(i+Thread.currentThread().getName());
		Thread.sleep(3000);
		i++;
		System.out.println(i+Thread.currentThread().getName()+(System.currentTimeMillis()-start));
	}

	@Override
	public void run() {
		try {
			method();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

输出为:

1Thread-0
1Thread-1
2Thread-13000
2Thread-03000

后续:

第二天,想到可能是因为请求来自于同一个客户端,才使得无法同时进入同一请求接口,然后做了如下测试:

使用Chrome、Opera、IE三个浏览器同时访问同一个请求,输出的日志为:

2018/02/28 10:24:44 819: INFO [http-nio-8082-exec-5] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-5:springmvc method begin
 2018/02/28 10:24:45 468: INFO [http-nio-8082-exec-4] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-4:springmvc method begin
 2018/02/28 10:24:46 284: INFO [http-nio-8082-exec-10] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-10:springmvc method begin
 2018/02/28 10:24:50 820: INFO [http-nio-8082-exec-5] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-5:springmvc method end
 2018/02/28 10:24:50 821: INFO [http-nio-8082-exec-5] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-56002
 2018/02/28 10:24:51 468: INFO [http-nio-8082-exec-4] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-4:springmvc method end
 2018/02/28 10:24:51 469: INFO [http-nio-8082-exec-4] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-46001
 2018/02/28 10:24:52 285: INFO [http-nio-8082-exec-10] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-10:springmvc method end
 2018/02/28 10:24:52 285: INFO [http-nio-8082-exec-10] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-106001

从日志中可以看到,来自于不同的客户端对同一请求接口进行访问,随时可以同时执行请求方法的,因此在并发请求时,不会因为一个方法中耗时长,而出现请求排队的现象。

至于,Tomcat服务器如何区分请求来自同一客户端,然后让来自于同一客户端的同一请求排队的实现,就不知道了。

若要同一客户端对同一请求能够并行进入,可以在请求连接后附一个时间戳,方便起见,测试使用了任意字符串代替时间戳,测试如下:

同一客户端同时请求:    http://localhost:8082/concurent/controller/index?sssss

与http://localhost:8082/concurent/controller/index?ttttt

输出的日志为:

2018/02/28 10:57:35 181: INFO [http-nio-8082-exec-2] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-2:springmvc method begin
 2018/02/28 10:57:35 914: INFO [http-nio-8082-exec-3] com.hurricane.learn.concurent.controller.MyController.index(39) | http-nio-8082-exec-3:springmvc method begin
 2018/02/28 10:57:41 182: INFO [http-nio-8082-exec-2] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-2:springmvc method end
 2018/02/28 10:57:41 189: INFO [http-nio-8082-exec-2] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-26008
 2018/02/28 10:57:41 915: INFO [http-nio-8082-exec-3] com.hurricane.learn.concurent.controller.MyController.index(46) | http-nio-8082-exec-3:springmvc method end
 2018/02/28 10:57:41 915: INFO [http-nio-8082-exec-3] com.hurricane.learn.concurent.controller.MyController.index(48) | http-nio-8082-exec-36001

可以并行进入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值