使用多线程提高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、异步处理配置

原文地址:https://www.cnblogs.com/maple92/p/11616472.html

时间: 2024-11-06 11:13:47

使用多线程提高REST服务器性能的相关文章

哪些方法能提高香港服务器性能

哪些方法能提高香港服务器性能 1.为硬盘存储部分增加冗余硬盘和阵列控制卡,提供数据冗余,并且大幅度增加系统的IO性能. 2.增加冗余的CPU,使用SMP(对称性多处理器)技术提高系统性能,并且增加了中心处理的冗余. 3.增加冗余网卡,提高网络的IO性能,在某块网卡出现故障时,服务器不会与网络中断连接.4.增加冗余电源模块,提高服务器的供电能力,一旦某个电源模块出现问题时,系统不会因电源中断而导致宕机.5.增加内存,满足操作系统及不断增加的优化和应用程序的需求,提高香港服务器性能.另外,需要对于香

20个Linux服务器性能调优技巧

Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要目的是高效处理非交互式进程,响应时间并不是那么重要,相反,能够长时间处理高负载才是最关键的. Linux高可用服务器集群解决方案让IT系统管理员可以从容应对许多常见的硬件和软件故障,允许多台计算机一起工作,为关键服务正常运行提供保障,系统管理员可以不中断服务执行维护和升级.Linux服务器有各种用途

Tomcat 生产服务器性能优化

虑一下这种场景,你开发了一个应用,它有十分优秀的布局设计,最新的特性以及其它的优秀特点.但是在性能这方面欠缺,不管这个应用如何都会遭到客户拒绝.客户总是期望它们的应用应该有更好的性能.如果你在产品中使用了Tomcat服务器,那么这篇文章就会给你几方面来提升Tomcat服务器的性能.感谢ITWorld article给本文提供资源.经过沉思我已经知道了和早期版本相比最新的Tomcat提供更好的性能和稳定性.所以一直使用最新的Tomcat版本.现在本文使用下面几步来提高Tomcat服务器的性能. 增

[转]20个你不得不知的Linux服务器性能调优技巧

Linux是一种开源操作系统,它支持各种硬件平台,Linux服务器全球知名,它和Windows之间最主要的差异在于,Linux服务器默认情况下一般不提供GUI(图形用户界面),而是命令行界面,它的主要目的是高效处理非交互式进程,响应时间并不是那么重要,相反,能够长时间处理高负载才是最关键的.Linux高可用服务器集群解决方案让IT系统管理员可以从容应对许多常见的硬件和软件故障,允许多台计算机一起工作,为关键服务正常运行提供保障,系统管理员可以不中断服务执行维护和升级. Linux服务器有各种用途

提高服务器性能和并发能力

从哲学上说,消除瓶颈是提高服务器性能和并发能力的唯一途径.如果你能够消除所有的瓶颈,你就能够最大的发挥硬件性能,让系统的性能和并发数到达最佳.采用多线程多核编程,使用事件驱动或异步消息机制,尽量减少阻塞和等待操作(如I/O阻塞.同步等待或计时/超时等).原理:1.多线程多核编程,消除cpu瓶颈.2.采用IOCP或epoll,利用状态监测和通知方式,消除网络I/O阻塞瓶颈.3.采用事件驱动或异步消息机制,可以消除不必要的等待操作.4.如果是Linux,可以采用AIO来消除磁盘I/O阻塞瓶颈.5.在

集群类型以及提高服务器性能的技术概述

一.集群类型: 1.负载均衡集群(LB集群--Load Balancing): 考虑提高服务器容量,是实现伸缩性扩展的主要技术. 当并发请求出现下面的情形时,就要考虑扩展: 1200请求:1s 1500请求:2s 1800请求:10s 扩展类型: Scale up:向上,需要更强大性能的服务器,缺点是:提高的上限是有限的,并且它的性价比较差. Scale out:向外,需要n多台主机. A.LB的软件解决方案: LVS(Linux Virtual Server). Haproxy. Nginx等

修改Linux内核参数提高Nginx服务器并发性能

当linux下Nginx达到并发数很高,TCP TIME_WAIT套接字数量经常达到两.三万,这样服务器很容易被拖死.事实上,我们可以简单的通过修改Linux内核参数,可以减少Nginx服务器 的TIME_WAIT套接字数量,进而提高Nginx服务器并发性能.   vi /etc/sysctl.conf   增加以下几行: net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 1200 net.ipv4.tcp_syncookie

[.net&#160;面向对象程序设计进阶]&#160;(16)&#160;多线程(Multithreading)(一) 使用多线程提高程序性能

[.net 面向对象程序设计进阶] (16) 多线程(Multithreading)(一) 使用多线程提高程序性能 本节导读: 多线程(Multithreading)使我们程序可以同时进行多任务处理,直接提高了程序的执行效率,学习多线程对提高程序运行能力非常必要,本节主要介绍多线程原理及.NET中多线程的应用. 1. 关于多线程 在介绍多线程之前,先了解一下进程. 进程:独立运行的程序称为进程.(比如Windows系统后台程序,也可以称为后台进程) 线程:对于同一个程序分为多个执行流,称为线程.

[.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(三) 利用多线程提高程序性能(下)

[.net 面向对象程序设计进阶] (18) 多线程(Multithreading)(二) 利用多线程提高程序性能(下) 本节导读: 上节说了线程同步中使用线程锁和线程通知的方式来处理资源共享问题,这些是多线程的基本原理. .NET 4.0以后对多线程的实现变得更简单了. 本节主要讨论.NET4.0多线程的新特性——使用Task类创建多线程. 读前必备: A. LINQ使用  [.net 面向对象编程基础] (20) LINQ使用 B. 泛型          [.net 面向对象编程基础] (