1、安全优化
项目 | 配置 | 说明 |
---|---|---|
tomcat shutdown端口的包含 | 改为其他的特殊端口,暗号也要修改。例如: <server port=”8115″ shutdown=”hahf8755″> | 无 |
ajp连接端口禁用 | 从tomcat8.5开始默认禁用 | 8009端口,用于与Apache进行连接 |
禁用管理端 | 把管理端相关配置、文件、目录清理掉。 webapps下面的docs、example、host-manager、manager目录 | 如果开启较为危险 |
降权启动(监牢模式) | 通过普通用户运行与管理服务 | 端口大于1024。1024以内的端口为特权端口,只能root使用。 |
文件列表访问控制 | 类似于nginx autoindex,是否默认开启列出站点目录的功能,默认关闭 | 无 |
tomcat版本信息隐藏 | 遇到4xx、5xx错误的时候,显示指定页面,不包含服务器版本信息 | 无 |
tomcat web服务隐藏 | http响应头里面的信息,connector 8080部分增加头部信息,Server=信息 | 无 |
访问控制 | 类似于nginx,使用allow、deny | 一般推荐使用nginx限制 |
启停脚本权限回收 | tomcat/bin目录,脚本,700/500,从8.5开始750 | 权限最小化 |
访问日志格式规范 | tomcat server.xml文件中配置访问日志格式 | 参考nginx |
忽略一些暴露敏感信息的头部信息(响应头) | lnmp\lnmt环境中程序代码会在响应头中加入服务版本的信息 |
案例1:用普通用户启动tomcat
默认。tomcat目录属主属组为root,需要改为普通用户,比如为tomcat
[root@web01 ~]#useradd tomcat
[root@web01 ~]#chown -R tomcat.tomcat /app/tools/tomcat
使用普通用户tomcat运行tomcat
[root@web01 ~]#su - tomcat -c "/app/tools/tomcat/bin/startup.sh"
把该命令写入/etc/rc.local文件,添加可执行权限,就可以开机执行。
案例2:tomcat web服务隐藏
在connecor 8080 部分增加Server信息,例如:
[root@web01 ~]#vim /app/tools/tomcat/conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
Server="Nginx/1.24.1" #增加Server
connectionTimeout="20000"
redirectPort="8443" />
重启tomcat,访问:
[root@web01 ~]#curl -I 192.168.10.7:8080
HTTP/1.1 200
X-ZrLog: 2.2.1
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Sun, 09 Jul 2023 02:54:52 GMT
Server: Nginx/1.24.1
[root@web01 ~]#
显示:Nginx/1.24.1
案例3:屏蔽服务端软件或代码的版本信息
在nginx中配置proxy_hide_header XXX软件或代码名称
如果是php,则fastcgi_hide_header X-Powered-By;
可以在http{}、server{}、location{}区域设置
2、性能优化
io模型优化
线程数量
配置禁用DNS反向解析
压缩的配置(nginx)
2.1 io模型优化
类似于nginx的同步、异步模型
io模型 | 说明 |
---|---|
BIO | Blocked IO,阻塞,同步模型。Tomcat7及之前版本默认是BIO |
NIO(NIO1、NIO2) | New IO,非阻塞,异步模型,tomcat8开始默认是nio |
APR | 应对高并发 |
应用建议:使用默认即可
案例:设为nio2
Connector port="8080"
原始的:protocol=“HTTP/1.1"
修改后:protocol="org.apache.coyote.http11.http11Nio2Protocol"
设置apr模型:
1、安装依赖
apr-devel、tomcat-native
2、修改
protocol="org.apache.coyote.http11.http11AprProtocol"
2.2 线程数量
maxThreads="500":最大的线程数量,200-400之间,具体的数值需要进行压力测试
acceptCout="500":当达到最大线程数量的时候,队列长度多长。acceptCount一般与maxThreads一致
acceptorThreadCount="2":请求分成几个队伍进行,数值上与cpu核心数一致或2倍,默认是1
minSpareThreads="10":空闲时候最小的线程数量,不忙的时候,最少保留几个。
在server.xml的Connector中设置,例如:
[root@web01 ~]#vim /app/tools/tomcat/conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="200"
minSpareThreads="2"
.....
登录管理端就可以查看到设置后的内容
相关值的建议,搭建好环境,部署应用,通过压力测试确定
测试软件:ab,loadrunner,jmter….
2.3 DNS、压缩
在<Connector port=”8080″ protocol=”HTTP/1.1″中配置
禁用dns反向解析功能,加速访问。
enableLookups="false"
#类型与nginx gzip压缩(推荐在nginx配置gzip brotil(第三方模块))
compression="on" :开启toncat压缩功能,静态文本资源 html jss css
compressionSize="2048" :大于2048字节的文件才会被压缩
compressableMimeType="text/html,text/plain,text/css,application/javascritp,application/json,application/x-font-ttf,application/s-font-otf"
3、jvm优化
在catalina.sh文件中配置:
设置jvm内存大小
配置gc日志(垃圾回收)
配置自动dump配置
a)配置jvm内存大小、gc日志
#设置jvm初始内存大小(默认:物理内存的1/64)jvm最大内存大小(默认:物理内存的1/4)
#修改catalina.sh文件
JAVA_OPTS='-Xms1024m Xmx1024m -Xloggc:/var/log/tomcat_gc.log'
选项解释:
-Xms:jvm初始内存大小
-Xmx:jvm最大内存
方案1:一般,-Xmx是-Xms的2倍
方案2:-Xms 与 -Xmx 一致,防止重复gc垃圾回收
gc:garbage collect,垃圾回收,定期清理jvm内存
-Xloggc:/var/log/tomcat_gc.log:垃圾回收的日志
b)配置自动dump
配置自动dump弄能(jvm发生异常,自动导出jvm内存镜像)
-XX:+HeapDumpOnOutOfMemoryError #OOM故障,开启导出jvm镜像功能,用于java/tomcat加载应用故障,内存不足
-XX:HeapDumpPath=/app/tools/tomcat/temp/oom.hprof #指定输出到哪里
oom:out of memory,内存不足
最终:
JAVA_OPTS='-Xms1024m Xmx1024m -Xloggc:/var/log/tomcat_gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/app/tools/tomcat/temp/oom.hprof'
5、Java前后端分离项目
tomcat动静分离,提取出静态资源
静态资源:前端(html、css、js)
后端:Java、php、Python、golang....连接数据库
前后端分离:拆分前端部分和后端部分,一般前后端通过API接口的进行连接
API应用程序接口:开发人员写好的,可以直接调用的代码,使用的人员不需要关注功能如何实现,直接使用即可。
·调用天气预报API接口:
curl "https://v0.yiketianqi.com/api?unescape=1&version=v91&appid=43656176&appsecret=I42og6Lm&ext=&cityid=&city="
架构:

5.1 前端分离

5.2项目
1)概述
主机 | 环境 |
---|---|
web01 | 前端(nginx)+后端(jdk) |
db02 | 数据库mysql8.0,二进制安装,/app/tools/mysql/,数据目录/app/data/3306/ |
2)数据库准备
数据库端:db02,ip:192.168.10.52、172.16.1.52
1、解压
提前下载好mysql8.0二进制包:mysql-8.0.28-linux-glibc2.12-x86_64.tar.xz
#1、创建相关目录
[root@db02 ~]#mkdir -p /app/tools/ /app/data/3306/
#2、解压并创建软连接
[root@db02 ~]#tar xf mysql-8.0.28-linux-glibc2.12-x86_64.tar.xz -C /app/tools/
[root@db02 ~]#ln -s /app/tools/mysql-8.0.28-linux-glibc2.12-x86_64/ /app/tools/mysql
#3、安装依赖
[root@db02 ~]#yum install -y ncurses ncurses-devel libaio-devel openssl openssl-devel
修改数据目录/app/data/3306/属主属组为:mysql
[root@db02 ~]#chown -R mysql.mysql /app/data/3306/
2、创建数据库用户
创建数据库虚拟用户mysql
[root@db02 ~]#useradd -s /sbin/nologin -M mysql
3、配置数据库
配置文件:/etc/my.cnf
[root@db02 ~]#vim /etc/my.cnf
[mysqld]
#用户
user=mysql
#安装目录
basedir=/app/tools/mysql/
#数据目录
datadir=/app/data/3306/
port=3306
socket=/tmp/mysql.sock
[client]
socket=/tmp/mysql.sock
修改该文件的属主属组为mysql
[root@db02 ~]#chown mysql.mysql /etc/my.cnf
4、配置环境变量
[root@db02 ~]#echo 'export PATH=/app/tools/mysql/bin:$PATH' >> /etc/profile
[root@db02 ~]#source /etc/profile
5、初始化数据库
注意:只执行一次即可
[root@db02 ~]#mysqld --initialize-insecure --user=mysql --basedir=/app/tools/mysql --datadir=/app/data/3306
2023-07-09T08:02:39.031799Z 0 [System] [MY-013169] [Server] /app/tools/mysql-8.0.28-linux-glibc2.12-x86_64/bin/mysqld (mysqld 8.0.28) initializing of server in progress as process 2367
2023-07-09T08:02:39.545516Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2023-07-09T08:02:40.940703Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2023-07-09T08:02:46.239780Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
6、启动
准备启动文件:
[root@db02 ~]#cp /app/tools/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@db02 ~]#chmod +x /etc/init.d/mysqld
启动:
[root@db02 ~]#systemctl daemon-reload
[root@db02 ~]#systemctl start mysqld
[root@db02 ~]#systemctl enable mysqld
3)创建项目数据库
创建名为exam的数据库,指定字符集为:utf8mb4
授权用户为exam,密码为1
[root@db02 ~]#mysql
#创建数据库
mysql> create database exam charset utf8mb4;
#创建exam用户
mysql> create user exam@'172.16.1.%' identified with mysql_native_password by '1';
#授权
mysql> grant all on exam.* to exam@'172.16.1.%';
从mysql8.0开始,创建用户和授权要分开进行,identified设置密码要加上with mysql_native_password参数
导入数据(创建表、导入数据)
很多应用需要手动导入
[root@db02 ~]#mysql exam < xzs-mysql.sql
4)部署后端
1、创建项目目录
[root@web01 ~]#mkdir -p /app/code/exam/{front,backend}
2、解压项目代码
解压到backend目录
[root@web01 ~]#cd /app/code/exam/backend/
[root@web01 /app/code/exam/backend]#cp /root/xzs-3.9.0.jar .
配置文件内容:
[root@web01 ~]#vim /app/code/exam/backend/application-prod.yml
logging:
path: /var/log/xzs
spring:
datasource:
url: jdbc:mysql://172.16.1.52:3306/exam?useSSL=false&useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&allowMultiQueries=true
username: exam
password: 1
driver-class-name: com.mysql.cj.jdbc.Driver
执行:
[root@web01 /app/code/exam/backend]#java -Duser.timezone=Asia/Shanghai -jar -Dspring.profiles.active=prod xzs-3.9.0.jar
说明:
-Dspring.profiles.active=prod: jar包目录同层的application-prod.yml application.yml
后台执行:
nohup java -Duser.timezone=Asia/Shanghai -jar -Dspring.profiles.active=prod xzs-3.9.0.jar > start.log 2>&1 &
浏览器打开:192.168.10.7:8000
如下:

学生端:192.168.10.7:8000/student,用户名,student,密码:123456
管理员:192.168.10.7:8000/admin,用户名:admin,密码:123456
其他可以加入的后端的配置
server:
port:8000
undertow:
io-threads: 16
worker-threads: 4000
buffer-size: 1024
direct-buffers: true
compression:
enabled: true
min-response-size: 1
#loggin logback
logging:
#config: classpath:logback-spring.xml
#file: xzs
path: /var/log/xzs
#mybatis
mybatis:
mapper-locations: classpath:/mapper/*.xml
configuration:
log-prefix: repository
system:
security-ignore-urls:
- /api/wx/**
- /api/admin/upload/configAndUpload
- /api/admin/upload/auth
- /api/student/user/register
pwdkwy:
publicKey:
privateKey:
wx:
appid: wxxxx444
secret: 4d1gg44
token-to-live: 12h
security-ignore-urls:
- /api/wx/student/auth/bind
- /api/wx/student/auth/checkBind
- /api/wx/student/user/register
#连接对象存储,七牛
qn:
url: http://xzs.file.mindskip.net #域名要改为自己的
bucket: mindskip
access-key: adkidd455
secret-key: ddikd4
#mybatis page helper
pagehelper:
autoDialect: true
closeConn: true
reasonable: true
#mybatis datasource default HikariPool
spring:
#会话共享
session:
store-type: redis
#配置数据库
datasource:
url: jdbc:mysql://172.16.1.52:3306/exam?useSSL=false&useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true&allowMultiQueries=true
username: exam
password: 1
driver-class-name: com.mysql.cj.jdbc.Driver
#Redis地址
redis:
url: 127.16.1.51
timeout: 10000
database: 0
lettuce:
pool:
max-active: 8
max-wait: -1
max-idle: 8
min-idle: 1
cache:
type: redis
redis:
time-to-live: 12h
#runningtime environment
profiles:
active: dev
5)部署前端
nginx站点配置文件
[root@web01 ~]#vim /etc/nginx/conf.d/exam.conf
server {
listen 80;
server_name admin.exam.com;
root /app/code/exam/front/admin;
location / {
index index.html;
}
location /api/ {
proxy_pass http://localhost:8000;
}
}
server {
listen 80;
server_name stu.exam.com;
root /app/code/exam/front/student;
location / {
index index.html;
}
location /api/ {
proxy_pass http://localhost:8000;
}
}
解压前端代码到/app/code/exam/front目录
[root@web01 ~]#unzip exam-web-前端.zip
[root@web01 ~]#mv exam-web-前端/* /app/code/exam/front/
[root@web01 ~]#cd /app/code/exam/front/
[root@web01 /app/code/exam/front]#ls
admin student
重启nginx,Windows本地做hosts解析:
浏览器打开:admin.exam.com

浏览器打开:stu.exam.com
如下:
