export maxParameterCount="1000"
export acceptCount="1000"
export maxSpareThreads="750"
export maxThreads="1000"
export minSpareThreads="50"
export URIEncoding="UTF-8"
export JAVA_OPTS=" -Xms5120m -Xmx5120m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m -XX:MaxDirectMemorySize=2048m -XX:+HeapDumpOnOutOfMemoryError -Xloggc: -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=50 -XX:ErrorFile=/export/Logs/hs_err_pid%p.log /export/Logs/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintReferenceGC -XX:+PrintTenuringDistribution -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100M -Djava.library.path=/usr/local/lib -server -XX:HeapDumpPath=/export/Logs -Djava.awt.headless=true -Dsun.net.client.defaultConnectTimeout=60000 -Dsun.net.client.defaultReadTimeout=60000 -Djmagick.systemclassloader=no -Dnetworkaddress.cache.ttl=300 -Dsun.net.inetaddr.ttl=300 -DswimLaneEnable=true "
除了之前的 Tomcat + JVM 基础配置,生产环境还需要补充 "容易被忽略但至关重要" 的配置,主要包括 JVM 安全/诊断增强 、Tomcat 安全/性能加固 、操作系统内核优化 、日志规范 和 启动脚本健壮性 五个维度。以下是具体的补充配置和代码:
一、JVM 层面:补充安全、诊断与兜底配置
在现有 JAVA_OPTS 基础上,添加以下参数:
1. 安全加固(禁用不安全协议/功能)
bash
# 禁用 TLS 1.0/1.1 等不安全协议,强制使用 TLS 1.2+
-Djdk.tls.client.protocols=TLSv1.2,TLSv1.3
-Dhttps.protocols=TLSv1.2,TLSv1.3
# 禁用 JNDI 远程类加载(防止 Log4j2 等类似漏洞)
-Dcom.sun.jndi.rmi.object.trustURLCodebase=false
-Dcom.sun.jndi.cosnaming.object.trustURLCodebase=false
# 禁用 JVM 的 Attach 机制(防止未授权的进程注入,可选,需配合监控方案)
# -XX:+DisableAttachMechanism
2. OOM 兜底:自动重启应用(可选,需谨慎)
如果应用 OOM 后无法自动恢复,可以添加以下参数让 JVM 在 OOM 时自动执行重启脚本:
bash
# OOM 时执行自定义重启脚本(需提前写好 restart.sh)
-XX:OnOutOfMemoryError="/opt/scripts/restart.sh %p"
⚠️ 注意:restart.sh 需要包含"停止旧进程、等待端口释放、启动新应用"的逻辑,且要避免无限循环重启。
3. JMX 监控配置(配合 Prometheus/Grafana)
如果需要用 JConsole 或 Prometheus 监控 JVM 内部指标,添加以下参数:
bash
# 开启 JMX 远程监控(端口 9999,无认证,生产环境建议加认证和 SSL)
-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=你的服务器IP
二、Tomcat 层面:补充安全、性能与日志配置
1. 安全加固:关闭默认管理页面与危险方法
修改 Tomcat 的 conf/server.xml,禁用或注释掉以下内容:
xml
<!-- 1. 禁用默认的 Manager 管理页面(防止未授权访问) -->
<!-- <Valve className="org.apache.catalina.valves.AccessLogValve" ... /> -->
<!-- 2. 禁用危险的 HTTP 方法(只保留 GET/POST) -->
<Connector port="8080" protocol="HTTP/1.1"
...
allowTrace="false"
allowedMethods="GET,POST,PUT,DELETE" />
<!-- 3. 隐藏 Tomcat 版本号(防止被针对性攻击) -->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.ErrorReportValve"
showReport="false" showServerInfo="false" />
</Host>
2. 性能优化:开启 Gzip 压缩与限制请求大小
在 conf/server.xml 的 <Connector> 标签中添加:
xml
<Connector port="8080" protocol="HTTP/1.1"
...
<!-- 开启 Gzip 压缩,压缩文本/JS/CSS,减少传输带宽 -->
compression="on"
compressionMinSize="2048"
compressableMimeType="text/html,text/xml,text/plain,text/css,application/javascript,application/json"
<!-- 限制请求体大小(防止大文件上传攻击,这里设为 10MB,根据业务调整) -->
maxPostSize="10485760"
<!-- 限制请求头大小(防止 HTTP 头注入攻击) -->
maxHttpHeaderSize="8192" />
3. 补充 Access Log(访问日志)配置
在 conf/server.xml 的 <Host> 标签内添加 Access Log(用于分析用户请求、排查攻击):
xml
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="/export/Logs/tomcat_access" <!-- 日志保存路径 -->
prefix="access_log"
suffix=".log"
pattern="%h %l %u %t "%r" %s %b %D "%{Referer}i" "%{User-Agent}i""
rotatable="true"
renameOnRotate="true"
maxDays="30" /> <!-- 保留 30 天日志 -->
%h:客户端 IP;%s:HTTP 状态码;%b:响应大小;%D:请求处理时间(毫秒)。
三、操作系统层面:内核参数优化(高并发场景必须)
这是最容易被忽略但对高并发影响最大 的配置!需要修改 Linux 的 /etc/sysctl.conf 文件(修改后执行 sysctl -p 生效):
1. 文件描述符限制(允许更多并发连接)
bash
# 1. 先修改 /etc/security/limits.conf(永久生效)
* soft nofile 655350
* hard nofile 655350
* soft nproc 655350
* hard nproc 655350
# 2. 再修改 /etc/sysctl.conf
fs.file-max = 655350 # 系统级最大文件描述符数
2. TCP 网络参数优化(应对高并发连接)
bash
# /etc/sysctl.conf 中添加:
net.ipv4.tcp_tw_reuse = 1 # 允许 TIME_WAIT 状态的 socket 重新用于新连接
net.ipv4.tcp_tw_recycle = 0 # 关闭快速回收(NAT 环境下会有问题,建议设为 0)
net.ipv4.tcp_fin_timeout = 30 # TIME_WAIT 状态的超时时间(默认 60s,缩短到 30s)
net.ipv4.tcp_max_tw_buckets = 20000 # 系统允许的最大 TIME_WAIT socket 数
net.ipv4.tcp_max_syn_backlog = 8192 # SYN 队列长度(应对突发连接)
net.core.somaxconn = 8192 # 监听端口的最大等待连接数(配合 Tomcat 的 acceptCount)
net.core.netdev_max_backlog = 8192 # 网络设备接收队列的最大长度
四、日志层面:补充应用日志规范
除了 GC 日志和 Tomcat Access Log,应用日志(比如 Logback/Log4j2)也需要补充规范配置:
1. Logback 配置示例(logback-spring.xml)
xml
<configuration>
<!-- 1. 控制台输出(开发环境用,生产环境可关闭) -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 2. 应用日志文件(按天滚动,保留 30 天) -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/export/Logs/app/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/export/Logs/app/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>10GB</totalSizeCap> <!-- 总日志大小不超过 10GB -->
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 3. 错误日志单独输出(方便排查) -->
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/export/Logs/app/error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/export/Logs/app/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<!-- 4. 日志脱敏(防止敏感信息泄露,比如手机号、身份证号) -->
<conversionRule conversionWord="msg" converterClass="com.example.SensitiveDataMaskingConverter" />
<!-- 生产环境日志级别:INFO(避免 DEBUG 日志过多占用磁盘) -->
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>
五、启动脚本:补充健壮性检查
最后,给你的应用启动脚本(start.sh)补充以下检查逻辑,避免启动失败或异常:
bash
#!/bin/bash
APP_NAME="your-app.jar"
APP_PATH="/opt/app"
LOG_PATH="/export/Logs"
PID_FILE="$APP_PATH/app.pid"
# 1. 前置检查:创建必要目录
mkdir -p $LOG_PATH $APP_PATH
# 2. 前置检查:检查 JDK 版本(要求 JDK 8+)
JAVA_VERSION=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}' | awk -F '.' '{print $1$2}')
if [ "$JAVA_VERSION" -lt "18" ]; then
echo "错误:JDK 版本过低,需要 JDK 8+,当前版本:$(java -version 2>&1)"
exit 1
fi
# 3. 前置检查:检查端口是否被占用(假设应用端口是 8080)
if netstat -tuln | grep -q ":8080 "; then
echo "错误:端口 8080 已被占用,请先停止旧进程"
exit 1
fi
# 4. 停止旧进程(如果存在)
if [ -f $PID_FILE ]; then
PID=$(cat $PID_FILE)
if kill -0 $PID 2>/dev/null; then
echo "正在停止旧进程(PID: $PID)..."
kill $PID
sleep 10
if kill -0 $PID 2>/dev/null; then
echo "强制杀死旧进程..."
kill -9 $PID
fi
fi
rm -f $PID_FILE
fi
# 5. 启动应用(使用修正后的 JVM 参数)
echo "正在启动应用..."
nohup java -jar $APP_PATH/$APP_NAME \
-Xms5120m -Xmx5120m \
-XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m \
-XX:MaxDirectMemorySize=2048m \
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$LOG_PATH \
-XX:ErrorFile=$LOG_PATH/hs_err_pid%p.log \
-Xloggc:$LOG_PATH/gc.log \
-XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:ParallelRefProcEnabled \
-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintReferenceGC -XX:+PrintTenuringDistribution \
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=100M \
-Djava.awt.headless=true \
-Dsun.net.client.defaultConnectTimeout=20000 -Dsun.net.client.defaultReadTimeout=20000 \
-Dnetworkaddress.cache.ttl=300 \
> $LOG_PATH/app.out 2>&1 &
# 6. 保存 PID 并检查启动是否成功
echo $! > $PID_FILE
sleep 15
if curl -s http://localhost:8080/actuator/health >/dev/null; then
echo "应用启动成功!PID: $(cat $PID_FILE)"
else
echo "应用启动失败,请查看日志:$LOG_PATH/app.out"
exit 1
fi
总结
补充以上配置后,你的生产环境会更安全、稳健、易排查问题。核心补充点是:
- JVM:安全加固、OOM 兜底、JMX 监控;
- Tomcat:关闭管理页面、开启压缩、配置 Access Log;
- 操作系统:文件描述符和 TCP 参数优化(高并发必须);
- 日志:规范滚动、脱敏、错误日志单独输出;
- 启动脚本:前置检查、健康检查、自动停止旧进程。
如果你需要 某个配置的更详细说明(比如日志脱敏的具体实现、JMX 加认证的方法),可以告诉我,我帮你进一步补充!