IO(六)

Tomcat是帮助程序员快速建立web应用的助手。

从servlet到Spring MVC 到SpringBoot。tomcat一直离不开。现在虽然嵌入了SpringBoot但是依然需要了解tomcat的使用原理以及改进趋势。

Tomcat的定位是web服务器(servlet容器)。同样类型的还有:Resin,Jetty,WebLogic以及JBoss

为什么现在基本都是tomcat呢?先看两个概念

Web容器

给处于其中的应用程序组件(JSP、Servlet)提供一个环境,使得JSP,Servlet能直接和容器中的环境变量、接口交互而不必关注其他系统问题。主要是由Web服务器来实现,例如Tomcat、WebLogic和Websphere等。该容器提供的接口严格遵守J2EE规范中的Web Application标准。我们把遵守以上标准的Web服务器就叫做J2EE中的Web容器。

EJB(Enterprise Java Bean)容器

企业级Java Bean容器。更具有行业领域特色。他提供给运行在其中的EJB组件各种管理功能。只要满足J2EE规范的EJB放入该容器中,马上就会被容器进行高效率的管理。并且可以通过现成的接口来获得系统级别的服务,例如邮件服务和事务管理等。Web容器和EJB容器在原理上是大体相同的,更多的区别是被隔离的外界环境。Web容器更多的是和基于HTTP的请求打交道。而EJB容器不是,它更多的是和数据库和其他服务打交道。但是它们都是把与外界的交互实现,从而减轻应用程序的负担。例如Servlet不用关心HTTP的细节,直接引用环境变量session、request和response就行;EJB不用关心数据库连接速度、各种事务控制,都直接交给容器来完成。


 

 在Tomcat的官网:Apache Tomcat软件是Java ServletJava服务器页面Java表达式语言Java WebSocket技术的开源实现。有这样的一个介绍。

 

找了一个Tomcat的架构图, 一个Connecter将在某个指定的端口上侦听客户请求,接收浏览器的发过来的 tcp 连接请求,创建一个 Request 和 Response 对象分别用于和请求端交换数据,然后会产生一个线程来处理这个请求并把产生的 Request 和 Response 对象传给处理Engine(Container中的一部分),从Engine出获得响应并返回客户。 
Tomcat中有两个经典的Connector,一个直接侦听来自Browser的HTTP请求,另外一个来自其他的WebServer请求。HTTP/1.1 Connector在端口8080处侦听来自客户Browser的HTTP请求,AJP/1.3 Connector在端口8009处侦听其他Web Server(其他的HTTP服务器)的Servlet/JSP请求。 
Connector 最重要的功能就是接收连接请求然后分配线程让 Container 来处理这个请求,所以这必然是多线程的,多线程的处理是 Connector 设计的核心。

Connector 类本身的作用主要是在其创建时创建ProtocolHandler,然后在生命周期的相关方法中调用了ProtocolHandler 的相关生命周期方法。Connector 的使用方法是通过Connector 标签配置在conf/server.xml 文件中,所以Connector 是在Catalina 的load 方法中根据conf/server.xml 配置文件创建Server对象时创建的。Connector 的生命周期方法是在Service 中调用的

Connector 的创建过程主要是初始化ProtocolHandler。server.xrnl 配置文件中Connector 标签的protocol 属性会设置到Connector 构造函数的参数中,它用于指定ProtocolHandler 的类型

public Connector(String protocol) {
        setProtocol(protocol);
        // Instantiate protocol handler
        try {
            Class<?> clazz = Class.forName(protocolHandlerClassName);
            this.protocolHandler = (ProtocolHandler) clazz.newInstance();
        } catch (Exception e) {
            log.error(sm.getString(
                    "coyoteConnector.protocolHandlerInstantiationFailed"), e);
        }
    }

 

setProtocol方法

/**
     * 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);
            }
        }

    }

 Apr 是Apache Portable Runtime 的缩写,是Apache 提供的一个运行时环境,如果要使用Apr 需要先安装,安装后Tomcat 可以自己检测出来。如果安装了Apr, setProtocol 方法会根据配置的HTTP/1.1 属性对应地将protocolHandlerClassName 设置为org.apache.coyote.http11.Http11.AprProtocol ,如果没有安装Apr,会根据配置的HTTP/1.1 属性将protocoHandlerClassName设置为com..apache.coyote.http11.Http11NioProtocol,然后就会根据protocolHandlerClassName 来创建ProtocolHandler。

 

协议处理器ProtocolHandler

 

posted @ 2020-11-25 15:49  smartcat994  阅读(153)  评论(0编辑  收藏  举报