Tomcat 源代码分析之Socket通讯
此系列文章皆为Tomcat 7.0代码代码分析。
1. Socket通讯:
Tomcat对于 Socket的处理方式主要分为以下几种:
- BIO方式:采用Java阻塞Socket通讯的方式处理连接。
- NIO方式:之前采用BIO(阻塞方式),现在由于在Java1.4之后引入NIO,提供了NIO的实现。
- APR方式:为了和本地机器更好的集成,有更高的性能,例如一些高级的系统IO功能(sendfile, epoll and OpenSSL),本地操作的处理(shared memory, NT pipes and Unix sockets以及OS Level的功能(random number generation, system status, etc),Tomcat使用JNI调用处理Socket链接。
- AJP和ARP结合的方式。
- AJP方式:通过AJP协议进行通讯 : AJP主要用于Apache的HTTP服务器和Servlet Web容器之间通讯,它是Packet_Oriented的,换句话说,它发送给浏览器(其他Web Server)的数据是Packet(s),得到Servlet 容器的响应也是Packet(s),这里有特殊情况,如果Servlet 容器发送的数据是二进制的,则直接发送给浏览器。此外,AJP还可以重用和Servlet容器之间的Socket连接(Socket Connection),降低创建开销。 具体请看:http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html。
2. 模型介绍
Connector由ProtocolHandler和一个连接端口组成,ProtocolHandler使用以上介绍的各种方式处理Socket。
根据配置选取不同的ProtocolHandler实现类的代码如下:
-
-
-
-
-
- public void setProtocol(String protocol) {
-
- if (AprLifecycleListener.isAprAvailable()) {
- if ("HTTP/1.1".equals(protocol)) {
- setProtocolHandlerClassName
- ("org.apache.coyote.http11.Http11AprProtocol");
- } else if ("AJP/1.3".equals(protocol)) {
- setProtocolHandlerClassName
- ("org.apache.coyote.ajp.AjpAprProtocol");
- } else if (protocol != null) {
- setProtocolHandlerClassName(protocol);
- } else {
- setProtocolHandlerClassName
- ("org.apache.coyote.http11.Http11AprProtocol");
- }
- } else {
- if ("HTTP/1.1".equals(protocol)) {
- setProtocolHandlerClassName
- ("org.apache.coyote.http11.Http11Protocol");
- } else if ("AJP/1.3".equals(protocol)) {
- setProtocolHandlerClassName
- ("org.apache.coyote.ajp.AjpProtocol");
- } else if (protocol != null) {
- setProtocolHandlerClassName(protocol);
- }
- }
-
- }
其相应的配置例子如下:
- <Connector port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443" />
Connector调用ProtocolHandler对象处理Socket,主要代码在该Connector类的startInternal()里,如下
-
-
-
-
-
- @Override
- protected void startInternal() throws LifecycleException {
-
- setState(LifecycleState.STARTING);
-
- try {
- protocolHandler.start();
- } catch (Exception e) {
- String errPrefix = "";
- if(this.service != null) {
- errPrefix += "service.getName(): \"" + this.service.getName() + "\"; ";
- }
-
- throw new LifecycleException
- (errPrefix + " " + sm.getString
- ("coyoteConnector.protocolHandlerStartFailed"), e);
- }
-
- mapperListener.start();
- }
而ProtocolHandler对象会启动一个相应的AbstractEndpoint对象来创建ServerSocket,监听服务相应的端口,并启动线程池处理消息。
ProtocolHandler对象启动AbstractEndpoint对象的代码在org.apache.coyote.AbstractProtocolHandler类里,如下:
- @Override
- public void start() throws Exception {
- if (getLog().isInfoEnabled())
- getLog().info(sm.getString("abstractProtocolHandler.start",
- getName()));
- try {
- endpoint.start();
- } catch (Exception ex) {
- getLog().error(sm.getString("abstractProtocolHandler.startError",
- getName()), ex);
- throw ex;
- }
- }
各种不同的ProtocolHandler对应的AbstractEndpoint如下:
ProtocolHandler
|
AbstractEndpoint
|
AjpAprProtocol
|
AprEndpoint
|
AjpProtocol
|
JIoEndpoint
|
Http11AprProtocol
|
AprEndpoint
|
Http11NioProtocol
|
NioEndpoint
|
Http11Protocol
|
JIoEndpoint
|
不同协议处理方式请看这个类的实现:AprEndpoint,JIoEndpoint,NioEndpoint。
JIoEndpoint采用BIO方式处理,NioEndpoint采用NIO的方式处理,AprEndpoint调用大量的Poll的大量native方法处理Socket。具体不再一一介绍。
我们最后为这三个组件画出一个简单的模型,如下:
3. Tomcat中Server,Service和Connector之间的关系:
一个Server包含多个Service,而一个Service由多个Connector组成。
一个Server对应一个Servlet容器的实例,而一个Service可以由多个Connector组成,但是这些Connector必须是一个Engine的,Engine代表一台实际的物理或者虚拟机器,因为Tomcat可以实现集群的,配置片段示例如下:
- <Service name="Catalina">
- <Connector port="8080" protocol="HTTP/1.1"
- connectionTimeout="20000"
- redirectPort="8443" />
- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
- <Engine …>
- ….
- </Engine>
- </Service>
今天就讲到这里了,后续继续把自己已看的东西整理出来。
分享到:
相关推荐
Tomcat源码剖析 : 整体架构 层层分析 源码解析 架构分析 (Http服务器功能:Socket通信(TCP/IP)、解析Http报文 Servlet容器功能:有很多Servlet(自带系统级Servlet+自定义Servlet),Servlet处理具体的业务逻辑...
tomcat的基础脚本分析 tomcat的源码启动分析 tomcat的web应用启动分析 tomcat的socket分析 tomcat的cocket与容器对接时序分析
NULL 博文链接:https://yjhexy.iteye.com/blog/661491
/********** 本例子是本人参考网上的例子,重新整理和修改的例子,非常简单和具有针对性****/ 1.背景:Flex Socket通信及安全策略,使用flex实现客户端,java实现...需要在java服务端开通843权限策略,具体看例子源码
深入剖析tomcat第三章SocketInputStream源码 * $Header: /home/cvs/jakarta-tomcat-4.0/catalina/src/share/org/apache/catalina/util/StringManager.java,v 1.2 2001/07/22 20:25:14 pier Exp $ * $Revision: 1.2...
从零手写Tomcat【源码】【abl-tomcat-001】【准备步骤,基础Socket通信环境搭建】 文章地址:https://blog.csdn.net/m0_37969197/article/details/123956989 目录地址:...
本项目是一套基于java Swing 框架使用socket技术开发的即时通讯系统,主要针对计算机相关专业的正在做bishe的学生和需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目可以直接作为bishe使用。 ...
8.3 关联spring源代码87 8.4 小结89 第9章 创建Spring MVC之器90 9.1 整体结构介绍90 9.2 HttpServletBean93 9.3 FrameworkServlet95 9.4 DispatcherServlet100 9.5 小结107 第10章 Spring MVC之用108 10.1...
用Java仿写的tomcat的源代码,实现基本功能 1、整个项目启动的时候,扫描含有注解的文件,并放到map中,key为url,value为全类名 2、发送请求,使用socket实现,发送url和参数 3、拿到socket返回的字符串,处理拿到...
Java绘制图片火焰效果,源代码相关注释:前景和背景Image对象、Applet和绘制火焰的效果的Image对象、Applet和绘制火焰的效果的Graphics对象、火焰效果的线程、Applet的高度,图片到图片装载器、绘制火焰效果的X坐标...
一个简单的程序,只是创建一个ServerSocket,监听8080端口,然后解析监听到的socket,简单返回一个静态文本,意在了解tomcat底层是 依据socket通信; private static void await() { ServerSocket serverSocket = ...
NULL 博文链接:https://tyrion.iteye.com/blog/1868654
tiny-tomcat A tiny http server container refer to tomcat. 关于 tiny-tomcat是为了学习j2ee服务器规范而建立的学习项目。我将努力尝试从使用功能的角度出发,同时参考J2ee规范、Tomcat源码、Http规范以及其他网上...
深入理解Tomcat ...** Tomcat组件分析** ** Tomcat生产配置(网络io模型,调优思路)** ** Tomcat是如何启动的?NIO从接受socket到我们的servlet?** ** Tomcat如何打破双亲委派?** 0.简介 Tomcat
包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,...
Java绘制图片火焰效果,源代码相关注释:前景和背景Image对象、Applet和绘制火焰的效果的Image对象、Applet和绘制火焰的效果的Graphics对象、火焰效果的线程、Applet的高度,图片到图片装载器、绘制火焰效果的X坐标...
打开服务器网页与外部服务器网页(例如百度),上一个网页与下页个网页的浏览以及查看源代码的功能,需要的朋友可以下载看看,如果使用上有需要帮助之处,可以发邮件(603803104@qq.com),给予解答。
集合源码分析 开发基础 设计模式 配套代码: 算法与数据结构 配套代码: 配套代码: http DevOps git gitlab maven docker 详细安装过程 框架 Spring Mybatis SpringMVC SpringBoot Spring Security Shiro Swagger-...
java版Web Socket实现的一个简易聊天室,包含源码(导入Myeclipse可直接运行),含 tomcat7.0.69,以及注意事项.doc。代码写得较简洁,一看就懂。