谈谈jetty8 的io模型
来源:互联网 发布:机电软件 编辑:程序博客网 时间:2024/06/05 18:56
几个重要的概念
- Connector: jetty网络接口的封装,用于监听网络连接
- SelectorManager:底层selector封装,管理网络事件,主要是向底层selector注册感兴趣的网络事件,并从selector中轮询出准备好的事件
- EndPoint:socket的封装,用于底层网络的读写,一旦网络读写准备好,会调用相应的connection的handle方法
- Connection:请求的抽象,比如解析请求的http协议,并调用servlet 容器,依赖EndPoint
见图
几个重要的线程
1) Acceptor线程
- task:org.eclipse.jetty.server.AbstractConnector.Acceptor
- 数量设定:setAcceptors(Math.max(1,(Runtime.getRuntime().availableProcessors()+3)/4));见SelectChannelConnector构造函数
- 触发时机:见SelectChannelConnector(AbstractConnector).doStart()
- 执行线程:QueuedThreadPool中的线程
- 执行逻辑
- 轮询SelectChannelConnector.accept(int acceptorID)
- 以阻塞的方式获取连接请求
- 一旦获得连接,调用ConnectorSelectorManager.register(SocketChannel channel)
- 向SelectorManager$SelectSet 内部的_changes队列中添加该事件(有新的连接)
- 唤醒selector
2)Selector 线程
- task:匿名内部类(new Runnable(){......})
- 数量设定:在jetty.xml中配置
- 触发时机:见SelectChannelConnector$ConnectorSelectorManager(SelectorManager).doStart()
- 执行线程:QueuedThreadPool中的线程
- 执行逻辑
- 轮询SelectorManager$SelectSet.doSelect()
- 从_changes队列获取感兴趣的事件
- 如果是EndPoint类型(读写事件)
- 如果已在selector中注册过,则更新selection key, 否则向selector注册
- 如果是ChannelAndAttachment类型
- 如果关联的SocketChannel已连接,则向selector注册读事件
- 否则注册连接事件
- 如果是SocketChannel类型(连接事件)
- 则向selector注册读事件//key = channel.register(selector,SelectionKey.OP_READ,null);
- 实例化SelectChannelEndPoint //createEndPoint(channel,key);
- 调用SelectChannelEndPoint.schedule()
- 调用SelectChannelConnector$ConnectorSelectorManager.dispatch(Runnable task)将请求扔给QueuedThreadPool(存放在内部jobs队列)
- 如果是ChangeTask类型
- 直接执行
- 如果是Runnable
- 直接丢给QueuedThreadPool
- 运行selector.select获取准备好的SelectionKey,遍历SelectionKey
- 如果key无效则去更新
- 如果有事件发生则调用SelectChannelEndPoint.schedule()
- 调用selector.selectedKeys().clear()
3)Worker线程
- task:匿名内部类(new Runnable(){......})
- 数量设定:在jetty.xml中配置
- 触发时机:QueuedThreadPool.startThread
- 执行线程:QueuedThreadPool中的线程
- 执行逻辑:
- 轮询从jobs队列取job(通常是SelectChannelEndPoint的匿名内部类(new Runnable(){......}))
- 然后执行job.run(通常是SelectChannelEndPoint.handle())
- 调用SelectChannelConnector$SelectChannelHttpConnection(AsyncHttpConnection).handle()
- HttpParser.parseAvailable()(不断调用parseNext读取请求的内容)处理请求
- flush内容
- 如果过程中存在写阻塞,会调用SelectChannelEndPoint.scheduleWrite()或者直接调用updateKey()往_changes队列中添加写事件
线程关系见图
小结(请求处理流程)
- Acceptor线程负责监听连接,一但有连接过来,写入changes队列
- Selector轮询changes队列,将队列中的感兴趣事件往selector中注册,并从selector中查出准备好的网络事件,一旦有准备好的网络事件,通过调用endpoint.schedule()将task丢入线程池的jobs队列
- Work线程会从jobs队列取出任务,然后执行
- 上面的3组线程全来自QueuedThreadPool中的线程
- 谈谈jetty8 的io模型
- 谈谈Java的IO操作
- 谈谈C++里的IO
- 谈谈java的内存模型
- 谈谈Word2Vec的CBOW模型
- eclipseMars4.5+maven3+jetty8的简单使用
- 配置nginx+jetty8的https环境
- winsocket的IO模型
- Linux的IO模型
- 常见的IO模型
- socket的IO模型
- 传统的IO模型
- 谈谈模型
- 谈谈Java中的新的IO特性
- IO模型的五中模型
- winsock IO 模型的笔记
- IO多路复用模型的探讨
- 网络IO模型的分类
- 提取字段的某一部分值
- 风影墙纸,一天看N回。
- 基础总结篇之九:Intent应用详解
- Service生命周期的学习
- 微软MSChart图表插件使用
- 谈谈jetty8 的io模型
- make 中的函数
- HDU2294 Pendant 矩阵应用
- JAVA类的基本应用
- 深入理解JAVA中的栈与堆
- JAVA类的基本应用2
- HDU3732多重背包
- 后缀数组
- 使用scanf函数时应该注意的问题