tomcat 简介


tomcat 简介

                          

官网:Apache Tomcat 10 (10.0.14) - Documentation Index

                     

                            

****************

tomcat 架构

                    

              

                    

组件说明

bootstrap:应用服务器启动入口,通过反射调用创建catalina实例
catalina:解析server.xml创建各个组件,启动、停止应用服务器

server:表示这个servlet容器,整个tomcat只有一个server实例
service:包含一个或者多个connector集合、以及一个由所有connector共享的container组成,
         同一个tomcat(server)实例中可有任意多个service实例,彼此之间相互独立

connector:tomcat链接器,监听读取scoket请求,将其交由container处理
protocolhandler:协议处理器,针对不同协议和i/o方式,提供不同的实现
abstractEndpoint:socket监听端口,监听请求
processor:读取请求数据

mapper:维护容器映射信息,按照映射规则查找容器
mapperListener:容器组件状态变更时,注册或者取消对应的容器信息
coyoteAdapter:使用适配器模式实现connector、mapper、container的解耦,
               coyote是connector的默认实现,coyoteAdapter是coyote的适配器

container:处理客户端请求,并返回响应数据,包括engine、host、context、wrapper
engine:表示servlet容器引擎,是获取目标容器的入口,不直接处理请求
host:servlet引擎的虚拟机,与服务器的网名(如www.baidu.com)有关,客户端可使用这个网名连接服务器
context:表示servletContext,是一个独立的web应用
wrapper:表示servletContext定义的servlet

pipeline:构造容器职责链,一次处理容器接收到的请求
          pipeline维护了一个最基本的valve,位于职责链的末端,负责请求处理和响应输出
valve:位于职责链上,负责处理请求,按顺序依次添加到pipeline,后添加的valve位于pipeline最前面
executor:tomcat组件使用的线程池,实现对客户端请求的并发处理

                        

bootstrap:服务器启动入口,反射调用创建catalina

public final class Bootstrap {
    private static final Log log = LogFactory.getLog(Bootstrap.class);
    private static final Object daemonLock = new Object();
    private static volatile Bootstrap daemon = null;
    private static final File catalinaBaseFile;
    private static final File catalinaHomeFile;
    private static final Pattern PATH_PATTERN = Pattern.compile("(\"[^\"]*\")|(([^,])*)");
    private Object catalinaDaemon = null;
    ClassLoader commonLoader = null;
    ClassLoader catalinaLoader = null;
    ClassLoader sharedLoader = null;

    public Bootstrap() {
    }

    public void init() throws Exception {
        this.initClassLoaders();
        Thread.currentThread().setContextClassLoader(this.catalinaLoader);
        SecurityClassLoad.securityClassLoad(this.catalinaLoader);
        if (log.isDebugEnabled()) {
            log.debug("Loading startup class");
        }

        Class<?> startupClass = this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");
                             //使用类加载器加载Catalina类
        Object startupInstance = startupClass.getConstructor().newInstance();
                             //反射调用创建catalina实例
        if (log.isDebugEnabled()) {
            log.debug("Setting startup class properties");
        }

        String methodName = "setParentClassLoader";
        Class<?>[] paramTypes = new Class[]{Class.forName("java.lang.ClassLoader")};
        Object[] paramValues = new Object[]{this.sharedLoader};
        Method method = startupInstance.getClass().getMethod(methodName, paramTypes);
        method.invoke(startupInstance, paramValues);
        this.catalinaDaemon = startupInstance;
    }

    public static void main(String[] args) {
        synchronized(daemonLock) {
            if (daemon == null) {
                Bootstrap bootstrap = new Bootstrap();

                try {
                    bootstrap.init();     //调用初始化方法,创建catalina实例
                } catch (Throwable var5) {
                    handleThrowable(var5);
                    var5.printStackTrace();
                    return;
                }

                daemon = bootstrap;
            } else {
                Thread.currentThread().setContextClassLoader(daemon.catalinaLoader);
            }
        }
         
        try {  //根据命令参数启动或者关闭应用服务器
            String command = "start";
            if (args.length > 0) {
                command = args[args.length - 1];
            }

            if (command.equals("startd")) {
                args[args.length - 1] = "start";
                daemon.load(args);
                daemon.start();
            } else if (command.equals("stopd")) {
                args[args.length - 1] = "stop";
                daemon.stop();
            } else if (command.equals("start")) {
                daemon.setAwait(true);
                daemon.load(args);
                daemon.start();
                if (null == daemon.getServer()) {
                    System.exit(1);
                }
            } else if (command.equals("stop")) {
                daemon.stopServer(args);
            } else if (command.equals("configtest")) {
                daemon.load(args);
                if (null == daemon.getServer()) {
                    System.exit(1);
                }

                System.exit(0);
            } else {
                log.warn("Bootstrap: command \"" + command + "\" does not exist.");
            }
        } catch (Throwable var7) {
            Throwable t = var7;
            if (var7 instanceof InvocationTargetException && var7.getCause() != null) {
                t = var7.getCause();
            }

            handleThrowable(t);
            t.printStackTrace();
            System.exit(1);
        }

    }

    public void init(String[] arguments) throws Exception {
    public void start() throws Exception {

    public void stop() throws Exception {
    public void stopServer() throws Exception {
    public void stopServer(String[] arguments) throws Exception {

    public void setAwait(boolean await) throws Exception {
    public boolean getAwait() throws Exception {
    public void destroy() {

    public static String getCatalinaHome() {
    public static String getCatalinaBase() {
    public static File getCatalinaHomeFile() {
    public static File getCatalinaBaseFile() {

    static void handleThrowable(Throwable t) {
    static Throwable unwrapInvocationTargetException(Throwable t) {

    protected String replace(String str) {
    protected static String[] getPaths(String value) {

    private void initClassLoaders() {
    private ClassLoader createClassLoader(String name, ClassLoader parent) throws Exception {
    private void load(String[] arguments) throws Exception {
    private Object getServer() throws Exception {

                       

catalina:解析server.xml,创建容器组件

public class Catalina {
    protected static final StringManager sm = StringManager.getManager("org.apache.catalina.startup");
    public static final String SERVER_XML = "conf/server.xml";
    protected boolean await = false;
    protected String configFile = "conf/server.xml";
    protected ClassLoader parentClassLoader = Catalina.class.getClassLoader();
    protected Server server = null;
    protected boolean useShutdownHook = true;
    protected Thread shutdownHook = null;
    protected boolean useNaming = true;
    protected boolean loaded = false;
    protected boolean generateCode = false;
    protected File generatedCodeLocation = null;
    protected String generatedCodeLocationParameter = null;
    protected String generatedCodePackage = "catalinaembedded";
    protected boolean useGeneratedCode = false;
    private static final Log log = LogFactory.getLog(Catalina.class);

    public Catalina() {


    public void setAwait(boolean b) {
    public void setServer(Server server) {
    public void setConfigFile(String file) {
    public void setUseNaming(boolean useNaming) {
    public void setGenerateCode(boolean generateCode) {
    public void setUseShutdownHook(boolean useShutdownHook) {
    public void setUseGeneratedCode(boolean useGeneratedCode) {
    public void setParentClassLoader(ClassLoader parentClassLoader) {
    public void setGeneratedCodePackage(String generatedCodePackage) {
    public void setGeneratedCodeLocation(File generatedCodeLocation) {

    public boolean isAwait() {
    public boolean isUseNaming() {
    public boolean getUseShutdownHook() {
    public boolean getUseGeneratedCode() {

    public Server getServer() {
    public String getConfigFile() {
    public boolean getGenerateCode() {
    public File getGeneratedCodeLocation() {
    public String getGeneratedCodePackage() {
    public ClassLoader getParentClassLoader() {

    protected Digester createStartDigester() { //解析server.xml,返回创建server的digester
        Digester digester = new Digester();
        digester.setValidating(false);
        digester.setRulesValidation(true);
        Map<Class<?>, List<String>> fakeAttributes = new HashMap();
        List<String> objectAttrs = new ArrayList();
        objectAttrs.add("className");
        fakeAttributes.put(Object.class, objectAttrs);
        List<String> contextAttrs = new ArrayList();
        contextAttrs.add("source");
        fakeAttributes.put(StandardContext.class, contextAttrs);
        List<String> connectorAttrs = new ArrayList();
        connectorAttrs.add("portOffset");
        fakeAttributes.put(Connector.class, connectorAttrs);
        digester.setFakeAttributes(fakeAttributes);
        digester.setUseContextClassLoader(true);

        //创建server实例,默认为StandardServer,也可通过className属性指定自定义的server
        digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer", "className");
        digester.addSetProperties("Server");  //设置server属性
        digester.addSetNext("Server", "setServer", "org.apache.catalina.Server");
                                              //调用StandardServer的setServer方法设置server

        //创建全局命名上下文
        digester.addObjectCreate("Server/GlobalNamingResources", "org.apache.catalina.deploy.NamingResourcesImpl");
        digester.addSetProperties("Server/GlobalNamingResources");
        digester.addSetNext("Server/GlobalNamingResources", "setGlobalNamingResources", "org.apache.catalina.deploy.NamingResourcesImpl");

        //添加生命周期监听器
        digester.addRule("Server/Listener", new ListenerCreateRule((String)null, "className"));
        digester.addSetProperties("Server/Listener");
        digester.addSetNext("Server/Listener", "addLifecycleListener", "org.apache.catalina.LifecycleListener");

        //构造service实例
        digester.addObjectCreate("Server/Service", "org.apache.catalina.core.StandardService", "className");
        digester.addSetProperties("Server/Service");
        digester.addSetNext("Server/Service", "addService", "org.apache.catalina.Service");

        //为service实例添加生命周期监听器
        digester.addObjectCreate("Server/Service/Listener", (String)null, "className");
        digester.addSetProperties("Server/Service/Listener");
        digester.addSetNext("Server/Service/Listener", "addLifecycleListener", "org.apache.catalina.LifecycleListener");

        //为service添加executor,添加后catalina共享executor的级别为service,默认不共享
        digester.addObjectCreate("Server/Service/Executor", "org.apache.catalina.core.StandardThreadExecutor", "className");
        digester.addSetProperties("Server/Service/Executor");
        digester.addSetNext("Server/Service/Executor", "addExecutor", "org.apache.catalina.Executor");

        //为service添加connector
        digester.addRule("Server/Service/Connector", new ConnectorCreateRule());
        digester.addSetProperties("Server/Service/Connector", new String[]{"executor", "sslImplementationName", "protocol"});
        digester.addSetNext("Server/Service/Connector", "addConnector", "org.apache.catalina.connector.Connector");
        digester.addRule("Server/Service/Connector", new AddPortOffsetRule());

        //为connector添加虚拟主机ssl配置
        digester.addObjectCreate("Server/Service/Connector/SSLHostConfig", "org.apache.tomcat.util.net.SSLHostConfig");
        digester.addSetProperties("Server/Service/Connector/SSLHostConfig");
        digester.addSetNext("Server/Service/Connector/SSLHostConfig", "addSslHostConfig", "org.apache.tomcat.util.net.SSLHostConfig");
        digester.addRule("Server/Service/Connector/SSLHostConfig/Certificate", new CertificateCreateRule());
        digester.addSetProperties("Server/Service/Connector/SSLHostConfig/Certificate", new String[]{"type"});
        digester.addSetNext("Server/Service/Connector/SSLHostConfig/Certificate", "addCertificate", "org.apache.tomcat.util.net.SSLHostConfigCertificate");
        digester.addObjectCreate("Server/Service/Connector/SSLHostConfig/OpenSSLConf", "org.apache.tomcat.util.net.openssl.OpenSSLConf");
        digester.addSetProperties("Server/Service/Connector/SSLHostConfig/OpenSSLConf");
        digester.addSetNext("Server/Service/Connector/SSLHostConfig/OpenSSLConf", "setOpenSslConf", "org.apache.tomcat.util.net.openssl.OpenSSLConf");
        digester.addObjectCreate("Server/Service/Connector/SSLHostConfig/OpenSSLConf/OpenSSLConfCmd", "org.apache.tomcat.util.net.openssl.OpenSSLConfCmd");
        digester.addSetProperties("Server/Service/Connector/SSLHostConfig/OpenSSLConf/OpenSSLConfCmd");
        digester.addSetNext("Server/Service/Connector/SSLHostConfig/OpenSSLConf/OpenSSLConfCmd", "addCmd", "org.apache.tomcat.util.net.openssl.OpenSSLConfCmd");

        //为connector添加生命周期监听器
        digester.addObjectCreate("Server/Service/Connector/Listener", (String)null, "className");
        digester.addSetProperties("Server/Service/Connector/Listener");
        digester.addSetNext("Server/Service/Connector/Listener", "addLifecycleListener", "org.apache.catalina.LifecycleListener");

        //为connector添加升级协议
        digester.addObjectCreate("Server/Service/Connector/UpgradeProtocol", (String)null, "className");
        digester.addSetProperties("Server/Service/Connector/UpgradeProtocol");
        digester.addSetNext("Server/Service/Connector/UpgradeProtocol", "addUpgradeProtocol", "org.apache.coyote.UpgradeProtocol");

        //添加子元素解析规则
        digester.addRuleSet(new NamingRuleSet("Server/GlobalNamingResources/"));
        digester.addRuleSet(new EngineRuleSet("Server/Service/"));
        digester.addRuleSet(new HostRuleSet("Server/Service/Engine/"));
        digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));
        this.addClusterRuleSet(digester, "Server/Service/Engine/Host/Cluster/");
        digester.addRuleSet(new NamingRuleSet("Server/Service/Engine/Host/Context/"));
        digester.addRule("Server/Service/Engine", new Catalina.SetParentClassLoaderRule(this.parentClassLoader));
        this.addClusterRuleSet(digester, "Server/Service/Engine/Cluster/");
        return digester;
    }

    protected Digester createStopDigester() {  //创建停止服务器的digester
        Digester digester = new Digester();
        digester.setUseContextClassLoader(true);
        digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer", "className");
        digester.addSetProperties("Server");
        digester.addSetNext("Server", "setServer", "org.apache.catalina.Server");
        return digester;
    }


    public void stopServer() {
    public void stopServer(String[] arguments) {

    public void load() {
    public void load(String[] args) {

    public void start() {
    public void stop() {
    public void await() {

    protected void usage() {
    protected File configFile() {
    protected void initNaming() {
    protected void initStreams() {
    protected void generateLoader() {
    protected void setSecurityProtection() {
    protected boolean arguments(String[] args) {
    protected void parseServerXml(boolean start) {
    protected void generateClassFooter(Digester digester) {
    protected void generateClassHeader(Digester digester, boolean start) {

    private void addClusterRuleSet(Digester digester, String prefix) {


*********
内部类:SetParentClassLoaderRule

    final class SetParentClassLoaderRule extends Rule {
        ClassLoader parentClassLoader = null;

        public SetParentClassLoaderRule(ClassLoader parentClassLoader) {
        public void begin(String namespace, String name, Attributes attributes) throws Exception {


*********
内部类:CatalinaShutdownHook

    protected class CatalinaShutdownHook extends Thread {
        protected CatalinaShutdownHook() {
        }

        public void run() {

*********
内部接口:

    public interface ServerXml {

                        

                                 

LifeCycle:组件的生命周期

public interface Lifecycle {
    String BEFORE_INIT_EVENT = "before_init";          //初始化事件
    String AFTER_INIT_EVENT = "after_init";

    String START_EVENT = "start";                      //start事件
    String BEFORE_START_EVENT = "before_start";
    String AFTER_START_EVENT = "after_start";

    String STOP_EVENT = "stop";                        //stop事件
    String BEFORE_STOP_EVENT = "before_stop";
    String AFTER_STOP_EVENT = "after_stop";

    String AFTER_DESTROY_EVENT = "after_destroy";      //destroy事件
    String BEFORE_DESTROY_EVENT = "before_destroy";

    String PERIODIC_EVENT = "periodic";                //周期性事件
    String CONFIGURE_START_EVENT = "configure_start";  //配置开始事件
    String CONFIGURE_STOP_EVENT = "configure_stop";    //配置停止事件

    void addLifecycleListener(LifecycleListener var1);
    LifecycleListener[] findLifecycleListeners();
    void removeLifecycleListener(LifecycleListener var1);

    void init() throws LifecycleException;    //组件初始化
    void start() throws LifecycleException;   //组件启动
    void stop() throws LifecycleException;    //组件停止
    void destroy() throws LifecycleException; //组件销毁

    LifecycleState getState();
    String getStateName();

    public interface SingleUse {
    }
}

                      

Server:servlet容器

public interface Server extends Lifecycle {

    void setPort(int var1);
    void setPortOffset(int var1);
    void setAddress(String var1);
    void setShutdown(String var1);
    void setCatalinaHome(File var1);
    void setCatalina(Catalina var1);
    void setCatalinaBase(File var1);
    void setUtilityThreads(int var1);
    void setParentClassLoader(ClassLoader var1);
    void setGlobalNamingResources(NamingResourcesImpl var1);

    int getPort();
    int getPortOffset();
    int getPortWithOffset();
    int getUtilityThreads();

    String getAddress();
    String getShutdown();
    Catalina getCatalina();
    File getCatalinaBase();
    File getCatalinaHome();
    Object getNamingToken();
    Context getGlobalNamingContext();
    ClassLoader getParentClassLoader();
    ScheduledExecutorService getUtilityExecutor();
    NamingResourcesImpl getGlobalNamingResources();

    void await();
    void addService(Service var1);
    void removeService(Service var1);

    Service[] findServices();
    Service findService(String var1);
}

                       

Service:应用服务

public interface Service extends Lifecycle {

    void setName(String var1);
    void setServer(Server var1);
    void setParentClassLoader(ClassLoader var1);

    String getName();
    Server getServer();
    Mapper getMapper();
    String getDomain();
    ClassLoader getParentClassLoader();

    void addConnector(Connector var1);        //连接器
    Connector[] findConnectors();
    void removeConnector(Connector var1);

    void setContainer(Engine var1);           //应用容器
    Engine getContainer();

    void addExecutor(Executor var1);          //线程池
    Executor[] findExecutors();
    Executor getExecutor(String var1);
    void removeExecutor(Executor var1);
}

                      

Container:应用容器

public interface Container extends Lifecycle {
    String ADD_CHILD_EVENT = "addChild";
    String ADD_VALVE_EVENT = "addValve";
    String REMOVE_CHILD_EVENT = "removeChild";
    String REMOVE_VALVE_EVENT = "removeValve";

    void backgroundProcess();       //后台执行任务

    void addChild(Container var1);
    Container[] findChildren();
    Container findChild(String var1);
    void removeChild(Container var1);

    void addContainerListener(ContainerListener var1);
    void removeContainerListener(ContainerListener var1);
    ContainerListener[] findContainerListeners();

    void addPropertyChangeListener(PropertyChangeListener var1);
    void removePropertyChangeListener(PropertyChangeListener var1);

    void fireContainerEvent(String var1, Object var2);
    void logAccess(Request var1, Response var2, long var3, boolean var5);

    void setRealm(Realm var1);
    void setName(String var1);
    void setCluster(Cluster var1);
    void setParent(Container var1);
    void setStartStopThreads(int var1);
    void setBackgroundProcessorDelay(int var1);
    void setParentClassLoader(ClassLoader var1);

    Log getLogger();
    Realm getRealm();
    String getName();
    String getDomain();
    String getLogName();
    Cluster getCluster();
    Container getParent();
    Pipeline getPipeline();
    File getCatalinaBase();
    File getCatalinaHome();
    AccessLog getAccessLog();
    int getStartStopThreads();
    ObjectName getObjectName();
    String getMBeanKeyProperties();
    int getBackgroundProcessorDelay();
    ClassLoader getParentClassLoader();

    static String getConfigPath(Container container, String resourceName) {
    static Service getService(Container container) {
}

                           

Engine:处理引擎

public interface Engine extends Container {

    void setService(Service var1);
    void setJvmRoute(String var1);
    void setDefaultHost(String var1);

    Service getService();
    String getJvmRoute();
    String getDefaultHost();
}

                      

Host:servlet引擎(engine)虚拟机,客户端可根据网名连接服务器

public interface Host extends Container {
    String ADD_ALIAS_EVENT = "addAlias";
    String REMOVE_ALIAS_EVENT = "removeAlias";

    void setAppBase(String var1);
    void setXmlBase(String var1);
    void setAutoDeploy(boolean var1);
    void setConfigClass(String var1);
    void setCreateDirs(boolean var1);
    void setDeployIgnore(String var1);
    void setDeployOnStartup(boolean var1);
    ExecutorService getStartStopExecutor();
    void setUndeployOldVersions(boolean var1);

    boolean getCreateDirs();
    boolean getAutoDeploy();
    boolean getDeployOnStartup();
    boolean getUndeployOldVersions();

    String getXmlBase();
    String getAppBase();
    File getAppBaseFile();
    String getConfigClass();
    String getDeployIgnore();
    File getConfigBaseFile();
    Pattern getDeployIgnorePattern();

    void addAlias(String var1);
    String[] findAliases();
    void removeAlias(String var1);
}

                       

                           

****************

web 应用加载

                    

web应用加载由standardHost、hostConfig、standardContext、contextConfig、standardWrapper五个类完成

             

            

standardHost:读取server.xml,创建并启动context

如果server.xml的Host标签中存在context子标签,则读取配置创建context实例,
将其添加到host中,在host启动时,启动context实例

<Host name="localhost" appBase="webapps" uppackWARs="true" autoDepoly="true">
     <Context docBase="myApp" path="/myApp" reloadable="true"/>
</Host>
# docBase:web应用根目录地址
# path:web应用根请求地址
# 如果使用端口默认,则项目请求根路径为:http://localhost:8080/myApp

                
hostConfig:自动扫描部署目录,创建context实例并启动
standardContext:web应用初始化及启动,包括创建启动会话管理器、过滤器、监听器等

           

contextConfig:web应用生命周期监听,负责处理各类监听事件

after_init_event:context属性配置
before_start_event:更新context的docBase属性和web目录锁
configure_start_event:创建wrapper、filter、servletContextListener等实例,完成web容器初始化

                

standardWrapper:具体维护servlet实例

通过contextConfig完成web容器初始化后,线雕用standardWrapper.start,组建状态变为started;
对于启动时加载的servlet,调用standardWrapper.load,完成servlet加载

# servlet加载过程:
创建servlet实例,如果添加了JNDI注解,则进行依赖注入;
读取multipartConfig注解配置,用于处理multipart/form-data请求,包括上传文件最大字节数、临时存储路径等;
读取servletConfig配置,添加安全配置
调用init方法,完成servlet初始化

               

                    

****************

web 请求处理

                    

             

               

coyoteAdapter:将connector、mapper、connector联系起来,connector读取数据后,调用coyoteAdapter.service()方法处理请求

mapper:维护请求链接与host、context、wrapper之间的映射

mapperListener:监听host、context、wrapper,在组件启动、停止时注册或者移除映射关系

               

CoyoteAdapter

public class CoyoteAdapter implements Adapter {

    。。。

    public void service(Request req, Response res) throws Exception {

        org.apache.catalina.connector.Request request = (org.apache.catalina.connector.Request)req.getNote(1);
                                              //创建servlet请求
        org.apache.catalina.connector.Response response = (org.apache.catalina.connector.Response)res.getNote(1);
                                              //创建servlet响应
        if (request == null) {
            request = this.connector.createRequest();
            request.setCoyoteRequest(req);
            response = this.connector.createResponse();
            response.setCoyoteResponse(res);
            request.setResponse(response);
            response.setRequest(request);
            req.setNote(1, request);
            res.setNote(1, response);
            req.getParameters().setQueryStringCharset(this.connector.getURICharset());
        }

        if (this.connector.getXpoweredBy()) {
            response.addHeader("X-Powered-By", POWERED_BY);
        }

        boolean async = false;
        boolean postParseSuccess = false;
        req.getRequestProcessor().setWorkerThreadName((String)THREAD_NAME.get());
        boolean var21 = false;

        Host host;
        long time;
        AtomicBoolean error;
        Context context;
        label411: {
            try {
                var21 = true;
                postParseSuccess = this.postParseRequest(req, request, res, response);
                                 //转换请求参数,完成请求映射
                if (postParseSuccess) {
                    request.setAsyncSupported(this.connector.getService().getContainer().getPipeline().isAsyncSupported());
                    this.connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
                                 //得到当前engine的第一个valve并执行,完成客户端请求处理
                }

                if (request.isAsync()) {        //如果是异步请求
                    async = true;
                    ReadListener readListener = req.getReadListener();
                                                //获取请求读取事件监听器
                    if (readListener != null && request.isFinished()) {
                        ClassLoader oldCL = null;

                        try {
                            oldCL = request.getContext().bind(false, (ClassLoader)null);
                            if (req.sendAllDataReadEvent()) {
                                req.getReadListener().onAllDataRead();
                                                //如果请求读取已经结束,触发ReadListener的onAllDataRead方法
                            }
                        } finally {
                            request.getContext().unbind(false, oldCL);
                        }
                    }

                    Throwable throwable = (Throwable)request.getAttribute("javax.servlet.error.exception");
                    if (!request.isAsyncCompleting()) {
                        if (throwable != null) {
                            request.getAsyncContextInternal().setErrorState(throwable, true);
                            var21 = false;
                        } else {
                            var21 = false;
                        }
                    } else {
                        var21 = false;
                    }
                } else {                         //如果是同步请求
                    request.finishRequest();     //flush并关闭请求输入流
                    response.finishResponse();   //flush并关闭响应输出流
                    var21 = false;
                }
                break label411;
            } catch (IOException var26) {
                var21 = false;
            } finally {
                if (var21) {
                    AtomicBoolean error = new AtomicBoolean(false);
                    res.action(ActionCode.IS_ERROR, error);
                    if (request.isAsyncCompleting() && error.get()) {
                        res.action(ActionCode.ASYNC_POST_PROCESS, (Object)null);
                        async = false;
                    }

                    if (!async && postParseSuccess) {
                        Context context = request.getContext();
                        Host host = request.getHost();
                        long time = System.currentTimeMillis() - req.getStartTime();
                        if (context != null) {
                            context.logAccess(request, response, time, false);
                        } else if (response.isError()) {
                            if (host != null) {
                                host.logAccess(request, response, time, false);
                            } else {
                                this.connector.getService().getContainer().logAccess(request, response, time, false);
                            }
                        }
                    }

                    req.getRequestProcessor().setWorkerThreadName((String)null);
                    if (!async) {
                        this.updateWrapperErrorCount(request, response);
                        request.recycle();
                        response.recycle();
                    }

                }
            }

            error = new AtomicBoolean(false);
            res.action(ActionCode.IS_ERROR, error);
            if (request.isAsyncCompleting() && error.get()) {
                res.action(ActionCode.ASYNC_POST_PROCESS, (Object)null);
                async = false;
            }

            if (!async && postParseSuccess) {
                context = request.getContext();
                host = request.getHost();
                time = System.currentTimeMillis() - req.getStartTime();
                if (context != null) {
                    context.logAccess(request, response, time, false);
                } else if (response.isError()) {
                    if (host != null) {
                        host.logAccess(request, response, time, false);
                    } else {
                        this.connector.getService().getContainer().logAccess(request, response, time, false);
                    }
                }
            }

            req.getRequestProcessor().setWorkerThreadName((String)null);
            if (!async) {
                this.updateWrapperErrorCount(request, response);
                request.recycle();
                response.recycle();
            }

            return;
        }

        error = new AtomicBoolean(false);
        res.action(ActionCode.IS_ERROR, error);
        if (request.isAsyncCompleting() && error.get()) {
            res.action(ActionCode.ASYNC_POST_PROCESS, (Object)null);
            async = false;
        }

        if (!async && postParseSuccess) {
            context = request.getContext();
            host = request.getHost();
            time = System.currentTimeMillis() - req.getStartTime();
            if (context != null) {
                context.logAccess(request, response, time, false);
            } else if (response.isError()) {
                if (host != null) {
                    host.logAccess(request, response, time, false);
                } else {
                    this.connector.getService().getContainer().logAccess(request, response, time, false);
                }
            }
        }

        req.getRequestProcessor().setWorkerThreadName((String)null);
        if (!async) {
            this.updateWrapperErrorCount(request, response);
            request.recycle();
            response.recycle();
        }

    }

}

                   

                     

****************

tomcat 网络协议

                    

http协议

# 配置方式
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>

属性说明
port:8080,默认端口为8080
protocol="HTTP/1.1":当前链接器支持的协议为HTTP/1.1
          protocol采用此种配置方式,会自动检测tomcat是否安装了apr,
          如果安装了apr,tomcat使用apr处理http,否则使用nio

protocol="org.apache.coyote.http11.Http11NioProtocol"
         使用nio处理http

connectionTimeout:connector接收到链接后等待的超时时间,单位为毫秒,默认为20s
redirectPost:ssl请求重定向端口,默认为8443

说明:The APR/Native HTTP Connector is deprecated and will be removed in Tomcat 10.1.x onwards

               

ajp协议

# 配置方式
<Connector port="8080" protocol="AJP/1.3" connectionTimeout="20000" redirectPort="8443"/>

属性说明
port:8080,默认端口为8080
protocol="AJP/1.3":当前链接器支持的协议为ajp
          protocol采用此种配置方式,会自动检测tomcat是否安装了apr,
          如果安装了apr,tomcat使用apr处理请求,否则使用nio

protocol="org.apache.coyote.ajp.AjpNioProtocol"
         使用nio处理http

            

http2协议

# UpgradeProtocol提供http2升级支持
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443">
  <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol">
<Connector>

# http2添加ssl配置(openSSL的tls,java8的tls不支持alpn)
<Connector port="8080" protocol="HTTP/1.1" SSLEnabled="true" sslImplementionName="org.apache.tomcat.util.net.openssl.OpenSSLImplementation"  connectionTimeout="20000" redirectPort="8443">
  <UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol">
  <SSLHostConfig>
     <Certificate certificateKeyFile="./key.pem" certificateFile="./cert.pem" certificateChainFile="./chain.pem"/>
  </SSLHostConfig>
</Connector>
protocol如果指定Http11AprProtocol,且tomcat安装了apr,
则不需要指定sslImplementationName,http11AprProtocol默认使用的openssl

                     

                          

****************

tomcat i/o

                    

BIO:同步阻塞读取数据,8.5之后移除BIO

NIO:同步非阻塞io,对应的protocol

org.apache.coyote.ajp.AjpNioProtocol
org.apache.coyote.http11.Http11NioProtocol

              

NIO2(AIO):异步非阻塞io,对应的的协议

org.apache.coyote.ajp.AjpNio2Protocol
org.apache.coyote.http11.Http11Nio2Protocol

                   

APR:一般在与web服务器集成时使用,对应的协议(10.1.x开始禁用,后续会移除)

org.apache.coyote.ajp.AjpAprProtocol
org.apache.coyote.http11.Http11AprProtocol

说明:The APR/Native HTTP Connector is deprecated and will be removed in Tomcat 10.1.x onwards

                        

                      

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值