tomcat 01 开始

本文详细介绍了如何安装Tomcat8.5,以及关键配置文件如binbin目录、catalina.properties等的作用。重点讲解了webapps中的应用部署,Servlet类的doGet方法处理,以及Engine、Host、Context和Wrapper组件的交互。同时涉及了线程安全问题和pipeline/Valve组件的使用。
摘要由CSDN通过智能技术生成

01.安装tomcat 这里的版本是8.5

02.项目(文件系统的角度)
在这里插入图片描述
详细解释:

  • bin
  • bin目录主要是用来存放tomcat的脚本,如startup.sh , shutdown.sh
  • conf
    • catalina.policy: Tomcat安全策略文件,控制JVM相关权限,具体可以参考java. security.Permission
    • catalina.properties : Tomcat Catalina行为控制配置文件,比如Common ClassLoader
    • logging.properties : Tomcat日志配置文件, JDK Logging
    • server.xml : Tomcat Server配置文件
    • GlobalNamingResources :全局JNDI资源
    • context.xml :全局Context配置文件
    • tomcat-users.xml : Tomcat角色配置文件
    • web.xml : Servlet标准的web.xml部署文件,
      • Tomcat默认实现部分配置入内: org.apache.catalina.servlets.DefaultServlet
      • org.apache.jasper.servlet.JspServlet
  • lib 公共类库
  • logs tomcat在运行过程中产生的日志文件
  • webapps
    用来存放应用程序,当tomcat启动时会去加载webapps目录下的应用程序
  • work
    用来存放tomcat在运行时的编译后文件,例如JSP编译后的文件

03.重要的文件是webapps
这里存放的各种应用,重要的是webapps中的WEB-INF文件夹,里面的web.xml
里面写的servlet

举个例子:

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">

  <display-name>Tomcat Host Manager Application</display-name>
  <description>
    A scriptable host management web application for the Tomcat Web Server;
    Manager lets you view, create and remove virtual hosts.
  </description>

  <servlet>
    <servlet-name>HostManager</servlet-name>
    <servlet-class>org.apache.catalina.manager.host.HostManagerServlet</servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</param-value>
    </init-param>
  </servlet>
  <servlet>
    <servlet-name>HTMLHostManager</servlet-name>
    <servlet-class>org.apache.catalina.manager.host.HTMLHostManagerServlet</servlet-class>
    <init-param>
      <param-name>debug</param-name>
      <param-value>2</param-value>
    </init-param>
  </servlet>

04.servlet类的doGet方法:怎么处理doGet方法呢?

先讨论Tomcat的几个组件的事情:四个组件

Engine :直接理解为一个Tomcat  ,一个Engine
Host   :虚拟主机,一个Host表示一个服务器,可以给服务器配置一个域名  
Context:一个Context就是一个应用
Wrapper:servlet包装类

具体说明:
Context:中文是指上下文,其实就是一个Context就是一个应用。一个应用就会有一组servlet,用于响应应用中的不同请求List<servlet>

 <Context path="/zhouyu" docBase="D:\JavaProjects\HelloServlet\target\HelloServlet"></Context>

path: 要访问的路径(URL上的),一般都是项目的名字
docBase:内容放的地方


Host :虚拟主机,类似服务器,有域名可以访问。一个Host,一个服务器,一个服务器上可以运行很多的应用。List<Context >

Host的配置在server.xml看

 <Host name="localhost"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">
        <Context path="/zhouyu" docBase="D:\JavaProjects\HelloServlet\target\HelloServlet-1.0-SNAPSHOT"></Context>
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />
 </Host>
 <Host name="www.fuguang.com"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

 </Host>
 <Host name="www.zuozuozuo.com"  appBase="webapps"
        unpackWARs="true" autoDeploy="true">

 </Host>

在xml文件中,Host的属性
name: 域名
appBase: webapps—对应的就是webapps文件夹
unpackWARs:是不是要解压war包
autoDeploy: 是不是要自动部署


Engine: 一个Engine 就代表一个Tomcat。一个Engine,一个引擎,一个引擎上可以运行很多的服务器。List<Host >

    <Engine name="Catalina" defaultHost="localhost">

defaultHost 表示默认的服务器


Wrapper:servlet的包装类,有属性List<servlet>

问:如果如果面对同一种请求的话,servlet会怎么样?
多个请求共用一个servlet实例。这样会线程不安全。
问:怎么样改进?可以使用加锁的技术,用关键字synchronized,或者接口SingleThreadModel 来进行操作保证线程安全。这样,让一个请求面对一个servlet。
问:产生的后果呢?servlet数量太多,Context容器难以管理。
问:怎么改进?用Wrapper包装servlet,一类servlet是用一个Wrapper来包装。这样。Context容器的属性就会变成List<Wrapper>

线程不安全例子:
在这里插入图片描述
05.pipeline 和 valve 管道和阀门

在这里插入图片描述在这里插入图片描述

在这里插入图片描述





public interface Valve {


 
    public Valve getNext();


    public void setNext(Valve valve);


    public void backgroundProcess();

    public void invoke(Request request, Response response)
        throws IOException, ServletException;


    public boolean isAsyncSupported();
}

 public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        // Select the Host to be used for this Request
        Host host = request.getHost();
        if (host == null) {
            // HTTP 0.9 or HTTP 1.0 request without a host when no default host
            // is defined.
            // Don't overwrite an existing error
            if (!response.isError()) {
                response.sendError(404);
            }
            return;
        }
        if (request.isAsyncSupported()) {
            request.setAsyncSupported(host.getPipeline().isAsyncSupported());
        }

        // Ask this Host to process this request
        host.getPipeline().getFirst().invoke(request, response);
    }
  @Override
    public final void invoke(Request request, Response response)
        throws IOException, ServletException {

        // Initialize local variables we may need
        boolean unavailable = false;
        Throwable throwable = null;
        // This should be a Request attribute...
        long t1=System.currentTimeMillis();
        requestCount.incrementAndGet();
        StandardWrapper wrapper = (StandardWrapper) getContainer();
        Servlet servlet = null;
        Context context = (Context) wrapper.getParent();

        // Check for the application being marked unavailable
        if (!context.getState().isAvailable()) {
            response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                           sm.getString("standardContext.isUnavailable"));
            unavailable = true;
        }

        // Check for the servlet being marked unavailable
        if (!unavailable && wrapper.isUnavailable()) {
            container.getLogger().info(sm.getString("standardWrapper.isUnavailable",
                    wrapper.getName()));
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE)) {
                response.setDateHeader("Retry-After", available);
                response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                        sm.getString("standardWrapper.isUnavailable",
                                wrapper.getName()));
            } else if (available == Long.MAX_VALUE) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND,
                        sm.getString("standardWrapper.notFound",
                                wrapper.getName()));
            }
            unavailable = true;
        }

        // Allocate a servlet instance to process this request
        try {
            if (!unavailable) {
                servlet = wrapper.allocate();
            }
        } catch (UnavailableException e) {
            container.getLogger().error(
                    sm.getString("standardWrapper.allocateException",
                            wrapper.getName()), e);
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE)) {
                response.setDateHeader("Retry-After", available);
                response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                           sm.getString("standardWrapper.isUnavailable",
                                        wrapper.getName()));
            } else if (available == Long.MAX_VALUE) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND,
                           sm.getString("standardWrapper.notFound",
                                        wrapper.getName()));
            }
        } catch (ServletException e) {
            container.getLogger().error(sm.getString("standardWrapper.allocateException",
                             wrapper.getName()), StandardWrapper.getRootCause(e));
            throwable = e;
            exception(request, response, e);
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            container.getLogger().error(sm.getString("standardWrapper.allocateException",
                             wrapper.getName()), e);
            throwable = e;
            exception(request, response, e);
            servlet = null;
        }

        MessageBytes requestPathMB = request.getRequestPathMB();
        DispatcherType dispatcherType = DispatcherType.REQUEST;
        if (request.getDispatcherType()==DispatcherType.ASYNC) {
            dispatcherType = DispatcherType.ASYNC;
        }
        request.setAttribute(Globals.DISPATCHER_TYPE_ATTR,dispatcherType);
        request.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR,
                requestPathMB);
        // Create the filter chain for this request
        ApplicationFilterChain filterChain =
                ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);

        // Call the filter chain for this request
        // NOTE: This also calls the servlet's service() method
        Container container = this.container;
        try {
            if ((servlet != null) && (filterChain != null)) {
                // Swallow output if needed
                if (context.getSwallowOutput()) {
                    try {
                        SystemLogHandler.startCapture();
                        if (request.isAsyncDispatching()) {
                            request.getAsyncContextInternal().doInternalDispatch();
                        } else {
                            filterChain.doFilter(request.getRequest(),
                                    response.getResponse());
                        }
                    } finally {
                        String log = SystemLogHandler.stopCapture();
                        if (log != null && log.length() > 0) {
                            context.getLogger().info(log);
                        }
                    }
                } else {
                    if (request.isAsyncDispatching()) {
                        request.getAsyncContextInternal().doInternalDispatch();
                    } else {
                        filterChain.doFilter
                            (request.getRequest(), response.getResponse());
                    }
                }

            }
        } catch (ClientAbortException | CloseNowException e) {
            if (container.getLogger().isDebugEnabled()) {
                container.getLogger().debug(sm.getString(
                        "standardWrapper.serviceException", wrapper.getName(),
                        context.getName()), e);
            }
            throwable = e;
            exception(request, response, e);
        } catch (IOException e) {
            container.getLogger().error(sm.getString(
                    "standardWrapper.serviceException", wrapper.getName(),
                    context.getName()), e);
            throwable = e;
            exception(request, response, e);
        } catch (UnavailableException e) {
            container.getLogger().error(sm.getString(
                    "standardWrapper.serviceException", wrapper.getName(),
                    context.getName()), e);
            //            throwable = e;
            //            exception(request, response, e);
            wrapper.unavailable(e);
            long available = wrapper.getAvailable();
            if ((available > 0L) && (available < Long.MAX_VALUE)) {
                response.setDateHeader("Retry-After", available);
                response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,
                           sm.getString("standardWrapper.isUnavailable",
                                        wrapper.getName()));
            } else if (available == Long.MAX_VALUE) {
                response.sendError(HttpServletResponse.SC_NOT_FOUND,
                            sm.getString("standardWrapper.notFound",
                                        wrapper.getName()));
            }
            // Do not save exception in 'throwable', because we
            // do not want to do exception(request, response, e) processing
        } catch (ServletException e) {
            Throwable rootCause = StandardWrapper.getRootCause(e);
            if (!(rootCause instanceof ClientAbortException)) {
                container.getLogger().error(sm.getString(
                        "standardWrapper.serviceExceptionRoot",
                        wrapper.getName(), context.getName(), e.getMessage()),
                        rootCause);
            }
            throwable = e;
            exception(request, response, e);
        } catch (Throwable e) {
            ExceptionUtils.handleThrowable(e);
            container.getLogger().error(sm.getString(
                    "standardWrapper.serviceException", wrapper.getName(),
                    context.getName()), e);
            throwable = e;
            exception(request, response, e);
        } finally {
            // Release the filter chain (if any) for this request
            if (filterChain != null) {
                filterChain.release();
            }

            // Deallocate the allocated servlet instance
            try {
                if (servlet != null) {
                    wrapper.deallocate(servlet);
                }
            } catch (Throwable e) {
                ExceptionUtils.handleThrowable(e);
                container.getLogger().error(sm.getString("standardWrapper.deallocateException",
                                 wrapper.getName()), e);
                if (throwable == null) {
                    throwable = e;
                    exception(request, response, e);
                }
            }

            // If this servlet has been marked permanently unavailable,
            // unload it and release this instance
            try {
                if ((servlet != null) &&
                    (wrapper.getAvailable() == Long.MAX_VALUE)) {
                    wrapper.unload();
                }
            } catch (Throwable e) {
                ExceptionUtils.handleThrowable(e);
                container.getLogger().error(sm.getString("standardWrapper.unloadException",
                                 wrapper.getName()), e);
                if (throwable == null) {
                    exception(request, response, e);
                }
            }
            long t2=System.currentTimeMillis();

            long time=t2-t1;
            processingTime += time;
            if( time > maxTime) {
                maxTime=time;
            }
            if( time < minTime) {
                minTime=time;
            }
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值