• Java开发工程师(Web方向)


    第3章--Tomcat

    Tomcat安装与运行

    Tomcat:目前最常用的基于java的web应用服务器

    本课程中所有的Java代码最终都需要部署到Tomcat中运行

    Tomcat的配置文件是XML的

    互联网公司基本上服务端程序都是跑在类Unix平台

    Tomcat:源代码为Java;为开源软件

    Apache Software Foundation(Apache软件基金会)出品:制作开源软件的非盈利组织;

    安装:

    1. 依赖JDK(源代码为Java)

    2. 下载: http://tomcat.apache.org/

    编译好的二进制包 apache-tomcat-version.tar.gz

    解压:在目录下 tar xzvf filename

    3. 配置环境变量 CATALINA_HOME

    CATALINA是Tomcat的一个组件,该组件会调用用户的Java代码

    配置过程:

    (本机目录/Users/shenglin/Develop/apache-tomcat-8.5.9)

    export CATALINA_HOME=directory     // temporarily config

    4. 验证安装是否成功

    启动Tomcat

    类Unix平台:     $CATALINA_HOME/bin/startup.sh  

                     或 $CATALINA_HOME/bin/catalina.sh start

    使用chrome验证Tomcat是否安装成功

    Tomcat的默认端口是8080

    因此在chrome地址栏里输入127.0.0.1:8080(localhost:8080) 加载后显示的便是tomcat默认主界面

    --> Tomcat安装成功

     

    Tomcat的资源:

    静态资源(HTML页面)

    动态资源(通过代码生成页面 --> Servlet )

    --> e.g.

    case study:饭馆网站

    创建Soymilk.html(卖豆浆页面--静态)

    [html] view plain copy 
      1. <pre name="code" class="html"><html>  
      2.     <body>  
      3.         <h1>Soy Milk</h1>  
      4.     </body>  
      5. </html</pre>  
      6. <pre></pre>  

    卖面条页面--动态:涉及Servlet(跟着做就行,之后详解)

    创建WEB-INF/classes 目录

    在该目录下创建com.netease包

    functionality:卖面条

    创建NoodleServlet.java

    [java] view plain copy
      1. <pre name="code" class="html">package com.netease;  
      2.   
      3. import java.io.IOException;  
      4. import java.io.PrintWriter;  
      5. import java.util.Date;  
      6.   
      7. import javax.servlet.ServletException;  
      8. import javax.servlet.http.HttpServlet;  
      9. import javax.servlet.http.HttpServletRequest;  
      10. import javax.servlet.http.HttpServletResponse;  
      11.   
      12. public class NoodleServlet extends HttpServlet {  
      13.     protected void doGet(HttpServletRequest request, HttpServletResponse   
      14.         response) throws ServletException, IOException {  
      15.         PrintWriter writer = response.getWriter();  
      16.   
      17.         String vegetable = request.getParameter("vegetable");  
      18.   
      19.         if(vegetable == null) {  
      20.             vegetable = "Tomato";  
      21.         }  
      22.   
      23.         writer.println("<html><body>");  
      24.         writer.println("<h1> Noodle with " + vegetable + "</h1>");  
      25.         writer.println("</body></html>");  
      26.     }  
      27. }</pre>  
      28. <pre></pre>  

    在WEB-INF下创建配置文件web.xml

    [html] view plain copy
      1. <?xml version="1.0" encoding="UTF-8"?>  
      2. <web-app version="3.0">  
      3.     <display-name>Restaurant</display-name>  
      4.     <servlet>  
      5.         <servlet-name>noodles</servlet-name>  
      6.         <servlet-class>  
      7.             com.netease.NoodleServlet  
      8.         </servlet-class>  
      9.     </servlet>  
      10.   
      11.     <servlet-mapping>  
      12.         <servlet-name>noodles</servlet-name>  
      13.         <url-pattern>/noodles</url-pattern>  
      14.     </servlet-mapping>  
      15. </web-app>  

     

    创建完成,开始编译class NoodleServlet.java (记得开启Tomcat)

    javac -cp $CATALINA_HOME/lib/servlet-api.jar NoodleServlet.java 

     

    找到apache-tomcat的目录--webapps,将restaurant放入webapps文件夹中

    hierarchy:

     

    在chrome里尝试访问restaurant

    1. 豆浆页面(静态HTML)

    地址栏输入:http://127.0.0.1:8080/Restaurant/Soymilk.html

     

    2. 面条页面(动态Java)

    地址栏输入:http://127.0.0.1:8080/Restaurant/noodles

    (default)

     

    what if: http://127.0.0.1:8080/Restaurant/noodles?vegetable=Pear

    Works as well!

     

    关闭Tomcat

    $CATALINA_HOME/bin/shutdown.sh

    $CATALINA_HOME/bin/catalina.sh stop

    验证Tomcat是否关闭

    Chrome中输入上述地址,This site can't be reached.

     

    Tomcat的组成,架构与配置部署

    Tomcat的组成

    bin/   ---   可执行文件(如startup.sh, shutdown.sh)

    由于Tomcat为Java程序,启动时该怎么加入参数呢?

    JVM启动参数配置 --> 通过配置环境变量JAVA_OPTS的方式: 

    常用参数:

    -server   告诉JVM该应用为服务器应用,使JVM自动做一些优化

    -Xms512m   调整JVM中初始堆内存大小

    -Xmx512m   调整JVM中最大堆内存大小

    e.g.

    之后正常启动Tomcat即可 startup.sh

    conf/   ---   配置文件

    重要的配置文件 server.xml

    <Server>  
        <Service> (可有多个)
            <Connector><pre name="code" class="html"></pre><pre name="code" 
                class="html"><span>   </span>(可有多个)用于接受用户请求</pre><pre 
                name="code" class="html">
            </Connector>  
            <Engine>  一个Service只能用有一个Engine,用于处理Connector接收到的请求  
                <Host>  (可有多个)虚拟主机
                    <Context></pre><pre name="code" class="html"><span>       
                        </span>(可有多个)一个Context其实就是一个Web应用  
                    </Connext>  
                </Host>  
            </Engine>  
        </Service>  
    </Server></pre>  
    <pre></pre>  
    将Context之外包裹着的一层一层称为Container(容器)  
    <p></p>  
    <p>对应的组件实现:</p>  
    <pre></pre>  
    <pre></pre>   

    Connector -- 实现组件为Coyote(实现多种Connector,默认为BIO Connector (阻塞式))

    Container -- 具体实现的组件为Catalina(之前的配置里也指的是这个)

     

    Tomcat组件是如何完成web请求处理的?

    浏览器 --- Connector (从socket上读取数据,并解析数据) --> Container

    浏览器 <--- Connector --- Container (根据Connector传来的数据做决定,生成对应的具体响应)

    浏览器发一个请求,请求被Connector处理(进行socket操作,从socket读取数据,对请求进行解析)

    解析后的请求内容被Container (Catalina)处理,做出对应响应,响应通过Connector传递给浏览器

    (Connector:完成网络相关处理

    Container:执行Web应用的代码)

     

    Connector参数配置:

    port:端口号

    address:配置Connector所监听的网络请求的地址(实际上很多服务器是有不止一个IP的,默认会在所有地址上监听)

    protocol:默认HTTP/1.1

    connectionTimeout:客户端连接超时时间(ms)(若客户端不关闭连接也不发送请求(此时服务器端资源被占))

    acceptCount:系统繁忙时 (无空闲线程存在),新的请求需要排队,配置队列的最大值 (默认为100)。若队长超过100,则请求会被拒绝。

    maxConnections:connector能支持的同时最大连接数 (线程池中线程的数量) (达到最大值时将没有空闲线程处理新请求)

    (弹性) 线程池:如果来一条请求就创建一个线程,事后销毁,会很耗时。所以,事先创建一定数目的线程,当有任务时,从池中取出,用完后再放回池内

    最小空闲线程数:minSpareThreads(当没有任务时,等待任务的线程数,保证有请求时最快处理)

    最大线程数:maxThreads

    e.g.

    服务器端开发NB: 改动configuration文件之前的备份 

    conf目录下: cp server.xml server.xml.bak  // back up

    修改server.xml文件中的conf(需重启Tomcat才会生效)

    线程池:

    可在server.xml中将port改为8181,将minSpareThreads和maxThreads改为1

    在Connector中加入executor="tomcatThreadPool"

     

    (btw, it is acceptable to set minSpareThreads and maxThreads inside Connector directly)

     

    重启Tomcat后效果(使用curl发送请求(和使用chrome的效果是一样的))

    若同时有两个终端发出请求,则第二个终端需要排队等待服务器回应(因为maxThreads=1)

     

    lib/   ---   Tomcat的依赖库

    logs/   ---   默认存放日志的文件夹

    日志的作用:记录Tomcat的运行情况(用于问题定位和调试)

    日志分类:

    系统运行日志:Tomcat的运行信息和状态

    应用日志:用户程序的日志,servlet课程中讲解

    访问日志:记录HTTP请求访问 (Access Log)

    如何配置访问日志:

    server.xml

    directory:存放日志的目录

    prefix:日志文件名前缀

    suffix:日志文件名后缀

    fileDateFormat="yyyy-MM-dd.HH."   时间戳格式(默认yyyy-MM-dd.)

    rotatable="true"  将日志文件切割(依据fileDateFormat指定的时间戳切割)

    pattern:日志格式

    %r:请求行的内容

    %s:status codeHTTP响应的状态码

    %m:method

    %a:client ip

    %t:time

    %b:the number of bytes sent

    %{User-Agent}i :user agent

    ,etc.

    输出的log文件 e.g.

      

    temp/   ---   临时文件夹(web应用执行时产生的临时文件)

    work/   ---   供web应用使用(一般用来放置Tomcat运行过程中产生的一些文件)

    webapps/   ---   默认的应用部署目录

    如何在Tomcat中部署Web应用

    手动部署:将web应用拷贝到webapps/目录下

    常用部署:将web应用做成一个应用包(War包),方便共享。 

    e.g.

    总结

    Tomcat的安装

    Tomcat的启动与停止

    Tomcat的目录结构

    Tomcat的配置文件

    server.xml与Tomcat的架构

    Tomcat的常见配置项

    Connector的配置

    线程池的配置

    日志的配置

    部署Web应用

     

    Tomcat请求处理过程跟踪

    打开并调试server

    停留在acceptSocket处

    向server发送请求

    curl -X POST 'http://localhost:8080/server-example/user/specify?userName=server&userPassword=123'

    server端向前执行

    processSocket()

    SocketWrapper();

    execute(new SocketProcessor());  // another thread (request handling)

    SocketProcessor()

    request.getRequestProcessor();

    getInputBuffer().parseRequestLine():开始解析请求行(找method名,找url,找协议等)

    getInputBuffer().parseHeaders():开始解析请求头(while loop - key_value pairs)

    prepareRequest():处理部分请求解析--准备工作

    adapter.service(request, repsonse):派发请求

    CoyoteAdapter:

    匹配url至对应servlet

    servlet中具体的service:connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);

    得到具体method=req.getMethod(); doPost(req, resp);

    UserServlet.process(request, response); // 用户代码

    userName,userPassword...

    返回一个html页面

    request.finishRequest(); response.finishResponse();

    request.recycle(); response.recycle();

     

     

    What is next?

    手动部署很麻烦 --> Maven来管理Java Web开发过程

     

    Tomcat单元测验:http://www.cnblogs.com/windJcoder/p/5387987.html

    Tomcat单元作业:https://my.oschina.net/hava/blog/735565

  • 相关阅读:
    一元试用一个月的备份服务,把编剧的套路彻底堵死
    微软开源 PowerShell 并支持 Linux 和 OS X
    MySQL Database on Azure 支持 5.7 版本啦!
    python把字典写入excel之一例
    python字典无序?有序?
    字典转化为有序列表
    对xml文件的sax解析(增删改查)之二
    对xml文件的sax解析(增删改查)之一
    XML中CDATA和#PCDATA的区别
    dtd文件中写的引用实体被xml文件引用后无法在浏览器中显示的问题
  • 原文地址:https://www.cnblogs.com/FudgeBear/p/7235819.html
Copyright © 2020-2023  润新知