设为首页 收藏本站
查看: 310|回复: 0

[经验分享] Tomcat 源代码分析之Socket通讯

[复制链接]

尚未签到

发表于 2017-1-30 11:45:25 | 显示全部楼层 |阅读模式
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主要用于ApacheHTTP服务器和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.    模型介绍
ConnectorProtocolHandler和一个连接端口组成,ProtocolHandler使用以上介绍的各种方式处理Socket

根据配置选取不同的ProtocolHandler实现类的代码如下:

 

Java代码   DSC0000.png


  • /** 
  •      * Set the Coyote protocol which will be used by the connector. 
  •      * 
  •      * @param protocol The Coyote protocol name 
  •      */  
  •     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);  
  •             }  
  •         }  
  •   
  •     }  

  
 

 

其相应的配置例子如下:

 

Java代码  


  • <Connector port="8080" protocol="HTTP/1.1"  
  •                connectionTimeout="20000"  
  •                redirectPort="8443" />  

  
 

 

Connector调用ProtocolHandler对象处理Socket,主要代码在该Connector类的startInternal()里,如下

 

Java代码  


  • /** 
  •      * Begin processing requests via this Connector. 
  •      * 
  •      * @exception LifecycleException if a fatal startup error occurs 
  •      */  
  •     @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类里,如下:

 

Java代码  


  • @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
不同协议处理方式请看这个类的实现:AprEndpointJIoEndpointNioEndpoint

JIoEndpoint采用BIO方式处理,NioEndpoint采用NIO的方式处理,AprEndpoint调用大量的Poll的大量native方法处理Socket。具体不再一一介绍。

我们最后为这三个组件画出一个简单的模型,如下:

DSC0001.png

3.    TomcatServerServiceConnector之间的关系:
一个Server包含多个Service,而一个Service由多个Connector组成。

一个Server对应一个Servlet容器的实例,而一个Service可以由多个Connector组成,但是这些Connector必须是一个Engine的,Engine代表一台实际的物理或者虚拟机器,因为Tomcat可以实现集群的,配置片段示例如下:

 

Java代码  


  • <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>  

  
 

今天就讲到这里了,后续继续把自己已看的东西整理出来。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-335291-1-1.html 上篇帖子: 转载:Spring + JPA + Hibernate + Tomcat + EHCache 下篇帖子: tomcat PermGen space and Java heap space
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表