在springboot中使用线程池调用service,提高web程序的高并发处理能力。而标题中说到springmvc,这里使用springboot。是因为springboot包含springmvc。
本文介绍
- springboot中如何添加线程池
- 线程池中线程认领任务
- jemeter高并发测试接口
serivce中创建一个线程池,注解到spring的容器中,这样其他的方法就能够调用这里的线程池。交给线程池并发处理,controller提交的任务。
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.async.DeferredResult;
import javax.annotation.PreDestroy;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Service
public class LongTimeAsyncCallService {
//创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
private ExecutorService cacheExecutor = Executors.newCachedThreadPool();
//服务器关闭或者销毁servlet的时候会执行destory方法告知使用者,准备销毁这个servlet了。
//用于关闭线程
@PreDestroy
public void destroyExecutor(){
cacheExecutor.shutdown();
}
public void handle(DeferredResult deferredResult ,Callable callback){
cacheExecutor.submit(callback);
deferredResult.onTimeout(new Runnable() {
@Override
public void run() {
WebResult result = WebResult.getFailWebResult("-1","server time out");
deferredResult.setResult(result);
}
});
}
}
//Callable 一个一个请求变成任务
//DeferredResult 将请求线程与后台执行线程分离,异步开来
下面是:controller创建任务的实例代码
@Resource
LongTimeAsyncCallService callService;
private Long deferrTimeout;
@Resource
Myservice myservice;
@RequestMapping(value="/query")
public Object query(Param param){
DeferredResult<MyResult> deferredResult = new DeferredResult<>(deferrTimeout);
Callable callable = new Callable() {
@Override
public Object call() throws Exception {
myservice.query(param,deferredResult);
return deferredResult;
}
};
//使用service创建的线程池,处理controller请求产生的一个个的任务
callService.handle(deferredResult,callable);
return deferredResult;
}
根据上面的实例代码,可以得出,在高并发的情况下。contoller快速创建一个个callable任务,然后将这些任务交给线程池处理这些任务。任务的数量大于线程的数量,这样就达到了高性能的要求了。
我在实际条件下:线程500,访问次数10次,也就是5000samples有良好的性能体现。
下图是jemeter测试案例使用情况
自己水平的原因可能存在一些错误,email me: [email protected]