博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
流量控制闸门——LimitLatch套接字连接数限制器
阅读量:6316 次
发布时间:2019-06-22

本文共 1691 字,大约阅读时间需要 5 分钟。

Tomcat作为web服务器,对于每个客户端的请求将给予处理响应,但对于一台机器而言,访问请求的总流量有高峰期且服务器有物理极限,为了保证web服务器不被冲垮我们需要采取一些措施进行保护预防,需要稍微说明的此处的流量更多的是指套接字的连接数,通过控制套接字连接个数来控制流量。其中一种有效的方法就是采取流量控制,它就像在流量的入口增加了一道闸门,闸门的大小决定了流量的大小,一旦达到最大流量将关闭闸门停止接收直到有空闲通道。
 
创建一个流量控制器没思路?还是考虑下并发框架AQS吧,通过控制同步器的状态即可实现,如果忘了AQS框架相关知识请移步到前面多线程章节,具体思路是先初始化状态值,然后每到来一个socket就将状态加1,每关闭一个socket将状态减1,如此一来一旦状态值小于0则由AQS机制将停止对socket的接收,直到某个socket处理完释放。我们把思路拆成两部分,一是创建一个支持计数的控制器,另一个是将此控制器嵌入处理流程中。
① 控制器,整个过程是根据AQS推荐的自定义同步器的做法进行,但并没有使用AQS自带的状态变量,而是另外引入一个AtomicLong类型的count变量用于计数,其本质是一样的,不必过于纠结。控制器主要通过countUpOrAwait和countDown两个方法实现控制效果。
public class LimitLatch {
    private class Sync extends AbstractQueuedSynchronizer {
        public Sync() {}
        @Override
        protected int tryAcquireShared(int ignored) {
            long newCount = count.incrementAndGet();
            if (newCount > limit) {
                count.decrementAndGet();
                return -1;
            } else {
                return 1;
            }
        }
        @Override
        protected boolean tryReleaseShared(int arg) {
            count.decrementAndGet();
            return true;
        }
    }
    private final Sync sync;
    private final AtomicLong count;
    private volatile long limit;
    public LimitLatch(long limit) {
        this.limit = limit;
        this.count = new AtomicLong(0);
        this.sync = new Sync();
    }
    public void countUpOrAwait() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    public long countDown() {
        sync.releaseShared(0);
        long result = getCount();
        return result;
    }
}
② 流程嵌入控制器,伪代码如下,在接收socket前累加计数器,对socket的数据处理则交由另外的线程,它处理需要一段时间,假如这段时间又有1000个请求socket,则第1000个请求会导致停止程序阻塞,而唤醒的条件是线程池中的工作线程处理完其中一个socket并执行countDown操作。tomcat默认的大小为1000。
LimitLatch limitLatch = new LimitLatch(1000);
创建ServerSocket;
limitLatch.countUpOrAwait();//这里可能阻塞
Socket socket = ServerSocket.accept();

从线程池中获取一个空闲工作线程处理socket,处理完关闭socket并执行limitLatch.countDown();

你可能感兴趣的文章
鸟哥学习笔记---DNS
查看>>
Linux 常用目录管理命令(cd pwd mkdir rmdir)
查看>>
java程序员菜鸟进阶(四)oracle基础详解(四)oracle开启和关闭服务程序——解决安装oracle占用大量内存...
查看>>
Flask_学习笔记_09: Flask中的继承
查看>>
Mahout源码目录说明
查看>>
我的友情链接
查看>>
Java学习日志(17-2-集合框架工具类Arrays及其他特性)
查看>>
HTTP响应头和请求头信息对照表
查看>>
Chrome完美屏蔽优酷广告及黑屏教程
查看>>
一份不错的php面试题(附答案)
查看>>
前端工程资源发布、优化
查看>>
nginx安装(ubuntu14.04)
查看>>
SQLServer2008备份和恢复
查看>>
WinCE 6.0 的编译
查看>>
访问Nginx上的资源时出现403的原因及解决办法
查看>>
大家好,我是蔡某某,刚刚注册的账号,希望大家支持与帮助
查看>>
shell检测输入的IP是否合法
查看>>
30 分钟快速入门 Docker 教程
查看>>
初步计划
查看>>
Ubuntu11.10下编译android源码4.0.3
查看>>