Linux学习笔记-Tomcat (安装,部署jspgou商城,nginx session共享与优化)

1 简介

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,它早期的名称为catalina,后来由Apache、Sun 和其他一些公司及个人共同开发而成,并更名为Tomcat。Tomcat 是一个小型的轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选,因为Tomcat 技术先进、性能稳定,成为目前比较流行的Web 应用服务器。Tomcat是应用(java)服务器,它只是一个servlet容器,是Apache的扩展,但它是独立运行的。

因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS、Apache等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。

在Tomcat中,应用程序的部署很简单,你只需将你的WAR放到Tomcat的webapp目录下,Tomcat会自动检测到这个文件,并将其解压。你在浏览器中访问这个应用的Jsp时,通常第一次会很慢,因为Tomcat要将Jsp转化为Servlet文件,然后编译。编译以后,访问将会很快。

Tomcat不仅仅是一个Servlet容器,它也具有传统的Web服务器的功能:处理Html页面。但是与Apache相比,它的处理静态Html的能力就不如Apache.我们可以将Tomcat和Apache集成到一块,让Apache处理静态Html,而Tomcat处理Jsp和Servlet.

优点:

  • 免费的
  • 占用系统资源比较小
  • 跨平台性好,有JAVA环境就行
  • 开源

2 安装

2.1 部署JAVA环境

下载页面 https://download.oracle.com/java/18/latest/jdk-18_linux-x64_bin.tar.gz

# tar xf jdk-7u67-linux-x64.tar.gz
# mv jdk1.7.0_67/ /usr/local
# vim /etc/profile.d/java.sh
    export JAVA_HOME=/usr/local/java
    export PATH=$JAVA_HOME/bin:$PATH
# source  /etc/profile.d/java.sh 
# java -version
    java version "1.7.0_67"
    Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
    Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)

2.2 安装tomcat

下载页面https://tomcat.apache.org/download-80.cgi

# tar xf apache-tomcat-7.0.73.tar.gz -C /usr/local/
# ln -s /usr/local/apache-tomcat-7.0.73/ /usr/local/tomcat
# mv apache-tomcat-7.0.73 /usr/local/tomcat
# cd /usr/local/tomcat/
    bin	        命令:shutdown.sh 关闭tomcat;startup.sh启动tomcat
    lib	        java的库   .jar
    logs	        日志
    temp       临时文件
    work	    运行JSP脚本需要的class文件
    conf	        配置文件
    webapps	DocumentRoot  

3.3 启动tomcat

  • 方法一:
# cd bin/
# ./startup.sh 
    Using CATALINA_BASE:   /usr/local/tomcat
    Using CATALINA_HOME:   /usr/local/tomcat
    Using CATALINA_TMPDIR: /usr/local/tomcat/temp
    Using JRE_HOME:        /usr/local/java
    Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
    Tomcat started.

# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State                          PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN                         957/sshd
tcp6       0      0 :::8080                 :::*                    LISTEN                         1232/java
tcp6       0      0 :::22                   :::*                    LISTEN                         957/sshd
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN                         1232/java
tcp6       0      0 :::8009                 :::*                    LISTEN 
  • 方法二: system-V脚本:
 # vim /etc/init.d/tomcat  
        #!/bin/bash														
        # Init file for Tomcat server daemon								
        JAVA_OPTS='-Xms64m -Xmx128m'						
        JAVA_HOME=/usr/local/java					
        CATALINA_HOME=/usr/local/tomcat					
        export JAVA_OPTS JAVA_HOME CATALINA_HOME  
        exec $CATALINA_HOME/bin/catalina.sh $1

访问 域名:8080端口
发现启动成功
在这里插入图片描述

Tomcat 401 Unauthorized 解决方法

点击右边白框Server Status中出现登录界面与401错误:
在这里插入图片描述

在这里插入图片描述
根据网站提示我们如下操作:

# vim /usr/local/tomcat/conf/tomcat-users.xml

在配置文件内添加用户名和密码

<role rolename="manager-gui"/>
<user username="LZY" password="456" roles="manager-gui"/>

重启tomcat

# /usr/local/tomcat/bin/shutdown.sh
# /usr/local/tomcat/bin/startup.sh

输入设置的账号密码
在这里插入图片描述
登录成功
在这里插入图片描述


  • 问题1 : tomcat启动特别慢(PORT: 8005)
    解决:
    打开$JAVA_HOME/jre/lib/security/java.security这个文件,修改下面的内容:
    securerandom.source=file:/dev/./urandom
    https://blog.csdn.net/u013939884/article/details/72860358/

3 配置文件

# vim /usr/local/tomcat/conf/server.xml

3.1 配置文件详解

port 8005

    <?xml version='1.0' encoding='utf-8'?>
    <Server port="8005" shutdown="SHUTDOWN">
    ##Server中的port监听关闭tomcat的请求,shutdown指定向端口发送的命令串
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />        
      <GlobalNamingResources>
      <Resource name="UserDatabase" auth="Container"
                type="org.apache.catalina.UserDatabase"
                description="User database that can be updated and saved"
                factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>        
    <Service name="Catalina">

port 8080

        <Connector port="8080" protocol="HTTP/1.1"
       ##监听8080端口,负责建立HTTP连接。在通过浏览器访问Tomcat服务器的Web应用时,使用的就是这个连接器
                   connectionTimeout="20000"
                   ##连接超时时间数(毫秒)
                   redirectPort="8443" />
                   ##指定服务器正在处理http请求时收到一个SSL传输请求后重定向的端口号

port 8009

         <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
         ##监听8009端口,负责和apache服务器建立连接。在把Tomcat与apache集成时,需要用到这个连接器            `
        <Engine name="Catalina" defaultHost="localhost">
        ##defaultHost默认连接到哪个主机
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>          
          <Host name="localhost"  appBase="webapps"
          ##指定的主机名或ip,应用程序目录
                unpackWARs="true" autoDeploy="true">
          ##是否自动解压war文件 ,是否自动发布
            <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" />
           ##定义日志文件及格式 %h
          </Host>

        </Engine>
      </Service>
    </Server>

4 多实例

作用:
多实例运行不同的应用(类似虚拟主机)
多实例运行相同的应用(实现负载均衡,支持高并发处理,session问题)

tomcat单机多实例配置

Tomcat:/usr/local/tomcat/{bin,lib}

instance1:   /usr/local/tomcat/instance1/{conf,logs,temp,work,webapps}     8081
instance2:   /usr/local/tomcat/instance2/{conf,logs,temp,work,webapps}     8082
instance3:   /usr/local/tomcat/instance3/{conf,logs,temp,work,webapps}     8083

webapps: /webapps/ROOT
  1. Tomcat安装<略>

  2. 配置多实例目录

  # tree -d -L 3 /usr/local/tomcat/
        /usr/local/tomcat/
        ├── bin
        ├── lib
        ├── instance1
        │   ├── conf
        │   ├── logs
        │   ├── temp
        │   ├── webapps
        │   └── work
        ├── instance2
        │   ├── conf
        │   ├── logs
        │   ├── temp
        │   ├── webapps
        │   └── work
        ├── instance3
            ├── conf
            ├── logs
            ├── temp
            ├── webapps
            └── work
  1. 配置实例server.xml
# vim /usr/local/tomcat/instans1/conf/server.xml
    <!-- <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> -->
    <Server port="8091" shutdown="SHUTDOWN">
    <Connector port="8081" protocol="HTTP/1.1"
                   connectionTimeout="20000"
                   redirectPort="8443" />
    <Host name="localhost"  appBase="/webapps"
                unpackWARs="true" autoDeploy="true">
  1. 写启动脚本
# vim /usr/local/tomcat/instans1/tomcat-instans1.sh
    #!/bin/bash
    #instans1
    export CATALINA_HOME="/usr/local/tomcat"
    export CATALINA_BASE="/usr/local/tomcat/instance1"
    case "$1" in 
    start)
          $CATALINA_HOME/bin/startup.sh;;
    stop)
          $CATALINA_HOME/bin/shutdown.sh;;
    restart)
          $CATALINA_HOME/bin/shutdown.sh
          sleep 3
          $CATALINA_HOME/bin/startup.sh;; 
    esac
  1. 启动测试
# /usr/local/tomcat/instans1/tomcat-instans1.sh start
# /usr/local/tomcat/instans2/tomcat-instans2.sh start
# /usr/local/tomcat/instans2/tomcat-instans3.sh start

# netstat -tanp |grep 80
    tcp        0      0 :::8081                          :::*                        LISTEN      1587/java           
    tcp        0      0 :::8082                          :::*                        LISTEN      1560/java           
    tcp        0      0 :::8083                          :::*                        LISTEN      1752/java           
    tcp        0      0 ::ffff:127.0.0.1:8091       :::*                        LISTEN      1587/java           
    tcp        0      0 ::ffff:127.0.0.1:8092       :::*                        LISTEN      1560/java           
    tcp        0      0 ::ffff:127.0.0.1:8093       :::*                        LISTEN      1752/java                     
    tcp        0      0 :::8009                          :::*                        LISTEN      1560/java           

实战:tomcat部署jspgou商城

Tomcat 部署(jspgou)

在这里插入图片描述

5 nginx + tomcat

6 redis + tomcat 实现session共享

7 基本优化

tomcat调优主要从以下三方面着手:

  1. 内存优化
  2. 并发优化
  3. 内核优化

7.1 JVM内存优化

内存溢出的处理办法(tomcat内存优化):
Tomcat内存优化主要是对 tomcat 启动参数优化,我们可以在 tomcat 的启动脚本 catalina.sh(在此文件第一行开始添加新的设置即可)中设置 JAVA_OPTS 参数

JAVA_OPTS=”-server -Xms1024m -Xmx1024m -XX:PermSize=128m -XX:MaxPermSize=256m -Djava.awt.headless=true”
 -server  以服务端模式启动,启动速度会稍微慢点,但性能会高很多.-Xms    java虚拟机初始化时的初始堆大小;  
  -Xmx   java虚拟机可使用的最大堆大小;  
  -XX:PermSize          内存永久保留区域  
  -XX:MaxPermSize   内存最大永久保留区域(老生代对象能占用内存的最大值)  
  java.awt.headless=true  与图形操作有关,适用于Linux系统
注:要加“m”说明是MB,否则就是KB,在启动tomcat时会报内存不足。
注:永久保存区:
    PermGen space的全称是Permanent Generation space,是指内存的永久保存区域。这一部分用于存放Class和Meta的信息,Class在被 Load的时候被放入PermGen space区域,它和存放Instance的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的APP会LOAD很多CLASS的话,就很可能出现PermGen space错误。这种错误常见在web服务器对JSP进行pre compile的时候。jvm的gc是不会清理PemGen space的,导致内存溢出

  • 常见的内存溢出一般会有下面三种情况:
    1.OutOfMemoryError: Java heap space #堆溢出,若不是程序逻辑bug,可能是项目中引用的jar较多导致
    2.OutOfMemoryError: PermGen space #永久保存区域溢出,通常由于加载了过多的类导致
    3.OutOfMemoryError: unable to create new native thread. #当JVM的heap size设置过大时,thread的创建数量便会减少
    解决:
  1. 调整-Xms -Xmx参数可以解决第一种情况

    64位操作系统对堆内存大小无限制
    堆的大小可以使用 java -Xmx***M -version 命令来测试,***位置填写想设置的内存大小。支持的话会出现jdk的版本号,不支持会报错。

    -Xms -Xmx一般配置成一样比较好比如set JAVA_OPTS= -Xms1024m -Xmx1024m
    注意:java -Xmx***M version 命令来测试的最大堆内存是 -Xmx与 -XX:PermSize的和,比如系统支持最大的jvm堆大小是1.5G,那 -Xmx1024m -XX:PermSize=768M 是无法运行的

  2. 加大-XX:PermSize -XX:MaxPermSize来解决第二种情况

  3. 解决问题3方法如下:
    1).如果程序中有bug,导致创建大量不需要的线程或者线程没有及时回收,那么必须解决这个bug,修改参数是不能解决问题的。

    2).如果程序确实需要大量的线程,现有的设置不能达到要求,那么可以通过修改MaxProcessMemory,JVMMemory,ThreadStackSize这三个因素,来增加能创建的线程数:

     a. MaxProcessMemory 使用64位操作系统
     b. JVMMemory   减少JVMMemory的分配  使用tomcat的catalina.sh这里配置,JAVA_OPTS=-Xms1024m -Xmx1024m -XX:PermSize=256M -XX:MaxNewSize=512m-XX:MaxPermSize=256m
     c. ThreadStackSize  减小单个线程的栈大小 
    

    这个异常问题本质原因是:
    我们创建了太多的线程,而能创建的线程数是有限制的,导致了异常的发生。
    能创建的线程数的具体计算公式如下:
    (MaxProcessMemory - JVMMemory - ReservedOsMemory) / (ThreadStackSize) = Number of threads

    MaxProcessMemory 指的是一个进程的最大内存
    JVMMemory        JVM内存
    ReservedOsMemory  保留的操作系统内存
   ThreadStackSize     线程栈的大小 

在java语言里, 当你创建一个线程的时候,虚拟机会在JVM内存创建一个Thread对象同时创建一个操作系统线程,而这个系统线程的内存用的不是JVMMemory,而是系统中剩下的内存(MaxProcessMemory - JVMMemory - ReservedOsMemory)。由公式得出结论:你给JVM内存越多,那么你能创建的线程越少,越容易发生java.lang.OutOfMemoryError: unable to create new native thread。

7.2 并发优化

线程池设置:

线程池指定Web请求负载的数量,因此,为获得更好的性能这部分应小心处理。可以通过调整连接器属性“maxThreads”完成设置。maxThreads的值应该根据流量的大小,如果值过低,将有没有足够的线程来处理所有的请求,请求将进入等待状态,只有当一个的处理线程释放后才被处理;如果设置的太大,Tomcat的启动将花费更多时间。因此它取决于我们给maxThreads设置一个正确的值。
#vim server.xml

在上述配置中,maxThreads值设定为“500”,这指定可以由服务器处理的并发请求的最大数量。如果没有指定,这个属性的默认值为“200”。任何多出的并发请求将收到“拒绝连接”的错误提示,直到另一个处理请求进程被释放。错误看起来如下,
[ org.apache.tomcat.util.threads.ThreadPool logFull SEVERE: All threads (500) are currently busy, waiting. Increase maxThreads (500) or check the servlet status

最好使用“Tomcat集群”的多个实例。也就是说,如果有“1000”请求,两个Tomcat实例设置“maxThreads= 500”,而不在单Tomcat实例的情况下设置maxThreads=1000。


参数说明:

maxThreads            客户请求最大线程数 
minSpareThreads    Tomcat初始化时创建的 socket 线程数  
maxSpareThreads   Tomcat连接器的最大空闲 socket 线程数  
enableLookups        若设为true, 则支持域名解析,可把 ip 地址解析为主机名  
redirectPort             在需要基于安全通道的场合,把客户请求转发到基于SSL 的 redirectPort 端口  
acceptAccount        监听端口队列最大数,满了之后客户请求会被拒绝(不能小于maxSpareThreads  )  
connectionTimeout  连接超时  
minProcessors         服务器创建时的最小处理线程数  
maxProcessors        服务器同时最大处理线程数  
URIEncoding            URL统一编码

7.3 内核优化

Tomcat运行过程中可能会出现大量ESTABLISHED连接与Time_Wait连接
 # netstat -tan | awk '/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}'
        CLOSE_WAIT         348
        ESTABLISHED        1240
        TIME_WAIT            5621      监控Apache与tomcat之间的链接端口
    #netstat -n | grep 8009 | wc -l
        7198 
  1. 怎样解决time_wait过多的问题:

通过调整内核参数:

  # vim /etc/sysctl.conf #编辑文件,加入以下内容:
            net.ipv4.tcp_syncookies = 1
            net.ipv4.tcp_tw_reuse = 1
            net.ipv4.tcp_tw_recycle = 1
            net.ipv4.tcp_fin_timeout = 30
    # /sbin/sysctl -p #让参数生效。

配置说明:

  net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
    net.ipv4.tcp_tw_reuse = 1    表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
    net.ipv4.tcp_tw_recycle = 1  表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭;
    net.ipv4.tcp_fin_timeout=30修改系統默认的 TIMEOUT 时间。

如果以上配置调优后性能还不理想,可继续修改一下配置:

 # vi /etc/sysctl.conf
    net.ipv4.tcp_keepalive_time = 1200 
    #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。
    net.ipv4.ip_local_port_range = 1024 65000 
    #表示用于向外连接的端口范围。缺省情况下很小:3276861000,改为102465000。
    net.ipv4.tcp_max_syn_backlog = 8192 
    #表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
    net.ipv4.tcp_max_tw_buckets = 5000 
    #表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。

默认为180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于 Squid,效果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。
调优完毕,再压一下看看效果:

  # netstat -tan | awk '/^tcp/ {++y[$NF]} END {for(w in y) print w, y[w]}'
        ESTABLISHED        968
  1. 怎么解决请求结束后依然存在大量ESTABLISHED没有被释放
    初步推断是tomcat服务器回收session时出了问题,这个一般都跟服务器的Timeout设置有联系。
    查看tomcat的配置文件 server.xml
<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8"/>
*****检查配置得出20000毫秒的时候acceptCount="100" 

明显不合理,最大连接数也太小了吧。
所以进一步优化:
connectionTimeout=“20000” 改为 connectionTimeout=“100”
acceptCount="100"改为acceptCount=“5000”

Reference

  1. Tomcat 部署(jspgou)by 陈隶

  2. 课堂笔记

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值