锁定老帖子 主题:Tomcat 源代码分析之Socket通讯
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
作者 | 正文 | ||||||||||||
发表时间:2012-02-10
最后修改:2012-02-10
Tomcat 源代码分析之Socket通讯此系列文章皆为Tomcat 7.0代码代码分析。
1. Socket通讯:Tomcat对于 Socket的处理方式主要分为以下几种:
2. 模型介绍Connector由ProtocolHandler和一个连接端口组成,ProtocolHandler使用以上介绍的各种方式处理Socket。 根据配置选取不同的ProtocolHandler实现类的代码如下:
/** * 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); } } }
其相应的配置例子如下:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
Connector调用ProtocolHandler对象处理Socket,主要代码在该Connector类的startInternal()里,如下
/** * 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类里,如下:
@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如下:
不同协议处理方式请看这个类的实现: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> 今天就讲到这里了,后续继续把自己已看的东西整理出来。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||||||||||||
返回顶楼 | |||||||||||||
浏览 4249 次