使用多线程提高REST服务器性能
异步处理REST服务
1、使用Runnable异步处理Rest服务
释放主线程,启用副线程进行处理,副线程处理完成后直接返回请求
主要代码
import java.util.concurrent.Callable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
*
* @author hzc
*
*/
@RestController
public class AsyncController { private Logger logger = LoggerFactory.getLogger(AsyncController.class); @RequestMapping("/order")
public Callable<String> order() throws InterruptedException {
logger.info("主线程开始"); Callable<String> result = new Callable<String>() { @Override
public String call() throws Exception {
logger.info("副线程开始");
Thread.sleep(1000);
logger.info("副线程结束");
return "success";
} };
logger.info("主线程返回");
return result; }
}
2、使用DeferredResult异步处理Rest服务
释放主线程,启用副线程1进行前处理,副线程2进行后处理,副线程2处理完后返回请求
模拟业务场景

主线程调用副线程1进行业务处理,将任务放于消息队列,副线程2监听消息队列,并处理队列的任务,在使用DeferredResult获取队列返回的结果,返回给前端
Controller类
package com.maple.security.web.async; import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult; /**
*
* @author hzc
*
*/
@RestController
public class AsyncController { private Logger logger = LoggerFactory.getLogger(AsyncController.class); @Autowired
private MockQueue mockQueue; @Autowired
private DeferredResultHolder deferredResultHolder; @RequestMapping("/order")
public DeferredResult<String> order() throws InterruptedException {
logger.info("主线程开始"); String orderNumber = RandomStringUtils.randomNumeric(8);
mockQueue.setPlaceOrder(orderNumber); DeferredResult<String> result = new DeferredResult<>();
deferredResultHolder.getMap().put(orderNumber, result);
logger.info("主线程返回");
return result; }
}
模拟消息队列类
package com.maple.security.web.async; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; /**
*
* @author hzc
*
*/
@Component
public class MockQueue { private Logger logger = LoggerFactory.getLogger(MockQueue.class); // 生成下单
private String placeOrder; // 完成下单
private String completeOrder; public String getPlaceOrder() {
return placeOrder;
} public void setPlaceOrder(String placeOrder) {
new Thread(() -> {
logger.info("接到下单请求");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.completeOrder = placeOrder;
logger.info("下单请求处理完毕," + placeOrder);
}).start(); } public String getCompleteOrder() {
return completeOrder;
} public void setCompleteOrder(String completeOrder) {
this.completeOrder = completeOrder;
}
}
监听消息队列并处理类
package com.maple.security.web.async; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component; @Component
public class QueueListener implements ApplicationListener<ContextRefreshedEvent> { private Logger logger = LoggerFactory.getLogger(QueueListener.class); @Autowired
private MockQueue mockQueue; @Autowired
private DeferredResultHolder deferredResultHolder; @Override
public void onApplicationEvent(ContextRefreshedEvent event) { new Thread(() -> {
while (true) {
if (StringUtils.isNotBlank(mockQueue.getCompleteOrder())) {
String orderNumber = mockQueue.getCompleteOrder();
logger.info("返回订单处理结果:" + orderNumber);
deferredResultHolder.getMap().get(orderNumber).setResult("place order success"); mockQueue.setCompleteOrder(null); } else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start(); }
}
异步处理结果类
/**
*
*/
package com.maple.security.web.async; import java.util.HashMap;
import java.util.Map; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult; /**
* @author hzc
*
*/
@Component
public class DeferredResultHolder { private Map<String, DeferredResult<String>> map = new HashMap<String, DeferredResult<String>>(); public Map<String, DeferredResult<String>> getMap() {
return map;
} public void setMap(Map<String, DeferredResult<String>> map) {
this.map = map;
} }
3、异步处理配置
使用多线程提高REST服务器性能的更多相关文章
- 提高SharePoint2013服务器性能
一劳永逸,删除search services application,停止Windows服务:SharePoint Search Host Controller和SharePoint Server S ...
- 使用多线程提高Rest服务性能
⒈使用Runnable异步处理Rest服务 /** *使用Runnable异步处理Rest服务 * @return */ @GetMapping("/order") public ...
- Tomcat 服务器性能优化
简介 考虑一下这种场景,你开发了一个应用,它有十分优秀的布局设计,最新的特性以及其它的优秀特点.但是在性能这方面欠缺,不管这个应用如何都会遭到客户拒绝.客户总是期望它们的应用应该有更好的性能.如果你在 ...
- Tomcat服务器性能优化
在这篇文章里分以下的七个步骤,按照这些步骤走,Tomcat服务器的性能就能改善哦. 增加JVM堆(heap) 解决内存泄漏问题 线程池(thread pool)的设置 压缩 调节数据库性能 Tomca ...
- Tomcat 生产服务器性能优化
虑一下这种场景,你开发了一个应用,它有十分优秀的布局设计,最新的特性以及其它的优秀特点.但是在性能这方面欠缺,不管这个应用如何都会遭到客户拒绝.客户总是期望它们的应用应该有更好的性能.如果你在产品中使 ...
- 20个Linux服务器性能调优技巧
Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要 ...
- [转]20个你不得不知的Linux服务器性能调优技巧
Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要 ...
- [.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上)
[.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 利用多线程提高程序性能(上) 本节导读: 随着硬件和网络的高速发展,为多线程(Multithreading) ...
- [.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)
[.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这 ...
随机推荐
- HTML5存储方式
由于之前在参加面试或者笔试的过程中经常会被问到HTML5存储的内容,包括它们之间的区别.特征和应用范围,所以看到一篇介绍不错的文章,把里面的个人觉得适合我的内容按照自己的理解总结如下.方便以后忘记了进 ...
- Graphics 与 DisplayObject 的关系
在原生 Canvas 中,其实并没有 DisplayObject 的概念,它只有绘制图像的概念. 大部分的原生绘制图形或图像的 API 一般是这样的: api(x, y, ...) 例如 rect 就 ...
- idea 启动微服务 设置 run dashboard
微服务如果很多,启动时如果在run窗口,会不是很方便,所以idea中配置了rundashboard,有时不自动出现时,需要进行配置: 配置操作如下: 我的idea版本2020.2 1.在父工程的.id ...
- 实现call、apply 及 bind 函数
今日学习内容: (1)call 函数的实现步骤: 判断调用对象是否为函数,即使是定义在函数的原型上的,但是可能出现使用 call 等方式调用的情况. 判断传入上下文对象是否存在,如果不存在,则设置为 ...
- CRLF 漏洞学习和工具使用
原理 CRLF 指的是回车符(CR,ASCII 13,\r,%0d) 和换行符(LF,ASCII 10,\n,%0a),操作系统就是根据这个标识来进行换行的.但是如果对输入过滤不严,就会将恶意语句注入 ...
- Mybatis分页查询total中的坑
写在前面 今天用mybatis进行分页查询,大家应该都用过pageHelper这个插件,但是在计算总的数据数的时候,page.getTotal()总是返回0,要么就是返回pageSize(),今天给大 ...
- AgileConfig 1.6.0 发布 - 支持服务注册与发现
大家好,好久没有输出博文了,一是因为比较忙,另外一个原因是最近主要的精力是在给 AgileConfig 添加一个新的功能:服务注册与发现. 先说说为什么会添加这个功能.我自己的项目是用 Consul ...
- DevC++ 报错[Error] Id returned 1 exit status
DevC++ 报错[Error] Id returned 1 exit status 起因 学校机房的计算机总是二次编译总是报错 报错提示 [Error] Id returned 1 exit sta ...
- 腾讯云OCR服务二次开发
本文记录了对腾讯云OCR服务二次开发的代码和开发过程中遇到的问题.
- DOM的事件传播机制
在dom传播的过程中,一个事件有触发到响应,经历了三个过程: 1,目标的挖洞过程,先有html标签触发事件,然后向子标签一层一层传播,但未执行,,直到找到事件目标为止,这个过程叫做挖洞过程, 2,目标 ...