Tomcat请求处理(一) -- 服务器端口监听

简介: Tomcat请求处理(一) -- 服务器端口监听 其实tomcat在哪个类中监听请求的代码很容易找到: 在org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run()中的这么一句: Socket socket = serverSocketFactory.acceptSocket(serverSocket); 可是ServerSocketFactory是个抽象类,我还是很想知道整个过程的来龙去脉的。
Tomcat请求处理(一) -- 服务器端口监听
其实tomcat在哪个类中监听请求的代码很容易找到:

在org.apache.tomcat.util.net.JIoEndpoint$Acceptor#run()中的这么一句:

Socket socket = serverSocketFactory.acceptSocket(serverSocket);

可是ServerSocketFactory是个抽象类,我还是很想知道整个过程的来龙去脉的。

那就要还是从初始化开始,当Tomcat的HTTP Connector初始化,会org.apache.coyote.http11.Http11Protocol调用它的init()方法。

在这个init()方法中,又调用了org.apache.tomcat.util.net.JIoEndpoint#init(),代码如下:

Java代码 复制代码  收藏代码img_3d0b4cacdc5d213eebebbe13f1dc9910.gif
  1. public void init() throws Exception {   
  2.     if (initialized)   
  3.         return;   
  4.   
  5.     // acceptor线程的数量   
  6.     if (acceptorThreadCount == 0) {   
  7.         acceptorThreadCount = 1;   
  8.     }   
  9.   
  10.     // 返回DefaultServerSocketFactory类对象做为ServerSocketFactory的实例   
  11.     if (serverSocketFactory == null) {   
  12.         serverSocketFactory = ServerSocketFactory.getDefault();   
  13.     }   
  14.     // 创建ServerSocket   
  15.     if (serverSocket == null) {   
  16.         try {   
  17.             if (address == null) {   
  18.                 serverSocket = serverSocketFactory.createSocket(port, backlog);   
  19.             } else {   
  20.                 serverSocket = serverSocketFactory.createSocket(port, backlog, address);   
  21.             }   
  22.         } catch (BindException be) {   
  23.             if (address == null)   
  24.                 throw new BindException(be.getMessage() + ":" + port);   
  25.             else  
  26.                 throw new BindException(be.getMessage() + " " + address.toString() + ":" + port);   
  27.         }   
  28.     }   
  29.   
  30.     initialized = true;   
  31.   
  32. }  
public void init() throws Exception { if (initialized) return; // acceptor线程的数量 if (acceptorThreadCount == 0) { acceptorThreadCount = 1; } // 返回DefaultServerSocketFactory类对象做为ServerSocketFactory的实例 if (serverSocketFactory == null) { serverSocketFactory = ServerSocketFactory.getDefault(); } // 创建ServerSocket if (serverSocket == null) { try { if (address == null) { serverSocket = serverSocketFactory.createSocket(port, backlog); } else { serverSocket = serverSocketFactory.createSocket(port, backlog, address); } } catch (BindException be) { if (address == null) throw new BindException(be.getMessage() + ":" + port); else throw new BindException(be.getMessage() + " " + address.toString() + ":" + port); } } initialized = true; }

现在已经知道了文章最初提到的serverSocketFactory引用的是一个DefaultServerSocketFactory类的对象。并且在这里创建了一个ServerSocket对象。

当Tomcat初始化完毕执行一些列开启服务的动作时,HTTP Connector也会执行它的start()方法,然后会调用Http11Protocol的start()方法,最后程序会执行到JIoEndpoint#start(),下面来看一下:

Java代码 复制代码  收藏代码img_3d0b4cacdc5d213eebebbe13f1dc9910.gif
  1. public void start() throws Exception {   
  2.     if (!initialized) {   
  3.         init();   
  4.     }   
  5.   
  6.     if (!running) {   
  7.         running = true;   
  8.         paused = false;   
  9.   
  10.         // 先初始化一些Worker   
  11.         if (executor == null) {   
  12.             workers = new WorkerStack(maxThreads);   
  13.         }   
  14.   
  15.         // 开启Acceptor线程,默认只开启一个Acceptor线程,见JIoEndpoint#init()。   
  16.         for (int i = 0; i 
  17.             Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);   
  18.             acceptorThread.setPriority(threadPriority);   
  19.             acceptorThread.setDaemon(daemon);   
  20.             acceptorThread.start();   
  21.         }   
  22.     }   
  23. }  
public void start() throws Exception { if (!initialized) { init(); } if (!running) { running = true; paused = false; // 先初始化一些Worker if (executor == null) { workers = new WorkerStack(maxThreads); } // 开启Acceptor线程,默认只开启一个Acceptor线程,见JIoEndpoint#init()。 for (int i = 0; i
这样,就开启了一个Acceptor线程,接下来看一看这个线程做了什么东西。

Java代码 复制代码  收藏代码img_3d0b4cacdc5d213eebebbe13f1dc9910.gif
  1. public void run() {   
  2.     while (running) {   
  3.   
  4.         while (paused) {   
  5.             try {   
  6.                 Thread.sleep(1000);   
  7.             } catch (InterruptedException e) {   
  8.             }   
  9.         }   
  10.   
  11.         try {   
  12.             // 开始监听端口   
  13.             Socket socket = serverSocketFactory.acceptSocket(serverSocket);   
  14.             // 初始化Socket   
  15.             serverSocketFactory.initSocket(socket);   
  16.             if (!processSocket(socket)) {   
  17.                 try {   
  18.                     socket.close();   
  19.                 } catch (IOException e) {   
  20.                 }   
  21.             }   
  22.         } catch (IOException x) {   
  23.             if (running)   
  24.                 log.error(sm.getString("endpoint.accept.fail"), x);   
  25.         } catch (Throwable t) {   
  26.             log.error(sm.getString("endpoint.accept.fail"), t);   
  27.         }   
  28.     }   
  29.   
  30. }  
public void run() { while (running) { while (paused) { try { Thread.sleep(1000); } catch (InterruptedException e) { } } try { // 开始监听端口 Socket socket = serverSocketFactory.acceptSocket(serverSocket); // 初始化Socket serverSocketFactory.initSocket(socket); if (!processSocket(socket)) { try { socket.close(); } catch (IOException e) { } } } catch (IOException x) { if (running) log.error(sm.getString("endpoint.accept.fail"), x); } catch (Throwable t) { log.error(sm.getString("endpoint.accept.fail"), t); } } }

至此,Tomcat开启了一个端口进行请求的监听。
目录
相关文章
|
4月前
|
监控 Java 应用服务中间件
低并发编程|如何用720个请求让后端服务器瘫痪
本次故障因应用启动时未有效校验核心依赖模块初始化异常,导致后续请求处理中抛出无法捕获的错误,引发线程阻塞,最终耗尽HSF线程池,服务不可用。排查发现类初始化失败且异常未被正确处理,结合线程无限等待问题,确认为依赖初始化异常与流处理中断所致。修复措施包括加强启动校验、捕获Throwable及设置合理超时。总结指出,系统稳定性需从细节入手,防微杜渐,避免连锁故障。
低并发编程|如何用720个请求让后端服务器瘫痪
|
4月前
|
SQL Apache Windows
Windows服务器80端口被占用的全面解决方案
在服务管理器中启动apache2服务,即可正常使用80端口。若系统中还安装了其他微软产品如sql等,也可尝试停止其服务进行测试,但请注意,SQL通常不会使用80端口,因此一般不会受到影响。以上就是关于80端口被system占用的详细解决方法,希望对你有所帮助。
|
2月前
|
网络协议
端口最多只有65535个,为什么服务器能承受百万并发
服务器通过四元组(源IP、源端口、目标IP、目标端口)识别不同TCP连接,每条连接对应独立socket。数据包携带四元组信息,服务端据此查找对应socket进行通信。只要四元组任一元素不同,即视为新连接,可创建独立socket。资源充足时,单进程可支持百万级并发连接,socket与端口非一一对应。
190 10
端口最多只有65535个,为什么服务器能承受百万并发
|
7月前
|
网络协议 安全 应用服务中间件
云服务器怎么开启被关闭的端口?手把手教你开启端口
在使用云服务器时,若发现某些服务无法访问,可能是端口被关闭。本文介绍了端口关闭的原因、检查方法及开启步骤。原因包括初始设置限制、防火墙规则和外部网络策略;可通过netstat或ss命令检查端口状态,用ufw、iptables或firewalld调整防火墙规则。最后提供了解决常见问题的建议,确保端口正常开放并可供外网访问。
1421 9
|
4月前
|
弹性计算 网络协议 安全
【转】如何配置服务器的端口映射?
本文详解端口映射原理及配置方法,涵盖家庭、企业与云环境,包含静态、动态与双向映射类型,并提供常见问题解决方案。
1423 6
|
7月前
|
JSON API 数据安全/隐私保护
使用curl命令在服务器上执行HTTP请求
总的来说,curl是一个非常强大的工具,它可以让你在命令行中发送各种类型的HTTP请求。通过学习和实践,你可以掌握这个工具,使你的工作更加高效。
589 30
|
9月前
|
SQL 关系型数据库 MySQL
云服务器常用端口作用
了解云服务器常用端口的作用有助于高效管理资源、快速定位问题及更好地使用云服务。常见端口包括:21(FTP,文件传输)、22(SSH,远程连接Linux)、25(SMTP,发送邮件)、80(HTTP,网页服务)、110/143(POP3/IMAP,接收邮件)、443(HTTPS,加密网页)、1433(SQL Server)、3306(MySQL)、3389(RDP,远程访问Windows桌面)和8080(代理服务)。
477 2
|
9月前
|
网络协议 Unix 应用服务中间件
|
9月前
|
存储 安全 网络安全
阿里云国际站:阿里云服务器端口配置
悟空云@CloudWuKong阿里云是全球领先的云计算服务提供商,为用户提供弹性计算、数据库、存储、网络安全等一系列云计算服务。在使用阿里云服务器时,合理配置端口非常重要,可以提高服务器安全性和稳定性。
|
JSON JavaScript 前端开发
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
180 22

热门文章

最新文章