TOMCAT优化
tomcat优化分为:tomcat自身的优化和Java虚拟机的优化
垃圾都存在heap(堆)中
垃圾确定方法:
跟可达算法、引用计数器标识垃圾
清除垃圾的算法:
标记-清除: 用跟可达法标记出来,然后清除,会造成内存碎片
标记-压缩: 用跟可达法标记出来,清除,然后整理对象向内存一端移动
复制算法: 先把内存空间分成两半,每次只用其中一半,当这一半用完时,则将存活对象复制到另一半继续使用,最后将之前的一半空间全部清除。内存消耗比较大
效率:复制>标记清除>标记压缩
内存整齐度:复制=标记压缩>标记清除
内存利用率:标记压缩=标记清除>复制
堆内存分代
堆内存分代:年轻代,老年代
新创建的对象都放在年轻代中,年轻代的对象经过多少次垃圾回收都没被清除,放到老年代
年轻代又分为:Eden园区,幸存区[from(S0),to(S1)] (幸存区数据挪动指定的次数后,挪动到老年代)
老年代使用的标记-压缩算法,等于full GC,老年代如果满了,如触发全部代的垃圾回收
年轻代使用的复制算法,部分回收
堆内存分配(默认为JVM虚拟机总内存的1/4)
Eden园区站8/30,幸存区占2/30,老年代占2/3
业务生成的对象时间短,就给年轻代分多一点
业务生成的对象时间长,就给老年代分多一点
一般情况下99%的对象都是临时对象
查看JVM内存分配情况
cat Heap.java
public class Heap {
public static void main(String[] args){
//返回JVM试图使用的最大内存,字节单位
long max = Runtime.getRuntime().maxMemory();
//返回JVM初始化总内存
long total = Runtime.getRuntime().totalMemory();
System.out.println("max="+max+"字节\t"+(max/(double)1024/1024)+"MB");
System.out.println("total="+total+"字节\t"+
(total/(double)1024/1024)+"MB");
}
}
使用javac编译,生成Heap.class文件
javac Heap.java
使用java执行
java Heap
max=513802240字节 490.0MB
total=33554432字节 32.0MB
显示详细信息
java -XX:+PrintGCDetails Heap
java 内存调整相关参数
-Xms 初始使用内存大小(年轻代+老年代)
-Xmx 最大使用内存空间,-Xms和-Xmx建议设置成一样,建议分一半,但不要超过32G
-XX:NewSize 年轻代初始化内存大小
-XX:MaxNewSize 年轻代最大使用内存空间,建议和年轻代初始化内存大小设为一样
-Xmnsize 同时设置-XX:NewSize和-XX:MaxNewSize,代替两者
-XX:NewRatio 以比例方式设置新生代和老年代
-XX: SurvivorRatio 以比例方式设置eden和survivor (S0或S1)
-Xss 设置每个线程私有的栈空间大小,依据具体线程 大小和数量
TOMCAT如何调整堆内存大小:
Java可以直接在命令行添加参数
java -Xms1024m -Xmx1024m -XX:+PrintGCDetails Heap
tomcat需要写到配置文件里vim /usr/local/apache-tomcat-9.0.65/bin/catalina.sh
JAVA_OPTS="-Xms1024m -Xmx1024m"
重启tomcat服务
其他的一些服务,优化参数 如halo,可以直接加
java -Xms1024m -Xmx1024m -jar halo.jar
如果内存分配不合理,有可能造成内存满了,导致系统崩溃,出现OOM
造成OOM的情况:
内存分的不够
代码有问题
监控工具:jprofiler,定位oom的问题原因,需要购买
java自带图形化工具可查看堆内存使用情况(中文会乱码,需改成英文)
localectl set-locale LANG=en_US.UTF-8
执行/usr/loacl/jdk/bin/jvisualvm
垃圾回收方式:
并行回收 多个线程
串行回收 一个线程 (不建议用)
垃圾回收器按分代设置不同的垃圾回收器:
如:
年轻代:PS、PN (并行回收)
PS:,关注吞吐量,适用于非交互式程序,集中时间进行垃圾回收
PN:关注交互性,把垃圾时间打碎,回收N次,用户体验好
老年代:CMS和PO
如果年轻代用PS,则老年代用PO配合使用,关注吞吐量
如果年轻代用PN,则老年代用CMS配合使用,关注交互的
JDK8代:如果是交互式程序,年轻代用PN,老年代用CMS
如果程序更注重吞吐量,年轻代用PS,老年代用PO
JDK11代:G1算法垃圾回收器
tomcat文件配置catalina.sh设置垃圾回收:
JAVA_OPTS=
"-XX:+UseConcMarkSweepGC -XX: CMSInitiatingOccupancyFraction=80 - XX:+UseCMSCompactAtFullCollection -XX: CMSFullGCsBeforeCompaction=5"
生产案例:
[root@centos8 ~]#vim /usr/local/tomcat/bin/catalina.sh
JAVA_OPTS="-server -Xms4g -Xmx4g -Xss512k -Xmn1g -XX:CMSInitiatingOccupancyFraction=65 -XX:+AggressiveOpts -XX:+UseBiasedLocking -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=10 -XX:NewRatio=2 -XX:PermSize=128m -XX:MaxPermSize=512m -XX:CMSFullGCsBeforeCompaction=5 -XX:+ExplicitGCInvokesConcurrent -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection - XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods"
#一台tomcat服务器并发连接数不高,生产建议分配物理内存通常4G到8G较多,如果需要更多连接,一般会利用 虚拟化技术实现多台tomcat
开启JMX功能,打开监听端口,进行远程监控java程序
#为java程序开启JMX很简单,只要在运行java程序的命令后面指定如下命令即可
java\
-Dcom.sun.management.jmxremote \#启用远程监控JMX
-Djava.rmi.server.hostname=10.0.0.100 \#指定自已监听的IP
-Dcom.sun.management.jmxremote.port=12345 \#指定监听的PORT
-Dcom.sun.management.jmxremote.authenticate=false \
-Dcom.sun.management.jmxremote.ssl=false \
vim /usr/local/tomcat/bin/catalina.sh
JAVA_OPTS=
"-XX:+UseConcMarkSweepGC -XX: CMSInitiatingOccupancyFraction=80 - XX:+UseCMSCompactAtFullCollection -XX: CMSFullGCsBeforeCompaction=5 -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname=10.0.0.100 -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
在windows上使用jconsole可连接
TOMCAT线程池调整
vim /usr/local/tomcat/bin/catalina.sh
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="2000" redirectPort="8443" maxThreads="2000"/>
JAVA源码编译器--MAVEN
c语言编译:
./configure 指定编译选项,如装在哪个目录下,启用或者禁用哪些功能,执行完会生成一个makefire文件
make 读取makfire进行编译
make install
java编译:mvn clean packege -Dmaven.test.skip=true
编译依赖POM.xml文件,文件包含,编译所用到的依赖包
编译完成生成jar、var包、文件名及版本信息等
MAVEN工程构建的各个环节
clean:清理旧的垃圾文件
compile:编译class文件
text:自动测试,可跳过测试代码编译 -Dmaven.text.skip=true
repoat:结果
package:打包成war或jar,由pom.xml决定
deploy:部署,一般是TOMCAT让其
install:将打包得到的文件放到仓库指定位置
运行jar包 java -jar ....jar 可以加上优化选项 如:--server.port=8081
maven安装方式1:包安装
Ubuntu20.04安装maven
[root@ubuntu2004 ~]#apt -y install maven
#自动安装Openjdk11
[root@ubuntu2004 ~]#java -version
[root@ubuntu2004 ~]#mvn -v
#镜像加速 包依赖在国外,比较慢,需要把镜像改成国内
[root@ubuntu2004 ~]#vim /etc/maven/settings.xml (位置在166行左右)
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>前面
[root@ubuntu2004 ~]#mvn -version
Rocky/CentOS/RHEL安装maven
[root@rocky8 ~]#yum -y install maven
[root@rocky8 ~]#mvn -v
#镜像加速 包依赖在国外,比较慢,需要把镜像改成国内
[root@rocky8 ~]##vim /etc/maven/settings.xml (位置在166行左右)
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>前面
[root@ubuntu2004 ~]#mvn -version
maven安装方式2:二进制安装
官网说明:http://maven.apache.org/install.html
[root@ubuntu2004 ]#apt update
[root@ubuntu2004 ]#apt install openjdk-8-jdk -y
[root@ubuntu2004 ]#java -version
[root@ubuntu2004 ]#wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.8.6/binaries/apachemaven-3.8.6-bin.tar.gz
[root@ubuntu2004 ]#tar xf apache-maven-3.8.6-bin.tar.gz -C /usr/local/
[root@ubuntu2004 ]#cd /usr/local/
[root@ubuntu2004 local]#ln -s apache-maven-3.8.6/ maven
[root@ubuntu2004 local]#echo 'PATH=/usr/local/maven/bin:$PATH' > /etc/profile.d/maven.sh
[root@ubuntu2004 local]#. /etc/profile.d/maven.sh
[root@ubuntu2004 local]#mvn -version
Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
安装完成
#镜像加速 包依赖在国外,比较慢,需要把镜像改成国内
[root@ubuntu2004 ~]#vim /usr/local/maven/conf/settings.xml (位置在166行左右)
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
</mirrors>前面
[root@ubuntu2004 ~]#mvn -version
启动多线程编译
#启动多线程编译
mvn -T 4 clean install package -Dmaven.test.skip=true
#分配编译的CPU个数
mvn -T 2C clean install package -Dmaven.test.skip=true
执行 java 代码编译实战案例 (编译安装spring-boot项目)
安装git
[root@ubuntu2004 ~]#apt install git -y
下载spring-boot源码包
[root@ubuntu2004 ~]#git clone https://gitee.com/lbtooth/spring-boothelloWorld.git
[root@ubuntu2004 ~]#cd spring-boot-hellWoorld
[root@ubuntu2004 spring-boot-hellWoorld~]#ls
deploy Dockerfile Jenkisnfile LICENSE pom.xml README.md src
进行编译
[root@ubuntu2004 spring-boot-hellWoorld~]#mvn clean install package -Dmaven.test.skip=true
编译完成,生成target目录
[root@ubuntu2004 spring-boot-hellWoorld~]#ls
deploy Dockerfile Jenkisnfile LICENSE pom.xml README.md src target
[root@ubuntu2004 spring-boot-hellWoorld~]#ls target/
calsses generated-sources maven-archiver maven-status
spring-boothelloWorld-0.9.0-SNAPASHOT.jar
spring-boothelloWorld-0.9.0-SNAPASHOT.jar.original
把jar包放到项目目录下
如:
[root@ubuntu2004 spring-boot-hellWoorld~]#cp spring-boothelloWorld-0.9.0-SNAPASHOT.jar /opt
[root@ubuntu2004 spring-boot-hellWoorld~]# cd /opt
运行:java -jar spring-boothelloWorld-0.9.0-SNAPASHOT.jar 后可加优化参数
还可指定端口号
java -jar spring-boothelloWorld-0.9.0-SNAPASHOT.jar --server.port=80
查看是否监听 ss -ntlp
windows浏览器访问
10.0.0.100
编译java程序Jpress(当前jpress-v5.0.2不支持JDK11)
克隆下载jpress源码
[root@ubuntu2004 ~]#git clone https://gitee.com/JPressProjects/jpress.git 或者
[root@ubuntu2004 ~]#wget -O jpress-v4.2.0.tar.gz 'https://gitee.com/JPressProjects/jpress/repository/archive/v4.2.0? format=tar.gz
[root@ubuntu2004 ~]#cd jpress/
进入到jpress目录,进行编译,内存在4G以上
[root@ubuntu2004 jpress]#cd jpress/
[root@ubuntu2004 jpress]#mvn clean install package -Dmaven.test.skip=true
生成了war包
[root@ubuntu2004 jpress]#ll starter-tomcat/target/
总用量 124900
drwxr-xr-x 5 root root 4096 9月 27 17:51 ./
drwxr-xr-x 4 root root 4096 9月 27 17:51 ../
drwxr-xr-x 2 root root 4096 9月 27 17:51 classes/
drwxr-xr-x 2 root root 4096 9月 27 17:51 maven-archiver/
drwxr-xr-x 6 root root 4096 9月 27 17:51 starter-tomcat-5.0/
-rw-r--r-- 1 root root 4467 9月 27 17:51 starter-tomcat-5.0-classes.jar
-rw-r--r-- 1 root root 127865171 9月 27 17:51 starter-tomcat-5.0.war
打包到tomcat路径下
[root@ubuntu2004 jpress]#cp starter-tomcat/target/starter-tomcat-5.0.war /usr/local/tomcat/webapps/jpress.war
已自动解压
[root@ubuntu2004 jpress]#cd /usr/local/tomcat/webapps/
[root@ubuntu2004 webapps]#ls (自动生成jpress)
docs examples host-manager jpress jpress.war manager ROOT
通过浏览器访问http://10.0.0.100:8080/jpress
NEXUS私有仓库
Nexus 是一个强大的Maven和其它仓库的管理器,它极大地简化了自己内部仓库的维护和外部仓库的访问.
官网:https://www.sonatype.com/
安装NEXUS建议内存至少4G以上
nexus安装脚本
[root@ubuntu2004 ~]#cat install_nexus.sh
#!/bin/bash
NEXUS_URL="https://download.sonatype.com/nexus/3/nexus-3.39.0-01-unix.tar.gz"
#NEXUS_URL="https://download.sonatype.com/nexus/3/nexus-3.36.0-01-unix.tar.gz"
#NEXUS_URL="https://download.sonatype.com/nexus/3/nexus-3.29.2-02-unix.tar.gz"
INSTALL_DIR=/usr/local/nexus
HOST=`hostname -I|awk '{print $1}'`
GREEN="echo -e \E[32;1m"
END="\E[0m"
. /etc/os-release
color () {
RES_COL=60
MOVE_TO_COL="echo -en \\033[${RES_COL}G"
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_WARNING="echo -en \\033[1;33m"
SETCOLOR_NORMAL="echo -en \E[0m"
echo -n "$1" && $MOVE_TO_COL
echo -n "["
if [ $2 = "success" -o $2 = "0" ] ;then
${SETCOLOR_SUCCESS}
echo -n $" OK "
elif [ $2 = "failure" -o $2 = "1" ] ;then
${SETCOLOR_FAILURE}
echo -n $"FAILED"
else
${SETCOLOR_WARNING}
echo -n $"WARNING"
fi
${SETCOLOR_NORMAL}
echo -n "]"
echo
}
install_jdk() {
if [ $ID = "centos" -o $ID = "rocky" ];then
yum -y install java-1.8.0-openjdk || { color "安装JDK失败!" 1; exit 1; }
else
apt update
apt -y install openjdk-8-jdk || { color "安装JDK失败!" 1; exit 1; }
fi
color "安装JDK完成!" 0
java -version
}
install_nexus() {
if [ -f ${NEXUS_URL##*/} ];then
cp ${NEXUS_URL##*/} /usr/local/src
else
wget -P /usr/local/src/ $NEXUS_URL || { color "下载失败!" 1 ;exit ; }
fi
tar xf /usr/local/src/${NEXUS_URL##*/} -C /usr/local
ln -s /usr/local/nexus-*/ ${INSTALL_DIR}
ln -s ${INSTALL_DIR}/bin/nexus /usr/bin/
}
start_nexus (){
cat > /lib/systemd/system/nexus.service <<EOF
[Unit]
Description=nexus service
After=network.target
[Service]
Type=forking
LimitNOFILE=65536
ExecStart=${INSTALL_DIR}/bin/nexus start
ExecStop=${INSTALL_DIR}/bin/nexus stop
User=root
#User=nexus
Restart=on-abort
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now nexus.service
if [ $? -eq 0 ] ;then
color "nexus 安装成功" 0
echo "-------------------------------------------------------------------"
echo -e "访问链接: \c"
${GREEN}"http://$HOST:8081/"${END}
while [ ! -f ${INSTALL_DIR}/../sonatype-work/nexus3/admin.password ];do
sleep 1
done
PASS=`cat ${INSTALL_DIR}/../sonatype-work/nexus3/admin.password`
echo -e "用户和密码: \c"
${GREEN}"admin/$PASS"$END
else
color "nexus 安装失败!" 1
exit 1
fi
}
install_jdk
install_nexus
start_nexus
二进制包安装
NEXUS默认端口8081
maven仓库
更新缓存
[root@ubuntu2004 ~]#apt update
#安装JDK
[root@ubuntu2004 ~]#apt install openjdk-8-jdk -y
下载NEXUS安装包:
[root@ubuntu2004 ~]#wget https://download.sonatype.com/nexus/3/nexus-3.41.1-01- unix.tar.gz
将下载好的包解压缩
[root@ubuntu2004 ~]#tar xf nexus-3.41.1-01-unix.tar.gz -C /usr/local/
创建软链接
[root@ubuntu2004 ~]#cd /usr/local/
[root@ubuntu2004 local]#ls
apache-tomcat-9.0.65 etc include jdk1.8.0_341 man sbin sonatype-work tomcat
bin games jdk lib nexus-3.41.1-01 share src
[root@ubuntu2004 local]#ln -s nexus-3.41.1-01/ nexus
[root@ubuntu2004 local]#ls nexus/
bin deploy etc lib NOTICE.txt OSS-LICENSE.txt PRO-LICENSE.txt public replicator system
修改运行身份
[root@ubuntu2004 local]#vim /usr/local/nexus/bin/nexus.rc
run_as_user="root"
查看配置文件,可以在此文件中修改端口等配置
[root@ubuntu2004 ]#cat /usr/local/nexus/etc/nexus-default.properties
## DO NOT EDIT - CUSTOMIZATIONS BELONG IN $data-dir/etc/nexus.properties
##
# Jetty section
application-port=8081
application-host=0.0.0.0
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-requestlog.xml
nexus-context-path=/
# Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-feature
nexus.hazelcast.discovery.isEnabled=true
查看JVM配置文件(优化相关)
[root@ubuntu2004 ]#cat /usr/local/nexus/bin/nexus.vmoptions
创建service文件
[root@ubuntu2004 local]#vim /lib/systemd/system/nexus.service
[Unit]
Description=nexus serviceAfter=network.target
[Service] Type=forking LimitNOFILE=65536 ExecStart=/usr/local/nexus/bin/nexus start ExecStop=/usr/local/nexus/bin/nexus stop
User=root
#User=nexus
Restart=on-abort
[Install]WantedBy=multi-user.target
重新加载
[root@ubuntu2004 local]#systemctl daemon-reload
开机自启
[root@ubuntu2004 local]#systemctl enable --now nexus.service
去浏览器访问10.0.0.100:8081
点击sign in登录
用户名admin,密码在提示的目录里:
Your admin user password is located in
/usr/local/sonatype-work/nexus3/admin.password on the server.
去服务器上查看密码:
[root@ubuntu2004 local]#cat /usr/local/sonatype-work/nexus3/admin.password
6576897c-ac1c-42b9-b4e4-a9c6c70ac331
进入后直接提示修改新密码
匿名下载选第一个,输入密码下载选第二个
下一步即可使用nexus仓库
验证默认仓库
Hosted:本地仓库,通常我们会部署自己的构件到这一类型的仓库,比如公司的第三方库
Proxy:代理仓库,它们被用来代理远程的公共仓库,如maven中央仓库(官方仓库)
Group:仓库组,用来合并多个 hosted/proxy 仓库,当你的项目希望在多个repository 使用资源时就 不需要多次引用了,只需要引用一个group即可
Maven的仓库优化配置(MAVEN编译源代码需要的依赖包由nexus去拉取)
默认仓库maven-central使用国外仓库地址,可修改为如下的国内镜像地址进行加速
http://maven.aliyun.com/nexus/content/groups/public
点击齿轮图形进行设置--repositories
点击maven-central,将Remote storage地址修改为https://maven.aliyun.com/repository/central
将nexus的URL地址配置在maven的配置文件中
将此路径配置到maven仓库
[root@ubuntu2004 ~]#vim /conf/maven/settings.xml
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*</mirrorOf>
<name>Nexus aliyun</name>
<url>http://10.0.0.100:8081/repository/maven-central/</url>
</mirror>
</mirrors>前面
此时再下载依赖包mvn clean install package -Dmaven.test.skip=true
就是走的私有仓库http://10.0.0.100:8081/repository/maven-central/
nexus搭建yum仓库
自定义存储仓库数据目录
[root@ubuntu2004 local]#mkdir /data/blobs -p
到网站nexus去配置 点击blob stores-create blob stores-FILE
Type:file Name:blob-yum-zabbix-centos7 Path:/data/blob/blob-yum-zabbix-centos7
创建yum仓库 :repositories--create repository
选择yum(proxy)
代理直到清华源,把清华源上关于centos7系统zabbix安装包的URL路径输上
并指定安装包存储位置,并创建
进入仓库,复制仓库路径,找一台centos7服务器,并在服务器上配置YUM仓库
服务器上配置Yum仓库
vim /etc/yum.repos.d/base.repo
[zabbix]
baseurl=http://10.0.0.100:8081/repository/yum-zabbix5.0/
gpgcheck=0
enabled=1
yum clean all
yum repolist
更新仓库后,去nexus服务器/data/blob/blob-yum-zabbix-centos7/目录下,可看到数据
当在centos7服务器上装包后,安装包便存在nexus中
[root@centos7 ~]#yum list |grep zabbix
[root@centos7 ~]#yum install zabbix-agent
nexus配置apt仓库
点击blob stores-create blob stores-FILE
创建apt仓库 :repositories--create repository,选择apt(proxy)
选择目录后创建
进入复制路径
开启ubuntu服务器,并把路径写道配置文件中
vim /etc/apt/sources.list
把路径替换成nexus路径
更新仓库
apt update
nexus配置邮件通知
如何优化java程序
一:根据实际生产环境设置年轻代、老年代内存分配。
二:检查代码有没有问题。
三:设置垃圾回收器算法,提高效率和吞吐量。
四:开启JMX远程监控
五:调整线程池
如何编译
c语言编译:
./configure 指定编译选项,如装在哪个目录下,启用或者禁用哪些功能,执行完会生成一个makefire文件
make 读取makfire进行编译
make install
maven编译:mvn clean packege -Dmaven.test.skip=true
编译依赖POM.xml文件,文件包含,编译所用到的依赖包
编译完成生成jar、var包、版本信息等