• 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);
            }
        }
    }
    
    -------------------------------------
    吾生也有涯,而知也无涯。
  • 相关阅读:
    dayfunctools.weps 定义函数装饰器
    python3之concurrent.futures一个多线程多进程的直接对接模块,python3.2有线程池了
    python的类的super()
    django的admin
    python的单例模式
    git指南
    django创建验证码
    Django model对象接口
    Go语言基础
    迭代器&迭代对象&生成器
  • 原文地址:https://www.cnblogs.com/SanjiApollo/p/12822399.html
Copyright © 2020-2023  润新知