Tomcat学习之Acceptor
来源:互联网 发布:个人可以注册cn域名吗 编辑:程序博客网 时间:2024/05/19 05:33
http://blog.csdn.net/aesop_wubo/article/details/7627772
简介
Acceptor顾名思义就是接收器,用于接收用户请求,这节主要是分析Acceptor的启动和处理请求!
首先来看Acceptor的类图
从图中可以看出Acceptor实现了Runnable接口,可以作为一个线程启动,且都是Endpoint的内部类。Acceptor有3种实现JIo、Apr、Nio本节不会介绍他们之间的区别,常用的是JIoEndpoint.Acceptor,后面的例子,如果没有做特别说明指的是JIoEndpoint类里面的接收器。
启动
在tomcat启动的时候会启动Endpoint,会调用它的startInternal方法,来看看这个方法做了哪些事:
- public void startInternal() throws Exception {
- if (!running) {
- running = true;
- paused = false;
- // Create worker collection
- if (getExecutor() == null) {
- createExecutor();
- }
- initializeConnectionLatch();
- startAcceptorThreads();
- // Start async timeout thread
- Thread timeoutThread = new Thread(new AsyncTimeout(),
- getName() + "-AsyncTimeout");
- timeoutThread.setPriority(threadPriority);
- timeoutThread.setDaemon(true);
- timeoutThread.start();
- }
- }
- protected LimitLatch initializeConnectionLatch() {
- if (maxConnections==-1) return null;
- if (connectionLimitLatch==null) {
- connectionLimitLatch = new LimitLatch(getMaxConnections());
- }
- return connectionLimitLatch;
- }
2、启动带有接收器的线程
- protected final void startAcceptorThreads() {
- int count = getAcceptorThreadCount();
- acceptors = new Acceptor[count];
- for (int i = 0; i < count; i++) {
- acceptors[i] = createAcceptor();
- Thread t = new Thread(acceptors[i], getName() + "-Acceptor-" + i);
- t.setPriority(getAcceptorThreadPriority());
- t.setDaemon(getDaemon());
- t.start();
- }
- }
(1)getAcceptorThreadCount:在endpoint初始化时,调用AbstractEndpoint.init方法,紧接着调用bind方法,实现是在子类实现的,看看JIOEndpoint类的
bind方法
- public void bind() throws Exception {
- // Initialize thread count defaults for acceptor
- if (acceptorThreadCount == 0) {
- acceptorThreadCount = 1;
- }
- ......
- }
(2)然后创建count个线程,每个线程上都带有一个接收器,并把这些线程设置为后台线程,最后启动这些线程
处理请求
下面看看启动这些线程后,这些线程做了哪些事?
由于org.apache.tomcat.util.net.AbstractEndpoint.Acceptor实现了runnable接口,启动这些线程,也就是运行
org.apache.tomcat.util.net.AbstractEndpoint.Acceptor实现类的run方法,还是以JIO的实现方式为例来看,以下代码省略了很多异常处理
- public void run() {
- while (running) {
- while (paused && running) {
- Thread.sleep(50);
- }
- countUpOrAwaitConnection();
- socket = serverSocketFactory.acceptSocket(serverSocket);
- if (running && !paused && setSocketOptions(socket)) {
- if (!processSocket(socket)) {
- countDownConnection();
- ......
- }
- } else {
- countDownConnection();
- }
- }
- }
1、整体来看是一个while循环,只要服务器没有被关闭,这个while循环会一直运行,当没有请求到来时,这些线程就会sleep
2、获取一个接连,底层调用的是AQS的sync.acquireSharedInterruptibly(1)方法,有可能需要阻塞
3、如果有请求到来就会调用serverSocketFactory.acceptSocket方法,该方法不细讲,底层调用的就是socket.accept()方法
4、方法调用成功就会分享一个线程来处理这次请求,处理请求的代码在processSocket方法中完成,后面会细讲这个方法
5、如果在处理的过程中或者在acceptSocket的过程中有异常都会调用countDownConnection方法减少连接数,如果socket还打开就关闭socket
参考资料
Tomcat性能调校之连接器模块JIO、APR和NIO
- Tomcat学习之Acceptor
- Tomcat学习之Acceptor
- boost::asio学习之[八]acceptor 点滴
- Tomcat Acceptor/Poller
- Tomcat NioEndpoint的Acceptor
- 【muduo网络库学习】之Acceptor类分析
- Tomcat7 Acceptor线程学习
- ACE之Acceptor-Connector框架
- muduo源码分析之Acceptor
- tomcat服务器解析(六)-- Acceptor
- muduo源码学习(20)-Acceptor封装
- ACE之使用Acceptor-Connector框架
- Muduo之Acceptor源码分析笔记
- muduo网络库学习之EventLoop(三):Socket、Acceptor、TcpServer、TcpConnection(连接建立,接收消息)
- org.apache.tomcat.util.net.JIoEndpoint$Acceptor run(转)
- 【erlang 网络编程学习】 分析cowboy acceptor实现
- ACE之旅——Acceptor-Connector框架实例
- Tomcat学习之Tomcat架构
- 心态
- 织梦DedeCms系统未审核文档禁止动态浏览修改方法
- java中string与byte[]的转换
- 通过IIS7 Rewrite完美实现织梦DedeCms 301重定向
- 给织梦DedeCms文章页加上百度、谷歌搜索本篇文章功能
- Tomcat学习之Acceptor
- POJ 2686 - Y2K Accounting Bug
- 在织梦DedeCms的搜索框里显示提示信息
- UEditor学习笔记(二)
- 在Linux上搭建PHP条形码阅读器
- 进入织梦DedeCms数据库删除指定IP的所有评论
- Strategy模式
- 大话数据结构 -- 第九章 排序
- 织梦DedeCms获取文章URL地址的方法