• Tomcat 部署安装及JVM调优~


    Tomcat

    部署Tomcat环境

    环境准备
    	linux:  CentOS 7.3
    	tomcat: 9.0.0.M21
    	jdk:	1.8.0_131
    	ip:     192.168.1.5
    
    tomcat官方下载地址
    http://tomcat.apache.org/download-90.cgi
    
    下载tomcat
    # cd /usr/local/src
    # wget -c http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.0.M21/bin/apache-tomcat-9.0.0.M21.tar.gz
    
    添加tomcat的用户并设置密码
    # useradd  -u 601 tomcat
    # echo "tomcat" | passwd --stdin tomcat
    
    解压tomcat的tar包
    # tar -zxvf apache-tomcat-9.0.0.M21.tar.gz
    
    移动tomcat到目录/usr/local下
    # mv /usr/local/src/apache-tomcat-9.0.0.M21 /usr/local
    
    最佳实践方式,软连接
    # ln -sv /usr/local/apache-tomcat-9.0.0.M21/ /usr/local/tomcat
    
    
    下载JDK的tar包(jdk-8u131-linux-x64.tar.gz)下载到到/usr/local/src目录中
    官方下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
    
    解压JDK的压缩包
    # tar -zxvf jdk-8u131-linux-x64.tar.gz
    
    移动JDK的目录到/usr/local下
    # mv /usr/local/src/jdk1.8.0_131/ /usr/local
    
    最佳实践方式,创建软连接
    # ln -sv /usr/local/jdk1.8.0_131/ /usr/local/jdk
    
    设置java所需要的运行环境
    # cd /etc/profile.d/
    # vim tomcat.sh
    
    添加如下内容
    export JAVA_HOME=/usr/local/jdk
    export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
    export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib/tools.jar
    export TOMCAT_HOME=/usr/local/tomcat
    
    让tomcat的配置脚本生效
    # source /etc/profile.d/tomcat.sh 
    
    监测java的环境
    # java -version
    java version "1.8.0_131"
    Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
    Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
    
    
    
    更改jdk及tomcat目录的属主属组
    # chown -R tomcat:tomcat /usr/local/jdk/
    # chown -R tomcat:tomcat /usr/local/tomcat/
    
    切换到tomcat用户
    # su -l tomcat
    
    启动tomcat服务
    /usr/local/tomcat/bin/startup.sh
    
    tomcat的默认根路径(生产的代码)
    /usr/local/tomcat/webapps
    
    编辑tomcat的访问控制xml配置文件
    # vim /usr/local/tomcat/conf/tomcat-users.xml
    
    在配置文件中添加用户tomcat,并设置密码为1qazxsw2,这样就可以访问manager-gui和admin-gui的管理界面了
    <role rolename="manager-gui" />
    <role rolename="admin-gui" />
    <user username="tomcat" password="1qazxsw2" roles="manager-gui,admin-gui" />
    
    重启tomcat服务
    # /usr/local/tomcat/bin/shutdown.sh 
    # /usr/local/tomcat/bin/startup.sh
    
    这个时候如果是通过其他主机去访问tomcat的manager管理界面(为了安全考虑,默认是只允许主机访问),是无法使用的,我们需要再次修改一丢丢的内容
    # vim /usr/local/tomcat/webapps/manager/META-INF/context.xml
    
    修改allow的内容如下
    allow="127.d+.d+.d+|::1|0:0:0:0:0:0:0:1|d+.d+.d+.d+"
    
    浏览器可以去访问我们的tomcat服务的管理页面了
    http://192.168.1.5:8080/manager/html
    
    
    创建管理tomcat的启动关闭状态脚本
    vim /usr/bin/tomcat.sh
    
    添加如下内容
    #!/bin/bash
    
    TomcatPath=/usr/local/tomcat
    
    usage() {
    	echo "Usage:$0 [start|stop|status|restart]"
    }
    
    
    start_tomcat(){
    	/usr/local/tomcat/bin/startup.sh
    }
    
    stop_tomcat() {
    	TomcatPid=$(ps -aux | grep 'java' | grep 'tomcat' | grep -v 'grep' | awk '{print $2}')
    	kill -9 $TomcatPid
    	sleep 5;
    
    	TomcatStat=$(ps -aux | grep 'java' | grep 'tomcat' | grep -v 'grep' | awk '{print $2}') >> /dev/null
    	if [ -z $TomcatStat ];then
    		echo -e "33[31mtomcat stoping..33[0m"
    	else
    		kill -9 $TomcatStat
    	fi
    
    	cd $TomcatPath
    	rm -rf temp/* 
    	rm  -rf work/*
    
    }
    
    stat_tomcat() {
    	TomcatStat=$(ps -aux | grep 'java' | grep 'tomcat' | grep -v 'grep') >> /dev/null
    	
    	if [ -z $TomcatStat ];then
    		echo -e "33[31mtomcat stop..33[0m"
    	else
    		echo -e "33[32mtomcat running...33[0m"
    	fi
    }
    
    main(){
    	case $1 in
    		start)
    			start_tomcat;;
    		stop)
    			stop_tomcat;;
    		restart)
    			stop_tomcat && start_tomcat;;
    		status)
    			stat_tomcat;;
    		*)
    			usage;;
    	esac
    }
    
    main $1
    
    
    更改脚本的属组属组并添加运行权限
    # chown tomcat:tomcat /usr/bin/tomcat.sh
    # chmod +x /usr/bin/tomcat.sh
    
    测试下写的tomcat的脚本
    # tomcat status
    

    Tomcat的安全管理规范

    1. telnet管理端口保护
    	8005为管理端口,可以通过telnet连接执行SHUTDOWN即可关闭服务,不安全,我们需要换一个其他人未知的端口并调整关闭命令,我们需要做调成
    	# vim /usr/local/tomcat/conf/server.xml
    	<Server port="8561" shutdown="dangerous">
    
    2. ajp连接端口的保护,注释掉ajp
    	# vim /usr/local/tomcat/conf/server.xml
    	 <!--Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /-->
    

    Tomcat使用远程监测工具

    windows下载并安装jdk,使用jconsole就可以监控tomcat的状态
    http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
    
    
    修改tomcat服务端的配置
    # vim /usr/local/tomcat/bin/catalina.sh
    
    在第二行添加如下内容
    CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.1.5"
    

    利用jdk中的jconsole实现远程管理tomcat

    使用jvisualvm监控tomcat

    JVM原理及调优

    1. 什么是jvm?

      虚拟机、字节码、跨平台

    2. jvm结构

    3. JVM运行时的数据区

      • 程序计数器-------->线程私有
      • Java虚拟机栈----->线程私有
      • 本地方法栈-------->线程私有
      • Java堆-------------->线程公用
      • 方法区-------------->线程公用
    4. jVM结构图

    5. jvm内存分配

      栈内存分配

       1. 保存参数、局部变了、中间计算过程和其他数据,退出方法的时候,修改栈顶指针就可以把栈帧中的内容销毁 
       2. 栈的优点:存储速度比堆快,仅次于寄存器,栈数据可以共享
       3. 栈的缺点:存在栈中的数据大小,生存期是在编译时候就确定的,导致其缺乏灵活性
      

      堆内存分配

       1. 堆的优点:动态分配内存大小,生存期不必实现告诉编译器,它是在运行期动态分配的,垃圾回收器会自动收走不再使用的空间区域
       2. 堆的缺点:运行动态分配内存,在分配和销毁时都要占用时间,因此堆效率较低
      
    6. jvm堆配置参数

       1. -Xms初始堆大小
       	默认物理内存的1/64(<1GB)
       2. -Xmx最大堆大小
       	默认物理内存的1/4(<1GB),实际中建议不大于4GB
       3. 一般建议设置-Xms=-Xmx
       	好处是避免每次在gc后,调整堆的大小,减少系统内存分配开销
       4. 整个堆大小=年轻代大小+年老代大小+持久化大小
      
    7. jvm新生代(young generation)

       1. 新生代=1个eden区+2个Survior区 
       2. -Xmn 年轻代大小(1.4or lator)
       	-XX:NewSize,-XX:MaxNewSize(设置年轻代大小(for 1.3/1.4))
       	默认值大小为整个堆的3/8
       3. -XX:NewRatio
       	年轻代(包含Eden和两个Survivor区)与老年代的比值(除去持久化)
       	Xms=Xmx并且设置了Xmn的情况下,该参数不需要设置
       4. -XX:SurviorRatio
       	Eden区与Survivor区的大小比值,设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
       5. 用来存放JVM刚分配的Java对象
      
    8. jvm老年代(tenured greneration)

       1. 老年代=整个堆-年轻代大小-持久化大小
       2. 年轻代中经过垃圾回收没有回收掉的对象被复制到年老代
       3. 老年代存储对象比年轻代年龄大的多,而且不发达对象(缓存)
       4. 新建的对象也有可能直接进入老年代
       	4.1、大对象,可通过启动参数设置-XX:PretenureSizeThreshold=1024(单位为字节,默认为0)来代表超过多大时就不再新生代分配,而是直接在老年代分配
       	4.2、大的数组对象,切数组中无引用外部对象
       5. 老年代大小无配置参数
      
    9. java持久代(perm generation)

       	1. 持久代=整个堆-年轻代大小-老年代大小
       	2. -XX:PermSize -XX:MaxPermSize
       		设置持久代的大小,一般情况推荐把-XX:PermSize设置成XX:MaxPermSize的值为相同的值,因为永久代的调整也会导致堆内存需要触发fgc(Full GC)
       	3. 存放Class,Method元信息,其大小与项目的规模、类、方法的数量有关。一般设置为128M就够用,设置原则是预留30%的空间
       	4. 永久代的回收方式
       		4.1、常量池的常量,无用的类信息,常量的回收很简单,没有引用的就可以被回收
       		4.2、对无用的类进行回收,必须保证3点:
       			类的所有实例都已经被回收
       			加载类的ClassLoader已经被回收
       			类对象的Class对象没有被引用(既没有通过反射引用该类的方法)
      
    10. jvm内存垃圾收集算法

      	1. 引用计数器
      		每个对象有一个引用计数器,新增一个引用时计数加1,引用释放时计数减1,技术为0时可以回收。此方法简单,无法解决对象相互循环引用的问题,还有一个问题是如何解决精准计数
      	2. 根搜索法
      		从GC Roots开始向下搜搜,搜索所走过的路径成为引用链,当一个对象到GC Roots对任何引用链相连时,则证明此对象不可用的,不可达对象
      		在Java语言中,GC Roots包含:
      		虚拟机栈中引用对象
      		方法区中类静态属性实时引用的对象
      		方法区中常量引用的对象
      		本地方法栈中JNI引用的对象
      	3. 复制算法(Copying)
      		复制算法采用从根结合扫描,并将存货对象复制到一块新的,没有使用过的空间中,这种算法当控件存货的对象比较少时,极为高效,但是带来的成本是需要一块内存交换空间用于进行对象的移动
      			注意:
      				此算法用于新生代内存回收,从E区回收到S0或者S1
      	4. 标记清除算法(Mark-Sweep)
      		标记-清除算法采用从根集合进行扫描,对存货的对象标记,标记完毕后,在扫描整个空间中未被标记的对象,进行回收,标记清楚算法不需要进行对象的移动,并且仅对不存货的对象进行处理,在存货对象比较多的情况下极为高效,但由于标记-清除算法会受不存活的对象,因此会造成内存碎片(适用于old区域)
      	5. 标记压缩压缩算法(Mark-Compac)
      		标记-整理算法采用标记-清除算法一样的方法进行对象的标记,但是在清除的时不同,在回收不存活的对象占用的空间后,会将所有的存活对象往左端的空间移动,并更新对应的指针,因此成本高,但是却解决了内存碎片的问题(old区域)
      
    11. 名词解释

      	1. 串行回收
      		GC单线程内存回收,会暂停所有用户线程
      	2. 并行回收
      		手机是指多个GC线程并行工作,蛋姿势用户线程是暂停的,所以,Serial是串行的,Parallel收集是并行的,而CMS手机是并发的
      	3. 并发回收
      		指用户线程与GC线程同时执行(不一定是并行,可能是交替,蛋总体上是在同时执行的),不需要停顿用户线程(其实在CMS中用户线程还是需要停顿的,只是非常的短暂,GC线程是在另一个CPU上执行) 
      
    12. CMS(并发标记清除)回收器

      	1. 标记-清除算法
      		同时它又是一个使用多线程并发回收的垃圾回收期
      	2. -XX:ParallelCMSThreads
      		手工设置CMS的线程数量,CMS默认启动的线程数为(ParallelCGThread+3)/4
      	3. -XX:+UseConcMarkSweepCG开启
      		使用过ParNew+CMS+Serial Old的收集器组合进行内存回收,Serial Old作为CMS出现"Concurrent Mode Failure"失败后的后背收集器使用
      	4. -XX:CMSInitiatingOccupancyFration
      		设置CMS收集器在老年代空间被使用多少后触发垃圾收集,默认为68%,仅在CMS收集器时有效,-XX:CMSInitiatingOccupancyFration=70
      	5. -XX:+UseCMSCompactAtFullCollection
      		用于CMS收集器会产生碎片,此参数设置在垃圾收集器后是否需要一次内存碎片整理过程,仅在CMS收集时有效
      	6. -XX:+CMSFullCGBeforeCompaction
      		设置CMS收集器在进行若干次垃圾收集后在进行一次内存碎片整理过程,通常与UseCMSCompactATFullCollection参数一起使用
      	7. -XX:CMSInitiatingPermOccupancyFraction
      		设置Perm Gen使用达到多少比率时触发,默认为92%
  • 相关阅读:
    正则表达式
    虚拟机winXP试用期已过无法激活问题解决
    model.addattribute()的作用
    model.addAttribute() return @ResponseBody $ajax success data的关系
    bootStrap的使用
    【navicat】navicat导入导出数据库步骤
    【对比】mysql 与 oracle 区别
    oracle错误
    【备忘】船舶的几个吨位概念
    0731
  • 原文地址:https://www.cnblogs.com/demon89/p/tomcat.html
Copyright © 2020-2023  润新知