作者回复: 👍不错的问题。
1)多个Acceptor共享同一个ServerSocketChannel。多个Acceptor线程调用同一个ServerSocketChannel的accept方法,由操作系统保证线程安全
2)直接调用accept方法,编程上简单一些,否则每个Acceptor又要自己维护一个Selector。
3)每个ManagedSelector都有自己的Selector,多个Selector可以并行管理大量的channel,提高并发,连接请求到达时采用Round Robin的方式选择ManagedSelector。
作者回复: 下载这里的源码,直接IDE打开,设断点就行。
https://github.com/jetty-project/embedded-jetty-jsp
作者回复: 1)一个Socket上可以接收多个HTTP请求,每次请求跟一个Hanlder线程是一对一的关系,因为keepalive,一次请求处理完成后Socket不会立即关闭,下一次再来请求,会分配一个新的Hanlder线程。
2)很好的问题,这就是为什么Servlet3.0中引入了异步Servlet的概念,就是说遇到耗时的IO操作,Tomcat的线程会立即返回,当业务线程处理完后,再调用Tomcat的线程将响应发回给浏览器,异步Servlet的原理后面有专门的一篇来介绍。
作者回复: 赶时髦,在应用层面模拟异步编程风格
作者回复: 简单可以这样理解:
1. Acceptor就是不停的调accept函数,接收新的连接
2. Selector不停的调select函数,查询某个Channel上是否有数据可读
3. 同一个浏览器发过来的请求会重用TCP连接,也就是用同一个Channel
Channel是非阻塞的,连接器里维护了这些Channel实例,过了一段时间超时到了channel还没数据到来,表面用户长时间没有操作浏览器,这时Tomcat才关闭这个channel。
作者回复: 👍
作者回复: 第14篇会详细介绍,图文并茂。
作者回复: 说的很对,Tomcat和Jetty相比,Jetty的I/O线程模型更像Netty,后面会讲到Jetty的EatWhatYouKill线程策略,其实就是Netty 4.0中的线程模型。
作者回复: 随着讲解的深入,会涉及这部分内容。Jetty和Tomcat没有本质区别,一般来说Jetty比较小巧,又可以高度裁剪和定制,因此适合放在嵌入式设备等对内存资源比较紧张的场合。而Tomcat比较成熟稳定,对企业级应用支持比较好。
作者回复: 这个模块还只是架构层面的学习,下一个模块会深入到细节。
作者回复: Jetty的优势是小巧,代码量小,比如它只支持非阻塞IO,这意味着把它加载到内存后占用内存空间也小,另外还可以把它裁剪的更小,比如不需要Session支持,可以方便的去掉相应的Hanlder。
作者回复: 补一补相关的基础再来看会好点,22答疑篇希望能帮到你
作者回复:
感觉这些问题在14篇都会得到解答...
作者回复: 反过来想,如果等待连接到达,接收连接、等待数据到达、数据读取和请求处理(等待应用处理完)都在一个线程里,这中间线程可能大部分时间都在”等待“,没有干活,而线程资源是很宝贵的。并且线程阻塞会发生线程上下文切换,浪费CPU资源。
作者回复: 内部类,作为一个类的实现细节,外部不需要知道,通过内部类的方式实现显得整洁干净。
作者回复: 全局线程池和多个隔离的线程池各有优缺点。全局的线程池方便控制线程总数,防止过多的线程导致大量线程切换。隔离的线程池可以控制任务优先级,确保低优先级的任务不会去抢高优先级任务的线程。
作者回复: 这里的Accept事件,只是扔给ManagedSelector一个任务,它拿到这个任务就把Channel注册到自己的Selector上,并不是说ManagedSelector会去accept这个连接,因为连接已经建立了。
作者回复: 连接建立之后还要做些处理,这里onaccept应该建立连接的动作