GYM11-Jetty简介

简要的介绍了Jetty的启动流程。对象池是一个很新颖的概念,与线程池有所区别。

创建Server

初始化线程池

使用QueuedThreadpool实现SizedThreadPool

初始化ServerConnector

  • 初始化SecheduledExecutorScheduler
  • 初始化ByteBufferPool (相当于对象池,减少GC),创建对象的效率是很高的,回收很低。不能使用sycronized同步,效率太低,必须使用无锁。
    ArrayByteBufferPool。大小不一定相同,池中保存很多大小不同的对象。
    列外处理:如果社情的ByteBuffer过大或者过小无法在Pool中满足,则可以申请陈宫,但无法归还给Pool

    1
    2
    3
    4
    5
    6
    7
    8
    public ArrayByteBufferPool(int minSize,int increment,int maxSize)
    direct[] =
    indirect[] =
    Queue<ByteBuffer> = new ConcurrentLinkedQueue<>();
    //1取得合适的Bucket 2从Bucket中取得ByteBuffer 3不存在创建
    acquire()
    //1取得合适的Bucket 2清空Buffer 3归还Pool
    release()
  • ConnectionFactory维护
    用于创建链接,比如Accept后,需要创建一个表示链接的对象

  • 获取cpu数量

    1
    cores = Runtime.getRuntime().availableProcessors();
  • 更新acceptor数量

    1
    acceptors = Math.max(1,Math.min(4,cores/8));
  • 创建acceptor线程组

  • 初始化ServerConnectorManger
    继承自
    保存selector线程数量
    1
    Math.min(4,Runtime.getRuntime().availableProcessors()/2)

设置port

关联Server和Connector

Server.start

设置启动状态

启动过程doStart

  • 注册ShutdownMonitor 远程控制接口
  • 获取线程池
  • 设置selector数量
    累计所有connector的需要
  • 计算所需的所有线程数量
    如果大于默认的200则中断程序
  • 维护Bean
    启动QueudThreadPool:创建线程 设置线程的属性 启动线程
    启动WebAppContext
  • 启动Connector
    取得ConnectionFactory
    创建selector线程并启动
    创建Acceptor线程 设置线程名字优先级,将线程放入acceptors 监听端口
    没有Acceptor的情况

    启动完毕

    Http请求

    Accept成功

  • 设置为非阻塞模式
  • 配置Socket
  • 正式处理
    选择可用ManagedSelector线程
    1
    2
    3
    4
    5
    6
    private ManagedSelector chooseSelector(){
    //没有使用原子整数,不必担心因为多线程安全导致的问题
    long s = _selectorIndex++;
    int index = (int) (s % getSelectorCount());
    return _selectors[index];
    }

ManagedSelector处理
提交任务 加入到ConcurrentArrayQueue队列

请求处理

ManagedSelector.run()

1
2
3
4
5
private void runChanges(){
Runnable change;
while((change = _changes.poll())!=null)
runChange(change);
}

select()
处理SelectionKey