首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

Tomcat 源代码分析之Socket通信

2012-11-13 
Tomcat 源代码分析之Socket通讯?Tomcat?源代码分析之Socket通讯此系列文章皆为Tomcat 7.0代码代码分析。?1.

Tomcat 源代码分析之Socket通讯

?

Tomcat?源代码分析之Socket通讯

此系列文章皆为Tomcat 7.0代码代码分析。

?

1.????Socket通讯:

Tomcat对于?Socket的处理方式主要分为以下几种:

?

  1. ?BIO方式:采用Java阻塞Socket通讯的方式处理连接。
  2. ?NIO方式:之前采用BIO(阻塞方式),现在由于在Java1.4之后引入NIO,提供了NIO的实现。
  3. APR方式:为了和本地机器更好的集成,有更高的性能,例如一些高级的系统IO功能(sendfile, epoll and OpenSSL),本地操作的处理(shared memory, NT pipes and Unix sockets以及OS Level的功能(random number generation, system status, etc),Tomcat使用JNI调用处理Socket链接。
  4. AJP和ARP结合的方式。
  5. 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实现类的代码如下:

?

Java代码??Tomcat 源代码分析之Socket通信
  1. /**?
  2. ?????*?Set?the?Coyote?protocol?which?will?be?used?by?the?connector.?
  3. ?????*?
  4. ?????*?@param?protocol?The?Coyote?protocol?name?
  5. ?????*/??
  6. ????public?void?setProtocol(String?protocol)?{??
  7. ??
  8. ????????if?(AprLifecycleListener.isAprAvailable())?{??
  9. ????????????if?("HTTP/1.1".equals(protocol))?{??
  10. ????????????????setProtocolHandlerClassName??
  11. ????????????????????("org.apache.coyote.http11.Http11AprProtocol");??
  12. ????????????}?else?if?("AJP/1.3".equals(protocol))?{??
  13. ????????????????setProtocolHandlerClassName??
  14. ????????????????????("org.apache.coyote.ajp.AjpAprProtocol");??
  15. ????????????}?else?if?(protocol?!=?null)?{??
  16. ????????????????setProtocolHandlerClassName(protocol);??
  17. ????????????}?else?{??
  18. ????????????????setProtocolHandlerClassName??
  19. ????????????????????("org.apache.coyote.http11.Http11AprProtocol");??
  20. ????????????}??
  21. ????????}?else?{??
  22. ????????????if?("HTTP/1.1".equals(protocol))?{??
  23. ????????????????setProtocolHandlerClassName??
  24. ????????????????????("org.apache.coyote.http11.Http11Protocol");??
  25. ????????????}?else?if?("AJP/1.3".equals(protocol))?{??
  26. ????????????????setProtocolHandlerClassName??
  27. ????????????????????("org.apache.coyote.ajp.AjpProtocol");??
  28. ????????????}?else?if?(protocol?!=?null)?{??
  29. ????????????????setProtocolHandlerClassName(protocol);??
  30. ????????????}??
  31. ????????}??
  32. ??
  33. ????}??

?

?

其相应的配置例子如下:

?

Java代码??Tomcat 源代码分析之Socket通信
  1. <Connector?port="8080"?protocol="HTTP/1.1"??
  2. ???????????????connectionTimeout="20000"??
  3. ???????????????redirectPort="8443"?/>??

?

?

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

?

Java代码??Tomcat 源代码分析之Socket通信
  1. /**?
  2. ?????*?Begin?processing?requests?via?this?Connector.?
  3. ?????*?
  4. ?????*?@exception?LifecycleException?if?a?fatal?startup?error?occurs?
  5. ?????*/??
  6. ????@Override??
  7. ????protected?void?startInternal()?throws?LifecycleException?{??
  8. ??
  9. ????????setState(LifecycleState.STARTING);??
  10. ??
  11. ????????try?{??
  12. ????????????protocolHandler.start();??
  13. ????????}?catch?(Exception?e)?{??
  14. ????????????String?errPrefix?=?"";??
  15. ????????????if(this.service?!=?null)?{??
  16. ????????????????errPrefix?+=?"service.getName():?""?+?this.service.getName()?+?"";?";??
  17. ????????????}??
  18. ??
  19. ????????????throw?new?LifecycleException??
  20. ????????????????(errPrefix?+?"?"?+?sm.getString??
  21. ?????????????????("coyoteConnector.protocolHandlerStartFailed"),?e);??
  22. ????????}??
  23. ??
  24. ????????mapperListener.start();??
  25. }??

?

而ProtocolHandler对象会启动一个相应的AbstractEndpoint对象来创建ServerSocket,监听服务相应的端口,并启动线程池处理消息。

ProtocolHandler对象启动AbstractEndpoint对象的代码在org.apache.coyote.AbstractProtocolHandler类里,如下:

?

Java代码??Tomcat 源代码分析之Socket通信
  1. @Override??
  2. ????public?void?start()?throws?Exception?{??
  3. ????????if?(getLog().isInfoEnabled())??
  4. ????????????getLog().info(sm.getString("abstractProtocolHandler.start",??
  5. ????????????????????getName()));??
  6. ????????try?{??
  7. ????????????endpoint.start();??
  8. ????????}?catch?(Exception?ex)?{??
  9. ????????????getLog().error(sm.getString("abstractProtocolHandler.startError",??
  10. ????????????????????getName()),?ex);??
  11. ????????????throw?ex;??
  12. ????????}??
  13. }??

?

各种不同的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。具体不再一一介绍。

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

Tomcat 源代码分析之Socket通信

3.????Tomcat中Server,Service和Connector之间的关系:

一个Server包含多个Service,而一个Service由多个Connector组成。

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

?

Java代码??Tomcat 源代码分析之Socket通信
  1. <Service?name="Catalina">??
  2. ????????<Connector?port="8080"?protocol="HTTP/1.1"??
  3. ???????????????connectionTimeout="20000"??
  4. ???????????????redirectPort="8443"?/>??
  5. ????????<Connector?port="8009"?protocol="AJP/1.3"?redirectPort="8443"?/>??
  6. ???????<Engine??…>??
  7. ???????????????….??
  8. ???????</Engine>??
  9. </Service>??

?

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

热点排行