zoukankan      html  css  js  c++  java
  • Tomcat知多少 -- 01. 使用LimitLatch限制最大连接数

    1. 概述

    在英文中,latch是“门闩”的意思,这跟锁(lock)所要表达的意思接近,获取到latch则可以进入房间,否则只能等待。而我猜测使用latch而不是用lock可能是想表达“轻量级锁”。

    LimitLatch实例在初始化时会设置一个资源的上限值,在某一时刻,资源使用未达到上限则可以获取锁并消耗一个资源,资源使用达到上限后,随后到来的请求将进入队列,直到有资源得到释放。

    LimitLatch是一个共享性质的锁,这里的共享概念来自于AQS,指的是不同的线程可以同时获取该锁。

    实际上,在JDK的JUC包中,还有一个CountDownLatch存在,两者都是基于AQS框架实现的同步工具类,不过表达的意思却完全不同

    CountDownLatch表示的行为是“所有线程都到达了某一状态后才执行动作”,LimitLatch则更像是Semaphore,用于记录资源的使用。

    如上图所示,LimitLatch类的结构并不复杂,它有四个私有成员变量,作用如下:

    private final Sync sync;                // 同步工具类,Sync是内部类
    private final AtomicLong count;         // 当前使用资源数目
    private volatile long limit;            // 总的可用资源数目
    private volatile boolean released = false;    // 资源是否被全部释放
    

    另外,有两个主要的公有方法:

    • countUpOrAwait()用来获取一个资源,如果当前没有资源可以获取,则进入等待队列;
    • countDown()则用于释放一个资源。

    2. LimitLatch在Tomcat中的作用

    在Tomcat中,LimitLatch类用于限制Tomcat可接受的连接数量。

    2.1 初始化LimitLatch

    在NioEndPoint类中,initializeConnectionLatch()用于创建LimitLatch实例。

    protected LimitLatch initializeConnectionLatch() {
        if (maxConnections==-1) return null;
        if (connectionLimitLatch==null) {
            //  默认的最大连接数是 8 * 1024
            connectionLimitLatch = new LimitLatch(getMaxConnections());
        }
        return connectionLimitLatch;
    }
    

    2.2 在Acceptor中使用LimitLatch限制连接数量

    如下面代码所示,当超过最大连接数时,Acceptor线程将通过自旋锁等待。

    public class Acceptor<U> implements Runnable {
        @Override
        public void run() {
        	...
            //如果达到了最大连接数则等待
    	endpoint.countUpOrAwaitConnection();
    	...
    	// 从serverSocket中接受一个连接
    	socket = endpoint.serverSocketAccept();
    	...
        }
    }
    

    2.3 当socket被销毁时,占有的锁将被释放

    NioEndPoint类的destroySocket()方法中,每当销毁一个socket时就释放一个连接资源。

    @Override
    protected void destroySocket(SocketChannel socket) {
        countDownConnection();    // 实际上调用了LimitLatch的countDown()方法
        try {
            socket.close();
        } catch (IOException ioe) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("endpoint.err.close"), ioe);
            }
        }
    }
    
    -------------------------------------
    吾生也有涯,而知也无涯。
  • 相关阅读:
    海量数据框架变迁——阿里巴巴上市背后的技术力量
    redis集群配置
    【等待优化】sql server CXPACKET 等待 导致 CPU飙高、CPU100%
    (4.39)sql server如何配置分布式事务(MSDTC)
    mysql断电,mysql ibdata 文件损坏(批量利用mysql表空间导入导出)
    mysqlfrm使用
    (1.1)zabbix 基础概念及工作原理整理【转】
    (5.17)mysql集群技术概述(LVS、Keepalived、HAproxy)
    事务日志备份失败错误:Backup detected log corruption in database
    sql server事务日志解析工具(开源,类似apexsql log)
  • 原文地址:https://www.cnblogs.com/SanjiApollo/p/12822399.html
Copyright © 2011-2022 走看看