并发条件下springmvc的@RequestBody获取数据异常问题处理

来源:互联网 发布:windows python安装 编辑:程序博客网 时间:2024/05/22 14:53

问题描述:系统的框架使用的是ssm框架,在模拟压力测试的时候,使用APCHE的压力测试,100个并发循环向系统的controller层发送请求,结果发现有如下异常情况:

Caused by: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect datetime value: '20172-11-02 08:02:57' for column 'execution_end_time' at row 1


2017-06-07 17:11:08,657 ERROR [robot.modules.appointment.rest.OrdReceiveRestController] - com.boozhong.robot.common.exception.CheckException: ExecutionStartTime不能大于ExecutionEndTime!


2017-06-07 17:11:03,838 ERROR [robot.modules.appointment.rest.OrdReceiveRestController] - java.lang.NumberFormatException: For input string: "E4."


com.boozhong.robot.common.exception.CheckException: 订单新增失败,订单[REC17060726]预约时间必须提前至少一小时!

根据数据库进行查询,以及对比发送请求的请求体发现,对应的数据的设置是正确的,但是为什么在传入到后台的时候,数据会发生篡改,了解spring的同学知道,spring的controller层,采用了单实例的模式,也就是共享一个实例变量,加了注解@Scope("prototype")注解,将controller变成原型,但是通过测试,发现问题依然存在,这是为什么呢?通过反复的测试和比较,发现引起异常的是有两个关于时间的字段引起的,executionStartTime和executionEndTime,检查下与controller相关的代码,发现先定义一个成员变量SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"),使用这个变量去格式化开始时间和结束时间,问题这下就明朗多了,是由于设置了成员变量,成员变量在并发的情况下,导致了,篡改了格式化开始时间和结束时间,从未导致了程讯的异常。那应该怎么处理,要不不定义这成员变量,要不controller设置域(前面测试过了,加这个注解不能解决问题),或者使用ThreadLocal定义变量,我这里采用了第一种解决方式,在工具类中,写了一个格式化时间的方法,对应的业务逻辑格式化时间就使用这个工具类中的方法,问题最终解决。

但是问题解决了,通过测试发现,一个请求的消耗时间会越来越长,这时就要考虑怎么样优化,提供请求的性能,这个问题,先放一下。

下面简单总结一下,在高并发测试下,优化代码的经验:

将业务逻辑的各个逻辑使用logger.info记录每个逻辑的耗时,统计出耗时比较长的逻辑代码,发现有的是由于重复代码导致的,这时需要去重;有的是由于调用别的包下的方法导致的,这时在本类中编写相关业务方法;有的发现是sql的耗时比较长,记得有一个多表查询的sql,使用了全连接、左连接、右连接,发现使用连接的时候有一部分主表太大,导致连接查询耗时比较长,通过修改连接的主表以及新增索引等方式来优化sql的性能;还有涉及到比如获取本机的ip和port的数据,可以使用静态的方式,在虚拟机启动的时候获取到,这样可以减少请求的调用时间;涉及到经常查询的数据,并且不会改变的,采用的缓存的技术,提高的查询效率;有的采用了多线程的方式提高代码的效率,比如在获取一个订单数据的时候,在保存订单的时候,同时对订单到传送的图片下载到本地。