使用多线程提高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)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这 ...
随机推荐
- javaweb之模糊查询
模糊查询,主要通过sql语句来进行查询 一.dao层 加入模糊查询的方法 package dao; import java.sql.Connection; import java.sql.Prepar ...
- 【weex开发】weex官方源码
公司目前使用版本:weex_sdk:0.10.0 介绍地址:https://bintray.com/alibabaweex/maven/weex_sdk/0.18.0 weex最新版本:weex_sd ...
- IDEA中 mybatis-config、applicationContext.xml、log4j.properties、SpringMVC等文件没有图标标识符号,不是一个xml文件
1. 举例说明 mybatis-config.xml文件不显示图标,识别不出该xml文件 2. 解决办法 1)先点击 File -> Settings-,然后贴入下面代码 (2) 具体操作如下图 ...
- <wx-open-launch-weapp>详解
demo图, h5跳转小程序 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- 微信小程序下拉加载和上拉刷新两种实现方法
方法一:onPullDownRefresh和onReachBottom方法实现小程序下拉加载和上拉刷新 首先要在json文件里设置window属性 设置js里onPullDownRefresh和onR ...
- JAVASE If 单选择、双选择及镶嵌笔记
//单选package com.huang.boke.flowPath;import java.util.Scanner;public class test02 { public static voi ...
- oracle各种用户登录的方式
Oracle有3种用户: system.sys.scott 1.system和sys的差别在与是否能创建数据库2.sys用户登录创建数据库,3.scott是给刚開始学习的人学习的用户.学习者能够用Sc ...
- B. Lord of the Values 思维数学建构 附加 英文翻译
原题链接 Problem - 1523B - Codeforces 题目及部分翻译 While trading on(贸易,利用) his favorite exchange trader Willi ...
- 从零搭建Pytorch模型教程(三)搭建Transformer网络
前言 本文介绍了Transformer的基本流程,分块的两种实现方式,Position Emebdding的几种实现方式,Encoder的实现方式,最后分类的两种方式,以及最重要的数据格式的介绍. ...
- 还在用em strong吗?快来试试 text-emphasis
大家好,我是半夏,一个刚刚开始写文的沙雕程序员.如果喜欢我的文章,可以关注 点赞 加我微信:frontendpicker,一起学习交流前端,成为更优秀的工程师-关注公众号:搞前端的半夏,了解更多前端知 ...