秒杀数据会导致服务器奔溃,你可以借鉴Guarded Suspension模式

有时候我们需要避免突然出现太多的请求而导致服务器奔溃,但同时又需要保证用户的请求不丢失,在这里我们可以借鉴一下Guarded Suspension模式

原理

Guarded Suspension模式原理很简单,当大量访问同时进来时,我们需要将这些请求缓存起来,然后让服务器逐步消化,同时为了保证用户端有反馈,以至于不断的重刷加重服务器的负载,我们可以借鉴Future模式

模拟角色
  • ClientThread:客户端访问模拟
  • ServerThread:服务器处理模拟
  • RequestQueue:发送的消息类
代码

代码很简单,思想也很简单,就是在请求时候加一个缓存,好吧,下面开始看代码吧!

  • RequestQueue:消息类,当消息队列中为空的时,线程会等待,直到有消息才继续获得继续运行
public class RequestQueue {
    private LinkedList queue = new LinkedList();
    public synchronized Request getRequest(){
        while (queue.size() == 0){
            try {
                wait();
            }catch (InterruptedException e){
            }
        }
        return (Request)queue.remove();
    }

    public synchronized void addRequest(Request request){
        queue.add(request);
        notifyAll();
    }
}
  • RequestQueue:模拟发送消息的类,不断的向消息队列中添加消息
public class ClientThread extends Thread {
    private RequestQueue requestQueue;  // 请求队列
    public ClientThread(RequestQueue requestQueue,String name){
        super(name);
        this.requestQueue = requestQueue;
    }

    @Override
    public void run() {
        for(int i = 0;i < 10; i++){
            Request request = new Request("线程号:" + Thread.currentThread().getName() + "   ID:" + i);
            System.out.println("客户端发送请求:"  + request);
            requestQueue.addRequest(request);
            try{
                Thread.sleep(10);
            }catch (InterruptedException e){

            }
            //System.out.println("线程名称是:" + Thread.currentThread().getName());
        }
        System.out.println(Thread.currentThread().getName() + "===================请求结束");
    }
}
  • ServerThread:模拟服务器处理消息,它并不会马上处理消息,而是将消息放入队列中,让服务器依次处理
public class ServerThread extends Thread {
    private RequestQueue requestQueue;
    public ServerThread(RequestQueue requestQueue,String name){
        super(name);
        this.requestQueue = requestQueue;
    }

    @Override
    public void run() {
        while (true){
            final Request request = requestQueue.getRequest(); //得到请求
            try {
                Thread.sleep(100);//模拟处理消息
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("服务器线程:" + Thread.currentThread().getName() + "操控"  + request);
        }
    }
}
总结

上面模拟代码是存在问题的,因为消息没处理完,是不会马上给客户端反馈的,所有客户端会处于一个长期等待的状态,体验非常不好,如果这时候客户在不断刷新客户端,更会加重服务器的负担,所以这个时候就需要添加Future模式,及时给客户端一个反馈,待服务器处理完毕,在反馈真实数据给客户端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值